Переключить язык с URL-адресом в Ruby on Rails 3
У меня есть сайт на французском и английском языках. Я хочу, чтобы пользователь мог переключать язык "на лету", когда они нажимают ссылку в заголовке. Довольно просто.
Я следил за Ruby on Rails 3, и у меня есть это:
class ApplicationController < ActionController::Base
before_filter :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
protect_from_forgery
def default_url_options(options={})
logger.debug "default_url_options is passed options: #{options.inspect}\n"
{ :locale => I18n.locale }
end
end
Мои маршруты выглядят так:
scope "(:locale)", :locale => /en|fr/ do
match 'home' => 'home#index'
match 'home/ajax_twitter' => 'home#ajax_twitter'
match 'equipe' => 'equipe#index'
match 'equipe/sylvain' => 'equipe#sylvain'
match 'equipe/benoit' => 'equipe#benoit'
match 'equipe/stephane' => 'equipe#stephane'
match 'equipe/suemarie' => 'equipe#suemarie'
match 'equipe/regis' => 'equipe#regis'
match 'equipe/fred' => 'equipe#fred'
match 'equipe/callback' => 'equipe#callback'
match 'equipe/auth' => 'equipe#auth'
match 'equipe/ajax_contact' => 'equipe#ajax_contact'
match 'linkedinauth/callback' => 'linkedinAuth#callback'
match 'linkedinauth/init_auth' => 'linkedinAuth#init_auth'
match 'mission' => 'mission#index'
match 'service' => 'service#index'
match 'developmen' => 'developmen#index'
match 'contact' => 'contact#index'
match 'mandats' => 'mandats#index'
end
match '/:locale' => "home#index"
И, на мой взгляд, я делаю это:
<% if I18n.locale == I18n.default_locale %>
<%= link_to "English", '/en'%>
<% else %>
<%= link_to "Français", '/fr'%>
<%end%>
Все хорошо работает на домашней странице, но если я пытаюсь переключить язык, пока я нахожусь в определенном контроллере, я возвращаюсь на домашнюю страницу. Я попытался добавить это:
<% if I18n.locale == I18n.default_locale %>
<%= link_to "English", '/en/' + params[:controller]%>
<% else %>
<%= link_to "Français", '/fr/' + params[:controller]%>
<%end%>
Это исправляет контроллер, но если мы снова находимся в определенном действии и снова переключаем язык, я возвращаюсь к "индексу" этого контроллера.
Мой вопрос: Каков наилучший способ справиться с этим?
Думаю, я мог бы что-то реализовать в ApplicationController (filter), чтобы проверить, прошел ли контроллер/действие/id и добавляет его в локаль. Или я могу сделать это в route.rb?
Ответы
Ответ 1
Хорошо, наконец нашел способ, который мне нравится...
<% if I18n.locale == I18n.default_locale %>
<%= link_to "English", { :locale=>'en' } %>
<% else %>
<%= link_to "Français", { :locale=>'fr' } %>
<%end%>
Проще, чем это!
Vive Ruby on Rails!
Ответ 2
Если у вас есть маршрут маршрута, подобный этому, который охватывает все локализованные маршруты:
scope "/:locale" do
...
end
Если вы находитесь на странице внутри этого маршрута, например. '/en/...' вы можете создавать ссылки для изменения локали без изменения вашего текущего местоположения сайта следующим образом:
<%= link_to "Français", params.merge({:locale => :fr}) %>
<%= link_to "English", params.merge({:locale => :en}) %>
Ответ 3
Скажите, что вы хотите селектор для всех языков. Например. Вы находитесь в en
locale, и у вас также есть fr
и es
locales
В application_helper.rb
(или любой другой помощник в /app/helpers/ )
def alternate_locales
I18n.available_locales.map{|l|
yield(l)
}.join.html_safe
end
Теперь в любом месте просмотра:
<% alternate_locales do |l| %>
<li class="language <%= l %>"><%= link_to(l,locale: l) %></li>
<% end %>
Если пользовательский язык является английским, текущий URL-адрес www.example.com/en/path/
Это будет генерировать:
<li class="language fr"><a href="www.example.com/fr/path/">fr</a></li>
<li class="language es"><a href="www.example.com/es/path/">es</a></li>
<li class="language en"><a href="www.example.com/en/path/">en</a></li>
Кроме того, если вы хотите иметь ссылку [rel= "alternate" ] в заголовке:
<% alternate_locales do |l| %>
<link rel="alternate" hreflang="<%= l %>" href="<%= url_for(locale: l) %>">
<% end %>
Это создаст:
<link rel="alternate" hreflang="fr" href="www.example.com/fr/path/">
<link rel="alternate" hreflang="es" href="www.example.com/es/path/">
<link rel="alternate" hreflang="en" href="www.example.com/en/path/">
Ответ 4
Я считаю, что этот путь делает его более чистым. Итак, вот оно:
конфигурации /application.rb
I18n.available_locales = [:en, :pt, :es, :de]
Создайте файл .yml для каждого: locale на config/locales/: locale.yml
Не забудьте добавить это в каждый из файлов locale.yml, так как link_to t(lang)
переводится при изменении между местоположениями.
en:
en: "English"
pt: "Portuguese"
es: "Spanish"
de: "German"
Добавьте список локалей в свой html:
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<%= t(I18n.locale) %> # Current selected locales
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li class="header">Select a language</li>
<% I18n.available_locales.each do |lang| %> # Array of available locales
<li>
<%= link_to t(lang), change_locale_path(lang) %> # Each locale URL param and name
</li>
<% end %>
</ul>
Итак, теперь вы можете увидеть все локали, добавленные в config/application.rb
конфиг /routes.rb
match 'lang/:locale', to: 'index#change_locale', as: :change_locale, via: [:get]
приложение/контроллеры/index_controller.rb
def change_locale
l = params[:locale].to_s.strip.to_sym
l = I18n.default_locale unless I18n.available_locales.include?(l)
cookies.permanent[:my_locale] = l
redirect_to request.referer || root_url
end
приложение/контроллеры/application_controller.rb
before_action :set_locale
def set_locale
if cookies[:my_locale] && I18n.available_locales.include?(cookies[:grolla_locale].to_sym)
l = cookies[:my_locale].to_sym
else
l = I18n.default_locale
cookies.permanent[:my_locale] = l
end
I18n.locale = l
end