2012-12-20 7 views
7

Jestem w trakcie dodawania internacjonalizacji do aplikacji Rails i mniej więcej po odpowiednich Rails Guide i Railscast.Konfigurowanie tras Railsów w celu dostosowania do i18n

Zabrakło mi na dwie kwestie:

  1. Jak mogę dodać „domowy” link, który przekierowuje do bieżącej lokalizacji. Obecnie mam linki root_path, ale te zawodzą z powodu linii w routes.rb, zaprojektowanej do przechwytywania nieskopiowanych korzeni. Oznacza to, że ścieżka_kompilacji zawsze kieruje się do domyślnych ustawień narodowych, a nie do bieżących ustawień narodowych.
  2. Mam wszystko skonfigurowane i działające lokalnie (z wyjątkiem powyższego problemu z wyjątkiem numeru ), ale wdrażanie w Heroku wszystkich adresów URL wydaje się zrzucać poprzez mój plik tras i zostać złapanym przez jeden z haczyków. Przekierowują się one do '/' pod ustawieniem defulat .

Mój zestaw górę jest następujący

application_controller.rb

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

private 
def set_locale 
    I18n.locale = params[:locale] if params[:locale].present? 
end 

routes.rb

scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do 
    all_my_routes 

    # handles /valid-locale 
    root to: 'home#index', as: "localized_root" 
    # handles /valid-locale/fake-path 
    match '*path', to: redirect { |params, request| "/#{params[:locale]}" } 
end 

# handles/
root to: redirect("/#{I18n.default_locale}") 

# handles /bad-locale|anything/valid-path 
match '/*locale/*path', to: redirect("/#{I18n.default_locale}/%{path}") 

# handles /anything|valid-path-but-no-locale 
match '/*path', to: redirect("/#{I18n.default_locale}/%{path}") 

My home Link:

<%= link_to "Home", root_path %> 

Odpowiedz

9

W końcu udało mi się to zrobić po pewnym powrocie. Problem polegał na tym, że złapanie wszystkich tras było: a) złapanie więcej, niż się spodziewałem, i b) najwyraźniej zachowujące się inaczej w rozwoju w porównaniu z wdrażaniem (dlaczego tak powinno być, nie jestem pewien).

Zresztą pierwszy zmieniłem zakres aby opcjonalne (nawiasy note):

scope "(:locale)", ..... 

To gwarantuje, że scoped trasy są ważne, nawet jeśli nie locale jest ustawione (jest to głównie obsługiwać pewne problemy byłem korzystanie z wywołań zwrotnych itp.).

To pozwoliło mi spadać dwa root to linii, zachowując tylko

root to "home#index" 

rzuciłem linię "uchwyty/valid-locale/fałszywy-ścieżka", to było przyczyną problemów z drogami '/'.

Następnie zachowano następną połowę po zasięgu (uwaga na ostatnią).

# handles /bad-locale|anything/valid-path 
match '/*locale/*path', to: redirect("/#{I18n.default_locale}/%{path}") 

# handles /anything|valid-path-but-no-locale 
match '/*path', to: redirect("/#{I18n.default_locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" } 

# handles/
match '', to: redirect("/#{I18n.locale}") 

Jako punkt zainteresowania, miałem również zaktualizować action_mailer do obsługi nowych zlokalizowanych adresów URL.

config.action_mailer.default_url_options = { :host => 'path.to.my.app.com', :locale => I18n.locale } 

A teraz wszystko wydaje się działać!

+1

Świetne, że udało ci się uzyskać wszystko działa tak, jak chcesz. Jeśli zamierzałem coś zmienić, domyślam się, że odkąd zdecydowałeś się na użycie "I18n.locale" jako swojego "catch-all", prawdopodobnie użyjesz go we wszystkich innych połączeniach "match" zamiast "I18n" .default_locale', ponieważ przekierowujesz na "ostatnią znaną lokalizację" zamiast "Nie wiem, jakie ustawienia regionalne chcesz, aby uzyskać domyślne ustawienia regionalne aplikacji". Czy też pisałeś testy routingu? Jeśli tak, możesz je udostępnić, edytuj odpowiedź i opublikuj je dla dobra wszystkich. –

5

Jest klejnot, który robi to cudownie. (https://github.com/svenfuchs/routing-filter) Należy dodać następujący kod do Gemfile:

gem 'routing-filter' 

i dodaj następujące do pliku routes.rb

Rails.application.routes.draw do 
    filter :locale 
    ... 
end 

nadzieję, że to pomaga ...

+0

dziękuje Kzu, który wygląda na interesujący klejnot i taki, którego wcześniej nie spotkałem. Ale myślę, że w tym przypadku może to być przesada. To musi być dość standardowy przypadek użycia? Szczególnie w pierwszym numerze nie mogę pomóc w myśleniu, że przeoczyłem coś oczywistego (nie jestem pewien, co się dzieje z RE Heroku na tym etapie !!). Doceń wszelkie pomysły, które możesz mieć. –

+0

Ksu, przygotowywałam się do złożenia pytania o trasę i zobaczyłam twoją odpowiedź. Widziałem ten klejnot, ale wydaje mi się, że byłem trochę zmęczony i nie dostałem tego, co musiałem zrobić. Działa świetnie. –

0

Wygląda na to, mogliśmy użyć the comment I wrote w Railscasts, aby pomóc w routingu I18n. Chłodny!

Co zrobić z pierwszym problemem, czy zamiast tego można ponownie przekierować numer root to: redirect("/#{I18n.default_locale}"), aby przekierować na numer I18n.locale?

Co do drugiego numeru, Czy używałeś również testów w komentarzu Railscast lub masz własne testy, a jeśli tak, to czy je zdałeś? Czy Heroku dostarcza Ci jakiekolwiek logi błędów? ($ heroku logs). Mam uruchomione te trasy do Heroku zgodnie z oczekiwaniami, więc myślę, że jest szansa, że ​​nie jest to problem z Heroku.

+0

hi @paul, tak, "pożyczyłem" trochę kodu. Dzięki! Udało mi się to zrobić z kilkoma poprawkami, opublikuję opis moich kroków. –

+0

myśli lub krytyka na moim rozwiązaniu są bardziej niż mile widziane –

6

Ten blogpost wyjaśnia to rzeczywiście bardzo szczegółowo:

Tylko to, co szukałem, gdy nic nie wydaje się działać

http://dhampik.com/blog/rails-routes-tricks-with-locales

scope "/:locale", locale: /#{I18n.available_locales.join("|")}/ do 
    resources :posts  
    root to: "main#index" 
    end 

    root to: redirect("/#{I18n.default_locale}", status: 302), as: :redirected_root 

    get "/*path", to: redirect("/#{I18n.default_locale}/%{path}", status: 302), constraints: {path: /(?!(#{I18n.available_locales.join("|")})\/).*/}, format: false 

przekierowuje do domyślnych Lang Od korzenia i robi dużo także o innych rzeczach.

Powiązane problemy