Переключите язык с URL в Ruby on Rails 3 - PullRequest
19 голосов
/ 05 декабря 2011

У меня есть сайт на французском и английском языках.Я хочу, чтобы пользователь мог переключать язык на лету, когда он нажимает на ссылку в заголовке.Довольно просто.

Я следовал руководству по 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 (фильтр), чтобы проверить, передан ли контроллер / action / id, и добавить его в локаль.Или я могу сделать это в route.rb?

Ответы [ 4 ]

55 голосов
/ 06 декабря 2011

Ну что ж, наконец-то нашел способ, который мне нравится ...

<% if I18n.locale == I18n.default_locale %>
  <%= link_to "English", { :locale=>'en' } %>

<% else %>
  <%= link_to "Français", { :locale=>'fr' } %>

<%end%>

Как все просто!

Vive Ruby on Rails!

15 голосов
/ 25 октября 2012

Если у вас есть такой маршрут области действия, который охватывает все локализованные маршруты:

scope "/:locale" do
  ...
end

Если вы находитесь на странице внутри этого маршрута, например, "/ en / ...", вы можете создавать ссылки наизменить язык без изменения текущего местоположения сайта следующим образом:

<%= link_to "Français", params.merge({:locale => :fr}) %>
<%= link_to "English", params.merge({:locale => :en}) %>
7 голосов
/ 22 августа 2017

Я верю, что этот способ делает его чище.Итак, все идет так:

config / 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

config / rout.rb :

match 'lang/:locale', to: 'index#change_locale', as: :change_locale, via: [:get]

app / controllers / 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

app / controllers / 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
3 голосов
/ 27 февраля 2014

Скажите, что вы хотите селектор для всех языков.Например, вы находитесь в en локали, и у вас также есть fr и es локали

В 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/">
...