Frage

Ich füge L18N meine Rails-Anwendung durch das Gebietsschema mit url params übergeben. Meine Urls suchen wie http://example.com/en/users und http://example.com/ar/users (für das Englisch und arabisch locales respectively)

In meiner Routen-Datei, ich habe definiert meine Routen mit a: PATH_PREFIX Option:

map.resources :users, :path_prefix => '/:locale'

Und Gebietsschema festgelegt wird, um eine before_filter in Application definiert mit

def set_locale
    I18n.locale = params[:locale]
end

ich auch Application # default_url_options definiert, locale auf alle von der Anwendung generiert URLs hinzuzufügen:

def default_url_options(options={})
    {:locale => I18n.locale}
end

Was ich will, ist ein Glied in den Layout-Header hinzufügen (auf allen Seiten angezeigt), die auf die gleiche Seite verbinden würden aber mit den anderen locale.

Zum Beispiel, wenn ich die arabische locale bin gerade, ich mag einen „English“ Link in der Kopfzeile, das wird mich auf meine aktuellen Seite umleiten zurück, und das Gebietsschema auf Englisch eingestellt. Gibt es eine Möglichkeit, dies in Schienen zu tun?

War es hilfreich?

Lösung

dauerte eine Weile, dies zu finden, aber hier ist meine Lösung:

link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' ) 

Von dem docs hier: http://api.rubyonrails.org/classes /ActionController/Base.html#M000649

  

Wenn Sie eine neue URL zu erzeugen, fehlt   Werte können von den ausgefüllt werden   aktuelle Anforderung der Parameter. Zum   Beispiel url_for: action =>   ‚Some_action‘ wird die aktuelle behalten   Controller, wie erwartet. Dieses Verhalten   erstreckt sich auf andere Parameter, einschließlich   : Controller,: id, und andere   Parameter, die in einen platziert   Route des Weg.

So url_for mit auf den aktuellen Wunsch des Parameter ausfällt, ändern nur die ist, die Sie in Ihrem Code möchten. In diesem Fall alles, was ich geändert wurde: locale, so alles andere bleibt gleich.

Beachten Sie dies auch für „versteckt“ funktioniert: Parameter. Also, wenn Sie:

map.my_map ':locale/my_map', :controller => 'home', :action => 'my_map'

die oben url_for auf der Seite mit / en / my_map muß nicht 'zu Hause' in der URL (dh / de / home / my_map). Bonus.

Andere Tipps

gefunden Also habe ich einen Weg zu mehr explizit dies mit heraus unter Berufung auf (so viel) Schienen Magie.

url_for(params.merge({:your_new_parameter => value}))

Dies sollte in jedem link_to arbeiten.

Alle seine tun, ist die aktuelle Anforderung der Parameter zu nehmen und den neuen gewünschten Hash in sie verschmelzen und dann eine neue URL für das zu schaffen.

Link zur aktuellen Seite mit verschiedenen Gegenden

Getestet auf Rails 4

Hallo an alle. Nach einiger Zeit der Forschung entscheiden, ich meine eigene Lösung dafür zu schreiben.

link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' ) 

Das funktioniert perfekt, aber es erlaubt XSS Vulnerability nur Parameter in der URL vorbei wie unten:

http://localhost:3000/en/about?host=www.fishingsiteorbadurl.com/%23&port=80

oder worst case:

http://localhost:3000/en/about?host=%D0%BE%D1%87%D0%B5%D0%BD%D1%8C%D0%BF%D0%BB%D0%BE%D1%85%D0%BE%D0%B9%D1%81%D0%B0%D0%B9%D1%82.%D1%80%D1%84

Überprüfen Sie heraus, was URLs, nachdem sie durch diesen Link in Ihrer Anwendung erhalten wird.

Meine Produktionslösung. Methode „Sprache ändern“ Umleitungen auf jeder Seite mit der richtigen locale nur mit HTTP_REFERER in Request-Objekt. Bitte beachten Sie: URI.path Methode für nur Pfad erhalten, nicht ganze url

  

Jetzt "Sprache ändern" Methode in jedem Controller:

        def change_lang

        if request.referer.nil?
                 refer = root_url
        else
                 uri = URI(request.referer)
                 refer = uri.path
        end
        lang = params[:lang]
        cookies[:locale] = lang
        redirect_to refer

        end
  

application_controller.rb

before_action :set_locale

def set_locale

# -- Get lang from cookies or url parameter locale

user_locale = cookies[:locale] || params[:locale]

# -- If present

if user_locale.present? 

    # -- If it is has 2 symbols

    user_locale = user_locale.scan(/[a-zA-Z]{2}/) 
else

    # -- If no - use default en locale

    user_locale = 'en'
end


# -- Check, is this locale available for using.
# Please note: this needed for disable invalid locale warning.

if I18n.available_locales.include?(user_locale[0].to_sym)

    I18n.locale =  user_locale[0]
else
    I18n.locale =   "en"
end

end
  

Fügen Sie diese an Ihr Layout

<%= link_to 'English', change_lang_path('en') %> <%= link_to 'Russian', change_lang_path('ru') %>
  

config / routes.rb

scope "(:locale)", locale: /[a-zA-Z]{2}/ do
get "change_lang/:lang" => "users#change_lang", :as => "change_lang"
end

Es gibt keine Notwendigkeit zu verwenden params.merge oder jeden Affen-Patch-Lösung.

Ich hoffe, das hilft, weil ich persönlich viel Zeit damit verbracht, es zu lösen.

Sie können analysieren request_uri, und ersetzen Sie Ihren Ort auf dem Weg mit regulärem Ausdruck

Ok, hier ist Helfer Beispiel. Wenn ich das richtig das Ziel verstehen

def locale_url(url, locale)
  url.gsub(/\/\w*$/, "/#{locale}")
end

url = "http://www.domain.com/products/1/ru" # or request.request_uri
locale = "en"
locale_url(url, locale) #=> "http://www.domain.com/products/1/en"

Dies ist ein Startpunkt, so können Sie einige andere Sachen machen, die Sie benötigen

Haben Sie einen Blick auf diese, obwohl es nicht trocken und richtig sein kann, funktioniert aber perfekt für mich. Es liest alle Parameter, die Sie nur das Gebietsschema geliefert ersetzen EX Urls: http://example.com:3000/us/users?t= 123 & m = 343 etc

  def us_link           
        link_to "US", form_locale_url("/us")            
  end

  def jp_link           
    link_to "Japan",form_locale_url("/jp")           
  end              

  def form_locale_url(locale)            
    new_url = request.request_uri          
    new_locale_url = new_us_url = new_jp_url = new_url           
    if new_url == "/"          
      new_locale_url.sub!(/\//,locale)           
    elsif (new_url =~/\/us/) == 0        
      new_us_url.sub!(/\/us/,locale)        
    elsif (new_url =~/\/jp/) == 0          
      new_jp_url.sub!(/\/jp/,locale)       
    end     
  end

Ein viel schnelle Avenue - und praktisch, wenn Sie viele Parameter haben, dass Veränderungen an verschiedenen Orten ... die Unordnung mit einem Anker-Tag vermeiden, verschmilzt nur den neu locale param zu den bestehenden (und tatsächlich dem alt locale param zu töten) .

<%= link_to "ру", request.params.merge( locale: 'ru' ) %>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top