Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: host_locales does not set the locale #320

Closed
2 tasks done
staskolukasz opened this issue Nov 27, 2024 · 5 comments
Closed
2 tasks done

Bug: host_locales does not set the locale #320

staskolukasz opened this issue Nov 27, 2024 · 5 comments
Labels

Comments

@staskolukasz
Copy link

staskolukasz commented Nov 27, 2024

Bug description

Hello,

I would like to report an issue related to host_locales property.

I followed the guide and configured host_locales in route_translator.rb as shown below:

  ...
  config.host_locales = {
    "*.pl"                 => :pl,
    "*.de"                 => :de,
    "*.cz"                 => :cz
  }
  ...

Unfortunately, after starting the server and visiting a controller with a single action - index, which renders the value of locale, I noticed that the value did not change despite the above configuration. To solve the problem, it was necessary to apply a workaround in the ApplicationController:

class ApplicationController < ActionController::Base
  before_action :set_locale

  private

  def set_locale
    case request.host
    when /\.pl\z/
      I18n.locale = :pl
    when /\.de\z/
      I18n.locale = :de
    when /\.cz\z/
      I18n.locale = :cz
    else
      I18n.locale = I18n.default_locale
    end
  end
end

The problem - config.host_locales does not set the locale.

Steps to reproduce

  1. Update your /etc/hosts file:
127.0.0.1 abc.my-domain.pl
127.0.0.1 abc.my-domain.de
127.0.0.1 abc.my-domain.cz
  1. Install Ruby on Rails 8
  2. Add the configuration to development.rb file:
  config.hosts.concat(%w[
    abc.my-domain.pl
    abc.my-domain.de
    abc.my-domain.cz
  ])
  1. Add route_translator gem
  2. Run bundle install
  3. Run bundle exec rails g route_translator:install
  4. Configure the gem:
...
  config.host_locales = {
    "*.pl"                 => :pl,
    "*.de"                 => :de,
    "*.cz"                 => :cz
  }
  config.hide_locale = true
...
  1. Run rails g controller products
  2. Add one action to ProductsController - index
  3. Create translation files for two languages, de and cz:
de:
  routes:
    products: produkte

and

cz:
  routes:
    products: produkty
  1. Create following views for de (index.de.html.erb) and cz (index.cz.html.erb) language:
view: index.de.html.erb
<br />
locale: <%= I18n.locale %>

and

view: index.cz.html.erb
<br />
locale: <%= I18n.locale %>
  1. Create a default view (index.html.erb):
view: index.html.erb
<br />
locale: <%= I18n.locale %>
  1. Run ./bin/dev
  2. Visit http://abc.my-domain.de:3000/produkte
  3. Visit http://abc.my-domain.cz:3000/produkty

Expected behavior

When I visit http://abc.my-domain.de:3000/produkte I would like to see this in the view:

view: index.de.html.erb
locale: de

When I visit http://abc.my-domain.cz:3000/produkty I would like to see this in the view:

view: index.cz.html.erb
locale: cz

Actual behavior

When I visit http://abc.my-domain.de:3000/produkte I see this in the view:

view: index.html.erb
locale: en

When I visit http://abc.my-domain.cz:3000/produkty I see this in the view:

view: index.html.erb
locale: en

Reproducible reduced test case

No response

Ruby version

3.3.5

Ruby on Rails version

8.0

Route Translator version

14.2.0

I18n configuration

No custom configuration

Route Translator configuration

  config.host_locales = {
    "*.pl"                 => :pl,
    "*.de"                 => :de,
    "*.cz"                 => :cz
  }
  config.hide_locale = true

Rails routes source

...
localized do
    resources :products
end
...

Rails locales

de:
  routes:
    products: produkte

cz:
  routes:
    products: produkty

Rails routes

                             products_cz GET    /produkty(.:format)                                                                               products#index {:locale=>"cz"}
                             products_de GET    /produkte(.:format)                                                                               products#index {:locale=>"de"}
                             products_pl GET    /produkty(.:format)                                                                               products#index {:locale=>"pl"}
                             products_en GET    /products(.:format)                                                                               products#index {:locale=>"en"}
                                         POST   /produkty(.:format)                                                                               products#create {:locale=>"cz"}
                                         POST   /produkte(.:format)                                                                               products#create {:locale=>"de"}
                                         POST   /produkty(.:format)                                                                               products#create {:locale=>"pl"}
                                         POST   /products(.:format)                                                                               products#create {:locale=>"en"}
                          new_product_cz GET    /produkty/new(.:format)                                                                           products#new {:locale=>"cz"}
                          new_product_de GET    /produkte/new(.:format)                                                                           products#new {:locale=>"de"}
                          new_product_pl GET    /produkty/new(.:format)                                                                           products#new {:locale=>"pl"}
                          new_product_en GET    /products/new(.:format)                                                                           products#new {:locale=>"en"}
                         edit_product_cz GET    /produkty/:id/edit(.:format)                                                                      products#edit {:locale=>"cz"}
                         edit_product_de GET    /produkte/:id/edit(.:format)                                                                      products#edit {:locale=>"de"}
                         edit_product_pl GET    /produkty/:id/edit(.:format)                                                                      products#edit {:locale=>"pl"}
                         edit_product_en GET    /products/:id/edit(.:format)                                                                      products#edit {:locale=>"en"}
                              product_cz GET    /produkty/:id(.:format)                                                                           products#show {:locale=>"cz"}
                              product_de GET    /produkte/:id(.:format)                                                                           products#show {:locale=>"de"}
                              product_pl GET    /produkty/:id(.:format)                                                                           products#show {:locale=>"pl"}
                              product_en GET    /products/:id(.:format)                                                                           products#show {:locale=>"en"}
                                         PATCH  /produkty/:id(.:format)                                                                           products#update {:locale=>"cz"}
                                         PATCH  /produkte/:id(.:format)                                                                           products#update {:locale=>"de"}
                                         PATCH  /produkty/:id(.:format)                                                                           products#update {:locale=>"pl"}
                                         PATCH  /products/:id(.:format)                                                                           products#update {:locale=>"en"}
                                         PUT    /produkty/:id(.:format)                                                                           products#update {:locale=>"cz"}
                                         PUT    /produkte/:id(.:format)                                                                           products#update {:locale=>"de"}
                                         PUT    /produkty/:id(.:format)                                                                           products#update {:locale=>"pl"}
                                         PUT    /products/:id(.:format)                                                                           products#update {:locale=>"en"}
                                         DELETE /produkty/:id(.:format)                                                                           products#destroy {:locale=>"cz"}
                                         DELETE /produkte/:id(.:format)                                                                           products#destroy {:locale=>"de"}
                                         DELETE /produkty/:id(.:format)                                                                           products#destroy {:locale=>"pl"}
                                         DELETE /products/:id(.:format)                                                                           products#destroy {:locale=>"en"}

Bug report checklist

  • I have searched for existing issues and to the best of my knowledge this is not a duplicate
  • I understand that debugging Route Translator is a time consuming task, and I have carefully provided all the information requested
@tagliala
Copy link
Collaborator

tagliala commented Nov 28, 2024

Hi!

Thanks for being part of the Route Translator Community.

I don't know when I will have time to take a look here, because route translator issues are time consuming to review, however

before_action :set_locale

I strongly suggest to avoid this, because the locale will leak to other requests: Route Translator's current implementation, with around_action, is the correct one. Ref: #44

Please also post your controller code, or better, please host on github a test application showing the issue

@staskolukasz
Copy link
Author

staskolukasz commented Nov 28, 2024

Hi,

Thank you for your response! I appreciate it!

Please have a look at the repository https://github.com/staskolukasz/route-translator-test
I recommend you to go through commits section - I tried to keep them sweet and short.

In README.md file there is an instruction how to setup the application.

Also thank you for the great tip regarding #44 - I will adjust my code.

@tagliala
Copy link
Collaborator

Hello,

https://github.com/staskolukasz/route-translator-test/blob/main/app/controllers/application_controller.rb

After a fast look at the application controller, I'm not seeing

around_action :set_locale_from_url

From readme:

  1. If you want to set I18n.locale from the url parameter locale, add
    the following line in your ApplicationController or in the controllers
    that have translated content:
around_action :set_locale_from_url

Note: you might be tempted to use before_action instead of around_action: just don't. That could lead to thread-related issues.

Ref: https://github.com/enriclluelles/route_translator?tab=readme-ov-file#quick-start

@staskolukasz
Copy link
Author

Sir, you are right.

Added around_action as you suggested and everything's good now.
I don't know how I can thank you - just starred the project.

I'm closing the issue.

@tagliala
Copy link
Collaborator

Glad you solved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants