Voglio impostare il locale dal browserlocale dei clienti request.env['HTTP_ACCEPT_LANGUAGE']
e dall'URL.Rails I18n set_locale
Se un utente visita un URL (ad esempio: myapp.com) si dovrebbe controllare il
HTTP_ACCEPT_LANGUAGE
e reindirizzare all'URL destra (ad esempio: myapp.com/en - se ilbrowserlocale
è en)Se un utente sceglie una lingua diversa tramite un menu lingua, dovrebbe cambiare l'URL ad esempio: myapp.com/de.
Qui è la mia cosa ho ottenuto finora:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_locale
private
# set the language
def set_locale
if params[:locale].blank?
I18n.locale = extract_locale_from_accept_language_header
else
I18n.locale = params[:locale]
end
end
# pass in language as a default url parameter
def default_url_options(options = {})
{locale: I18n.locale}
end
# extract the language from the clients browser
def extract_locale_from_accept_language_header
browser_locale = request.env['HTTP_ACCEPT_LANGUAGE'].try(:scan, /^[a-z]{2}/).try(:first).try(:to_sym)
if I18n.available_locales.include? browser_locale
browser_locale
else
I18n.default_locale
end
end
end
Nei miei percorsi il file che ho ottenuto:
Myapp::Application.routes.draw do
# set language path
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
root :to => "mycontrollers#new"
...
end
match '*path', to: redirect("/#{I18n.locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" }
match '', to: redirect("/#{I18n.locale}")
end
Il problema è che il routesfile viene eseguito prima e la HTTP_ACCEPT_LANGUAGE
ha nessun effetto, perché il parametro url è già impostato quando si tratta del controller.
Qualcuno ha una soluzione per questo? Forse risolverlo con un middleware?
L'application_controller non è chiamato, in caso di partita '' -> così si finisce per non impostazione della localizzazione e senza reindirizzamento. Almeno questo è quello che è successo quando l'ho implementato. –
Ho appena controllato una nuova app Rails (4.1.0) e funziona come previsto. Invece di 'match '', per: redirect ("/# {I18n.locale} ")' dovrai scrivere 'get '', per: redirect ("/# {I18n.locale} ")'. Quella prima richiesta non userà application_controller.rb – etagwerker
Per qualche ragione non funziona per me (testato su 4.0 duro) - comunque ho trovato la seguente soluzione: http://stackoverflow.com/questions/23188986/ applicazione controller-non-essere-eseguito quando si accede-dominio-senza-reindirizzamento –