-
Notifications
You must be signed in to change notification settings - Fork 143
Generating translated URLs
If you would like to generate localized URLs in all available locales to link alternative versions of current page, you can use the following syntax:
<% I18n.available_locales.each do |locale| %>
<%= link_to locale, url_for(locale: locale.to_s, only_path: true), rel: 'alternate', hreflang: locale.to_s %>
<% end %>
Bear in mind mandatory conversion of I18n.available_locales
symbols to string (locale.to_s
) in the example above. Adding only_path
will generate relative URLs instead of absolute ones.
To generate URL for a different page you can specify controller's action in the url_for
call:
url_for(controller: '...', action: '...', locale: '...', only_path: true)
Please keep in mind that localized slugs needs extra code.
You will need a custom implementation to deal with this case, in this paragraph we will provide some approaches. Feel free to move this code where you think it belongs (helpers, presenters...) and please edit this wiki if you have better suggestions.
Let's say we have the following:
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
before_action :set_article, only: :show
private
def set_article
@article = Article.friendly.find(params[:id])
end
end
# app/models/article.rb
class Article < ApplicationRecord
extend FriendlyId
translates :title, :slug
friendly_id :title, use: %i[globalize slugged]
end
# config/routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
localized do
resources :articles, only: %i[index show]
end
end
# app/controllers/articles_controller
class ArticlesController < ApplicationController
before_action :set_article, only: :show
append_before_action :set_localized_urls, only: :show
private
def set_article
@article = Article.friendly.find(params[:id])
end
def set_localized_urls
@localized_urls = I18n.available_locales.each_with_object({}) do |locale, obj|
obj[locale] = I18n.with_locale(locale) { article_path(@article) }
end
end
end
<!-- app/views/articles/show.html.erb -->
<dl>
<% @localized_urls.each do |locale, url| %>
<dt><%= locale.to_s %></dt>
<dd><%= link_to url, url, rel: 'alternate', hreflang: locale.to_s %></dd>
<% end %>
</dl>
<!-- app/views/articles/show.html.erb -->
<dl>
<% I18n.available_locales.each do |locale| %>
<dt><%= locale.to_s %></dt>
<dd><%= I18n.with_locale(locale) { link_to url_for(@article), url_for(@article), rel: 'alternate', hreflang: locale.to_s } %></dd>
<% end %>
</dl>
<!-- app/views/articles/show.html.erb -->
<dl>
<% I18n.available_locales.each do |locale| %>
<dt><%= locale.to_s %></dt>
<dd><%= I18n.with_locale(locale) { link_to article_path(@article), article_path(@article), rel: 'alternate', hreflang: locale.to_s } %></dd>
<% end %>
</dl>
Ref: