使用Ruby on Rails 3中的URL切换语言

Cyg*_*sx1 19 url locale internationalization 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
Run Code Online (Sandbox Code Playgroud)

我的路线看起来像这样:

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"
Run Code Online (Sandbox Code Playgroud)

在我看来,我这样做:

<% if I18n.locale == I18n.default_locale %>
  <%= link_to "English", '/en'%>

<% else %>
  <%= link_to "Français", '/fr'%>

<%end%>
Run Code Online (Sandbox Code Playgroud)

一切都在主页上运行良好,但如果我在特定控制器中尝试切换语言,我将返回主页.我试着添加这个:

<% if I18n.locale == I18n.default_locale %>
  <%= link_to "English", '/en/' + params[:controller]%>

<% else %>
  <%= link_to "Français", '/fr/' + params[:controller]%>

<%end%>
Run Code Online (Sandbox Code Playgroud)

这修复了控制器,但是如果我们处于特定的操作并再次切换语言,我会回到该控制器的"索引".

我的问题:处理这个问题的最佳方法是什么?

我想我可以在ApplicationController(过滤器)中实现一些东西,以检查是否传递了一个控制器/动作/ id并将其附加到语言环境.或者我可以在routes.rb中执行此操作吗?

Cyg*_*sx1 59

哦,好吧,终于找到了我喜欢的方式......

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

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

<%end%>
Run Code Online (Sandbox Code Playgroud)

就这么简单!

Vive Ruby on Rails!


小智 15

如果您有这样的范围路线,涵盖所有本地化路线:

scope "/:locale" do
  ...
end
Run Code Online (Sandbox Code Playgroud)

如果您位于该范围路线内的页面中,例如'/ en/...',您可以创建链接以更改区域设置,而不会更改您当前的网站位置,如下所示:

<%= link_to "Français", params.merge({:locale => :fr}) %>
<%= link_to "English", params.merge({:locale => :en}) %>
Run Code Online (Sandbox Code Playgroud)


小智 7

我相信这种方式使它更清洁.所以这里:

配置/ application.rb中

I18n.available_locales = [:en, :pt, :es, :de]
Run Code Online (Sandbox Code Playgroud)

config/locales /:locale.yml上为每个:locale创建一个.yml文件

不要忘记在每个locale.yml文件上添加它,这是link_to t(lang)在不同位置之间进行转换时的转换方式.

en:
  en: "English"
  pt: "Portuguese"
  es: "Spanish"
  de: "German"
Run Code Online (Sandbox Code Playgroud)

将语言环境列表添加到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>
Run Code Online (Sandbox Code Playgroud)

现在,您可以看到添加到config/application.rb的所有语言环境

config/routes.rb:

match 'lang/:locale', to: 'index#change_locale', as: :change_locale, via: [:get]
Run Code Online (Sandbox Code Playgroud)

应用程序/控制器/ 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
Run Code Online (Sandbox Code Playgroud)

应用程序/控制器/ 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
Run Code Online (Sandbox Code Playgroud)