我正在尝试在RailsTutorial示例应用程序上实现国际化。
我设法为每个用户存储区域设置属性,以及myurl.com/en
和myurl.com/es
等网址本地化。关键是如何在用户注销时将两种方法结合起来并将我的应用程序国际化为URL params,否则请使用他自己的偏好。
到目前为止,我有这个。此时,用户首选项会覆盖URL参数,但如果用户选择es
语言并导航到myapp.com/en
,则内容将以西班牙语显示。如果用户已登录,我希望URL没有该参数。
# application_controller.rb
class ApplicationController < ActionController::Base
include SessionsHelper
before_action :set_locale
def default_url_options(options = {})
{locale: I18n.locale}.merge options
end
def set_locale
I18n.locale = (current_user&.locale) || params[:locale] || I18n.default_locale
end
end
# users_controller.rb
def change_locale
user = current_user
user.locale = params[:locale]
user.save
redirect_to request.referer
end
# routes.rb
post 'international/:locale' => 'users#change_locale', as: 'international'
scope "(:locale)", locale: /en|es/ do
# All my routes
end
get '/:locale' => 'static_pages#home' # Fix the home route
# _footer.html.erb
...
<li>
<%= link_to t('spanish'), international_path(locale: :es), :method => :post %>
</li>
<li>
<%= link_to t('english'), international_path(locale: :en), :method => :post %>
</li>
...
I18n.available_locales output
[:en, :"da-DK", :"en-GB", :he, :"en-NZ", :"en-au-ocker", :uk, :"en-CA", :ja, :"en-BORK", :"zh-CN", :ru, :de, :"en-AU", :"de-AT", :pl, :"ca-CAT", :fr, :"fi-FI", :vi, :"en-UG", :nl, :"en-SG", :nep, :pt, :ko, :es, :sv, :ca, :"de-CH", :"zh-TW", :sk, :"en-IND", :it, :"en-US", :"pt-BR", :fa, :"nb-NO"]
我的视图代码看起来像这样(现在只有两个链接)
<li>
<%= link_to "Español", international_path(locale: :es), :metho d => :post %>
</li>
<li>
<%= link_to "English", international_path(locale: :en), :method => :post %>
</li>
PryRpl调试:
当我登录时:如果我手动编写URL,它总是转到用户存储的语言,尽管我写的是哪个URL。它始终显示用户首选项(:en
或:es
)
当我登录并单击显式视图区域设置链接(上述之一)时:用户首选项已更改,因此它将存储的新语言加载到用户首选项。
当我没有登录时:它使用URL参数。
答案 0 :(得分:0)
感谢同事找到解决方案。
def set_locale
# Change current_user&.locale to enable ruby <2.3 compatibility
I18n.locale = (current_user.locale if current_user) || params[:locale] || I18n.default_locale
redirect_to locale: I18n.locale if request.get? && params[:locale] != I18n.locale.to_s
end
如果有人知道更好的解决方案,请用它发表答案。
答案 1 :(得分:0)
def set_locale
if user_signed_in?
I18n.locale = current_user.language
else
I18n.locale = params[:lang] || locale_from_header || I18n.default_locale
end
end
def locale_from_header
request.env.fetch('HTTP_ACCEPT_LANGUAGE', '').scan(/[a-z]{2}/).first
end