Charlon
Charlon

Reputation: 363

Changing locale but staying on the current page

I did an internationalization of my website. I used https://github.com/enriclluelles/route_translator

Every link are working depending on the current locale

I have 2 buttons like this : EN | FR

You can click on it to change the locale. It's working like this :

  if I18n.locale == :fr
    link_to('en', root_en_path)
  else
    link_to('fr', root_fr_path)
  end

The only problem is that if I'm on a certain page in my website and I change the locale, it will comeback to the root_path

What I want is to stay on the same page.

For example: I have a how_it_works page

If I'm in /fr/how_it_works I want the EN button to link to /en/how_it_works

I've been told to pass the locale as a param but I don't want that because I don't want to have a big link like /fr/how_it_works?locale=en and I'm sure that's a bad design

Upvotes: 1

Views: 1477

Answers (5)

Yannick Lescure
Yannick Lescure

Reputation: 119

What about ? :

<%= link_to "English", current_page_params.merge(locale: :en) %>

See more about it : https://gorails.com/episodes/rails-link-to-current-page-with-params

Upvotes: -1

randmin
randmin

Reputation: 948

I use a similar setup, and came across this (old) question. Matheus answer helped me to order my thoughts, and for me the solution was as simple as

<%= link_to "fr", controller: controller_name, action: action_name, locale: "fr"  %>

Note that this works because I use "scope" in routes.rb:

scope "(:locale)", locale: /en|fr/ do
  ...
end

This way, the locale gets passed on every request, and fetching it is easy

  I18n.locale = params[:locale]

I wanted to share this for others who might come by. Once again, built in rails comes with the power to do amazing things with a few lines.

Happy codin .

Upvotes: 0

Matheus
Matheus

Reputation: 83

Thank good lord for bringing the solution to me! I've just encountered you guys having the same issue so here it is what I have used.

<%= link_to(options = {controller: controller_name, action: action_name, locale: :en} , class: "navbar-item") do %>
    <%= image_tag "gb.svg", size: "24x24" %>
<% end %>

For displaying a link to the same page, however changing locales and using an image as link.

Upvotes: 1

Charlon
Charlon

Reputation: 363

After some research, I found a basic way to do it. I first thought this thing was already implemented in route_translator, but apparently no.

The solution :

  if I18n.locale == :fr
    en_uri = request.fullpath.gsub('/fr', '/en')
    good_link = en_uri[0, 3] == '/en' ? en_uri : root_en_path
    link_to('en', good_link)
  else
    fr_uri = request.fullpath.gsub('/en', '/fr')
    good_link = fr_uri[0, 3] == '/fr' ? fr_uri : root_fr_path
    link_to('fr', good_link)
  end

Upvotes: 0

oreoluwa
oreoluwa

Reputation: 5623

The advice you were given would be the best approach and no, you wouldn't be using a query parameter as you thought.

Rails.application.routes.draw do
  scope ':locale', constraints: { locale: /(en|fr)/ } do
   #define all your scopeable routes within here
  end
end

This way, you can visit /en/how-it-works or /fr/how-it-works. In your ApplicationController, you can do a before action :set_locale where you'd be setting the locale as params[:locale].

Hope that makes it clearer and resolves your issue.

UPDATE

Can't really figure out a better way of achieving this, but here's a way I could immediately work out:

url_params = params.to_h
if I18n.locale == :fr
  link_to('en', url_params.merge(locale: :en))
else
  link_to('fr', url_params.merge(locale: :fr)
end

Upvotes: 1

Related Questions