Schienen-Link zu der aktuellen Seite und Übergabe von Parametern, um es
-
23-09-2019 - |
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?
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' ) %>