Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ gem "bootsnap", "1.18.3", require: false
gem "devise", "4.9.4"
# devise-api authenticate API requests [https://github.com/nejdetkadir/devise-api]
gem "devise-api", github: "nejdetkadir/devise-api", branch: "main"
# Add devise-i18n for automatic translation of Devise views and messages
gem "devise-i18n", "~> 1.10"
Copy link
Collaborator

@danielnottingham danielnottingham May 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this gem?

I believe we can do this without adding another gem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that it's possible to translate Devise manually. I actually tested that approach without using the devise-i18n gem, but it didn’t translate everything, only any messages.

That’s because we didn’t generate the Devise views, so it kept using the default ones from the gem, which are hardcoded in English and don’t use t() for translations.

# Enumerations for Ruby with some magic powers!
gem "enumerate_it", "4.0.0"
# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]
Expand Down
7 changes: 7 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ GEM
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
devise-i18n (1.13.0)
devise (>= 4.9.0)
rails-i18n
diff-lcs (1.5.1)
docile (1.4.0)
dotenv (3.1.2)
Expand Down Expand Up @@ -403,6 +406,9 @@ GEM
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
rails-i18n (7.0.10)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (7.1.3.4)
actionpack (= 7.1.3.4)
activesupport (= 7.1.3.4)
Expand Down Expand Up @@ -589,6 +595,7 @@ DEPENDENCIES
debug (= 1.9.2)
devise (= 4.9.4)
devise-api!
devise-i18n (~> 1.10)
dotenv-rails (= 3.1.2)
enumerate_it (= 4.0.0)
factory_bot_rails (= 6.4.3)
Expand Down
5 changes: 5 additions & 0 deletions config/initializers/i18n.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

I18n.load_path += Rails.root.glob("/config/locales/**/*.{rb,yml}")
I18n.available_locales = %i[pt-BR en]
I18n.default_locale = :"pt-BR"
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ en:
password_change:
subject: "Password Changed"
omniauth_callbacks:
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
failure: 'Could not authenticate you from %{kind} because "%{reason}".'
success: "Successfully authenticated from %{kind} account."
passwords:
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
Expand Down
File renamed without changes.
File renamed without changes.
147 changes: 147 additions & 0 deletions config/locales/pt-BR/devise.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
pt-BR:
activerecord:
attributes:
user:
confirmation_sent_at: Confirmação enviada em
confirmation_token: Token de confirmação
confirmed_at: Confirmado em
created_at: Criado em
current_password: Senha atual
current_sign_in_at: Atualmente logado em
current_sign_in_ip: IP do acesso atual
email: E-mail
encrypted_password: Senha criptografada
failed_attempts: Tentativas sem sucesso
last_sign_in_at: Último acesso em
last_sign_in_ip: Último IP de acesso
locked_at: Bloqueado em
password: Senha
password_confirmation: Confirme sua senha
remember_created_at: Lembrar criado em
remember_me: Lembre-se de mim
reset_password_sent_at: Resetar senha enviado em
reset_password_token: Resetar token de senha
sign_in_count: Contagem de acessos
unconfirmed_email: E-mail não confirmado
unlock_token: Token de desbloqueio
updated_at: Atualizado em
models:
user:
one: Usuário
other: Usuários
devise:
confirmations:
confirmed: A sua conta foi confirmada com sucesso.
new:
resend_confirmation_instructions: Reenviar instruções de confirmação
send_instructions: Dentro de minutos, você receberá um email com as instruções de confirmação da sua conta.
send_paranoid_instructions: Se o seu e-mail existir em nosso banco de dados, você receberá um email com instruções sobre como confirmar sua conta em alguns minutos.
failure:
already_authenticated: Você já está autenticado.
inactive: A sua conta ainda não foi ativada.
invalid: "%{authentication_keys} ou senha inválidos."
last_attempt: Você tem mais uma única tentativa antes de sua conta ser bloqueada.
locked: A sua conta está bloqueada.
not_found_in_database: "%{authentication_keys} ou senha inválidos."
timeout: A sua sessão expirou, por favor, faça login novamente para continuar.
unauthenticated: Para continuar, faça login ou registre-se.
unconfirmed: Antes de continuar, confirme a sua conta.
mailer:
confirmation_instructions:
action: Confirmar minha conta
greeting: Bem-vindo %{recipient}!
instruction: "Você pode confirmar sua conta através do link abaixo:"
subject: Instruções de confirmação
email_changed:
greeting: Olá %{recipient}!
message: Estamos entrando em contato para notificá-lo de que seu e-mail está sendo alterado para %{email}.
message_unconfirmed: Estamos entrando em contato para notificá-lo de que seu e-mail está sendo alterado para %{email}.
subject: E-mail alterado
password_change:
greeting: Olá %{recipient}!
message: Estamos entrando em contato para notificá-lo de que sua senha foi alterada.
subject: Senha alterada
reset_password_instructions:
action: Redefinir minha senha
greeting: Olá %{recipient}!
instruction: Alguém fez o pedido para redefinir sua senha, e você pode fazer isso clicando no link abaixo.
instruction_2: Se você não fez este pedido, por favor ignore este e-mail.
instruction_3: Sua senha não será alterada até que você acesse o link acima e crie uma nova.
subject: Instruções de redefinição de senha
unlock_instructions:
action: Desbloquear minha conta
greeting: Olá %{recipient}!
instruction: "Clique no link abaixo para desbloquear sua conta:"
message: Sua conta foi bloqueada devido ao excessivo número de tentativas acesso inválidas.
subject: Instruções de desbloqueio
omniauth_callbacks:
failure: Não foi possível autorizar de uma conta de %{kind} porque "%{reason}".
success: Autorizado com sucesso de uma conta de %{kind}.
passwords:
edit:
change_my_password: Alterar minha senha
change_your_password: Alterar sua senha
confirm_new_password: Confirme sua nova senha
new_password: Nova senha
new:
forgot_your_password: Esqueceu sua senha?
send_me_reset_password_instructions: Enviar instruções para redefinição da senha
no_token: Você não pode acessar esta página sem estar logado. Se você veio de um email de redefinição de senha, por favor certifique-se de ter digitado a URL corretamente.
send_instructions: Dentro de minutos, você receberá um e-mail com as instruções de redefinição da sua senha.
send_paranoid_instructions: Se o seu email existir em nosso banco de dados, você receberá um email com um link para recuperação da senha.
updated: A sua senha foi alterada com sucesso. Você está autenticado.
updated_not_active: Sua senha foi alterada com sucesso.
registrations:
destroyed: Adeus! A sua conta foi cancelada com sucesso. Esperamos vê-lo novamente em breve.
edit:
are_you_sure: Você tem certeza?
cancel_my_account: Cancelar minha conta
currently_waiting_confirmation_for_email: "No momento esperando por: %{email}"
leave_blank_if_you_don_t_want_to_change_it: deixe em branco caso não queira alterá-la
title: Editar %{resource}
unhappy: Não está contente?
update: Atualizar
we_need_your_current_password_to_confirm_your_changes: precisamos da sua senha atual para confirmar suas mudanças
new:
sign_up: Inscrever-se
signed_up: Bem vindo! Você realizou seu registro com sucesso.
signed_up_but_inactive: Você se inscreveu com sucesso, porém nós não podemos autenticá-lo porque sua conta ainda não foi ativada.
signed_up_but_locked: Você se inscreveu com sucesso. Porém nós não podemos autenticá-lo porque sua conta está bloqueada.
signed_up_but_unconfirmed: Uma mensagem com um link de confirmação foi enviada para o seu e-mail. Por favor, acesse o link para ativar sua conta.
update_needs_confirmation: Sua conta foi atualizada com sucesso, mas nós precisamos verificar o novo endereço de email. Por favor, verifique seu e-mail e clique no link de confirmação para finalizar confirmando o seu novo e-mail.
updated: A sua conta foi atualizada com sucesso.
updated_but_not_signed_in: Sua conta foi atualizada com sucesso, uma vez que sua senha foi alterada será necessário realizar o login novamente.
sessions:
already_signed_out: Logout efetuado com sucesso.
new:
sign_in: Login
signed_in: Login efetuado com sucesso.
signed_out: Logout efetuado com sucesso.
shared:
links:
back: Voltar
didn_t_receive_confirmation_instructions: Não recebeu instruções de confirmação?
didn_t_receive_unlock_instructions: Não recebeu instruções de desbloqueio?
forgot_your_password: Esqueceu sua senha?
sign_in: Login
sign_in_with_provider: Entrar com %{provider}
sign_up: Inscrever-se
minimum_password_length:
one: "(Mínimo de %{count} caractere)"
other: "(Mínimo de %{count} caracteres)"
unlocks:
new:
resend_unlock_instructions: Reenviar instruções de desbloqueio
send_instructions: Dentro de minutos, você receberá um e-mail com instruções de desbloqueio da sua conta.
send_paranoid_instructions: Se sua conta existir em nosso banco de dados, você receberá em breve um e-mail com instruções para desbloquear ela.
unlocked: A sua conta foi desbloqueada com sucesso. Efetue login para continuar.
errors:
messages:
already_confirmed: já foi confirmado
confirmation_period_expired: É necessário ser confirmado dentro do período %{period}, por favor requisite um novo usuário.
expired: expirou, por favor solicite uma nova
not_found: não encontrado
not_locked: não foi bloqueado
not_saved:
one: "Não foi possível salvar %{resource}: 1 erro"
other: "Não foi possível salvar %{resource}: %{count} erros."
23 changes: 23 additions & 0 deletions config/locales/pt-BR/devise_api.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pt-BR:
devise:
api:
error_response:
invalid_authentication: "E-mail ou senha inválidos"
invalid_token: "Token inválido"
expired_token: "O token expirou"
expired_refresh_token: "O token de atualização expirou"
revoked_token: "O token foi revogado"
refresh_token_disabled: "O token de atualização está desabilitado para esta aplicação"
sign_up_disabled: "O cadastro está desabilitado para esta aplicação"
invalid_refresh_token: "Token de atualização inválido"
invalid_email: "E-mail inválido"
invalid_resource_owner: "Usuário inválido"
resource_owner_create_error: "Não foi possível criar o usuário"
devise_api_token_create_error: "Não foi possível criar o token"
devise_api_token_revoke_error: "Não foi possível revogar o token"
lockable:
locked: "Sua conta está bloqueada"
confirmable:
unconfirmed: "Você precisa confirmar sua conta antes de continuar"
registerable:
signed_up_but_unconfirmed: "Uma mensagem com o link de confirmação foi enviada para o seu e-mail. Por favor, siga o link para ativar sua conta"
7 changes: 7 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@
# You can uncomment this line to turn off ActiveRecord support entirely.
# config.use_active_record = false

# Config for run test translated to english
config.around do |example|
I18n.with_locale(:en) do
example.run
end
end

# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
Expand Down
Loading