enriclluelles/route_translator

URL switching issue

bgilbank opened this issue · 9 comments

Steps to reproduce*

Hi, I have an issue when switching URL's between English and French. The below code works fine until I introduce localized do in my routes file.

Source code of views/layouts/application.html.erb

  #  URL swticher
  <% if I18n.locale == I18n.default_locale %>
    <li><%= link_to "Français", locale: "fr-ca" %></li>
  <% else %>
    <li><%= link_to "English", locale: "en-ca" %></li>
 <% end %>

Source code of routes.rb*

 Rails.application.routes.draw do
 scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
 # Other routes removed for clarity
  localized do
   resources :contacts
  end

 end
end

Expected behavior*

The expected behaviour is that URL's would switch back and forth correctly. eg exmaple.com/contact-us (default) to example.com/fr-ca/nous-contacter to example.com/en-ca/contact-us

Actual behavior*

When switching URL's from English to French this occurs: example.com/fr-ca/en-ca/nous-contacter, instead of the expected example.com/en-ca/contact-us.

To see this in action visit: https://ficdnca.herokuapp.com/contact-us

  1. Switch to French
  2. Then switch back to English
  3. A routing error will occur

If you visit the root_path https://ficdnca.herokuapp.com which doesn't have the localized do block, URL switching works correctly.

Thanks for your help!

System configuration*

Rails version:
Rails 6
Ruby version:
Ruby 2.6.4
Route Translator version:
route_translator (7.0.1)

I18n configuration*

application_controller.rb

 def set_locale
  I18n.locale = params[:locale] || http_accept_language.compatible_language_from(I18n.available_locales) ||  I18n.default_locale
  end
    
  def default_url_options(options={})
    { locale: I18n.locale }.merge(options)
  end
  

config/application.rb

    config.i18n.enforce_available_locales = true
    config.i18n.available_locales = ['en-ca', 'fr-ca']
    config.i18n.default_locale = 'en-ca'
    config.i18n.fallbacks = true
    config.i18n.fallbacks = ['en-ca', 'fr-ca']
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]

* Failure to include this requirement may result in the issue being closed.

Hi!

Thanks for being part of the Route Translator Community.

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

This looks redundant in your use case

Does this wiki help?

https://github.com/enriclluelles/route_translator/wiki/Generating-translated-URLs

@tagliala Ah thank you. Everything works if I remove the below line from my routes file.

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

@tagliala Sorry, one last question. How do I translate Devise routes?

routes.rb

devise_for :users, path: '', path_names: { sign_up: 'register', sign_in: 'login', sign_out: 'signed-out', password: 'secret', confirmation: 'verification', unlock: 'unlock' }

I simply put the devise_for method inside the localized block

Example from an old application of mine:

localized do
  devise_for :users, path: '', path_names: { sign_in: :login, sign_out: :logout }, controllers: { confirmations: 'confirmations', passwords: 'passwords', registrations: 'registrations', sessions: 'sessions' }
  # ...
end

That's what I did, I was just wondering how to properly reference it in my yml files?

eg:

fr-ca:
  routes:
     contacts: "nous-contacter"
     devise_for: 
       users:
         sign_in: "s'identifier"

I figured it out, thank you for your help and your quick responses!

fr-ca:
  routes:
     contacts: "nous-contacter"
     login: "s'identifier"

Ok, got it.

I just translate content, leaving paths as they are. I do not advise to translate devise paths, but you should be able to do that by using directly the path names (sign_in), as explained here: https://github.com/enriclluelles/route_translator#inflections

Closing here