2011-12-05 32 views
19

Tôi có một trang web bằng cả tiếng Pháp và tiếng Anh. Tôi muốn người dùng có thể chuyển đổi ngôn ngữ khi họ nhấp vào liên kết trong tiêu đề. Khá đơn giản.Chuyển ngôn ngữ bằng URL trong Ruby on Rails 3

Tôi đã theo Ruby on Rails 3 hướng dẫn, và tôi có điều này:

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 

tuyến đường của tôi trông như thế này:

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" 

Và theo quan điểm của tôi, tôi làm điều này:

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

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

<%end%> 

Tất cả hoạt động tốt trong trang chủ, nhưng nếu tôi cố chuyển ngôn ngữ trong khi tôi đang ở trong một bộ điều khiển cụ thể, tôi sẽ được trả về trang. Tôi cố gắng để thêm video này:

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

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

<%end%> 

này sửa chữa các bộ điều khiển, nhưng nếu chúng ta đang ở trong một hành động cụ thể và chuyển đổi ngôn ngữ một lần nữa, tôi nhận được trở lại 'index' của bộ điều khiển này.

Câu hỏi của tôi: Cách tốt nhất để giải quyết vấn đề này là gì?

Tôi đoán tôi có thể thực hiện một cái gì đó trong ApplicationController (bộ lọc) để kiểm tra xem một bộ điều khiển/hành động/id được truyền và nối nó vào miền địa phương. Hoặc tôi có thể làm điều này trong routes.rb không?

Trả lời

52

Oh tốt, cuối cùng tìm thấy một cách tôi thích ...

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

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

<%end%> 

Như đơn giản như thế này!

Vive Ruby on Rails!

14

Nếu bạn có phạm vi tuyến đường như thế này bao gồm tất cả các tuyến đường địa phương:

scope "/:locale" do 
    ... 
end 

Nếu bạn đang ở trong một trang bên trong đó scoped đường ví dụ '/ vi/...' bạn có thể tạo liên kết để thay đổi ngôn ngữ mà không thay đổi vị trí hiện tại của trang web như sau:

<%= link_to "Français", params.merge({:locale => :fr}) %> 
<%= link_to "English", params.merge({:locale => :en}) %> 
+1

Vì lý do sử dụng một số biểu tượng (ví dụ. ': vi') gây ra' ActionController :: RoutingError (Không có đường khớp nào {...}) 'trên ** lần nhấp ** tiếp theo (được kiểm tra trong Rails 3.2.12). Sử dụng chuỗi thay vì giải quyết vấn đề (': locale => 'en''). – user569825

+0

đây là câu trả lời hữu ích hơn vì nó đề cập đến ngữ cảnh hiện tại, tức là các thông số. và hợp nhất chúng với ngôn ngữ, là một tham số meta cấp ... – Jerome

3

Giả sử bạn muốn chọn một ngôn ngữ. Ví dụ.Bạn đang ở en locale và bạn cũng có fres miền địa phương

Trong application_helper.rb (hoặc bất kỳ trợ giúp khác trong/app/giúp đỡ /)

def alternate_locales 
    I18n.available_locales.map{|l| 
    yield(l) 
    }.join.html_safe 
end 

Bây giờ bất cứ nơi nào trong giao diện:

<% alternate_locales do |l| %> 
    <li class="language <%= l %>"><%= link_to(l,locale: l) %></li> 
<% end %> 

Nếu ngôn ngữ người dùng là tiếng Anh, URL hiện tại là www.example.com/en/path/ Điều này sẽ tạo ra:

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

Thêm vào đó, nếu bạn muốn có liên kết [rel = "alternate"] liên kết trong tiêu đề:

<% alternate_locales do |l| %> 
    <link rel="alternate" hreflang="<%= l %>" href="<%= url_for(locale: l) %>"> 
<% end %> 

Điều đó sẽ tạo ra:

<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/"> 
3

Tôi tin rằng cách này làm cho nó rõ ràng hơn. Vì vậy, ở đây nó đi:

config/application.rb

I18n.available_locales = [:en, :pt, :es, :de] 

Tạo một file .yml cho mỗi: locale trên config/miền địa phương /: locale.yml

Đừng quên thêm điều này vào mỗi tệp locale.yml, đây là cách mà link_to t(lang) được dịch khi thay đổi giữa các vị trí.

en: 
    en: "English" 
    pt: "Portuguese" 
    es: "Spanish" 
    de: "German" 

Thêm danh sách ngôn ngữ để html của bạn:

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

Vì vậy, bây giờ bạn có thể xem tất cả các miền địa phương mà bạn đã thêm vào config/application.rb

config/tuyến .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 
Các vấn đề liên quan