When I was converting my Rails apps from 3.2.13 to Rails 4 I asked this question: Rails 4 - Would Like To Do Custom Error Pages in Public Folder Using I18n . I found out that all I had to do was to create error files for each error code and locale. In my Rails 4 apps I had 404.en.html , 404.fr.html , 500.en.html and 500.fr.html in my public folder. They were working as expected.
I recently converted all of my Rails apps to Rails 5 but had not checked if this still worked until now. I redesigned one of my apps and upgraded to Rails 5.1.1. I recreated the error pages to my new website format. I'm trying to test my error pages in localhost before I deploy my changes to Heroku. I have the following temporary configuration in /config/environments/development.rb
so I can see my error pages.
config.consider_all_requests_local = false
config.action_dispatch.show_exceptions = true
When I display my website in English and force an error the English error page 404.en.html displays as expected. However when I display the French version of the page and force the same error the English error page displays, not the French error page 404.fr.html . I verified several times that the text in the French error file is French, not English.
I've been searching on Stack Overflow and on the web in general but I'm not finding any information about how to do this for Rails 5. Just about all of it is for Rails 2, 3 or 4.
I decided to deploy to Heroku to see if maybe the issue was with my testing using localhost. Unfortunately I have the same problem.
I searched again and saw that in the Rails documentation they use rescue pages so I did a search on the Guides site for 5.0 and found the following about Localized views which briefly mentioned rescue files.
application_controller
before_action :set_locale
def default_url_options(options={})
{ :locale => I18n.locale }
end
private
def set_locale
I18n.locale = (params[:locale] if params[:locale].present?) || cookies[:locale] || I18n.default_locale || 'en'
cookies[:locale] = I18n.locale if cookies[:locale] != I18n.locale
end
Here is my log where the locale is "es"
Started GET "/es" for 127.0.0.1 at 2017-08-12 10:00:34 -0500 Processing by PagesController#home as HTML Parameters: {"locale"=>"es"} es
Here is how the English error page displays with locale es. When I click on any link on this page it displays the Spanish version of the website which I expect since the locale is es.
Here is the es error page in my public folder. You will see the text is in Spanish, not English.
Seems to be working fine on rails 5 (5.1.3). This is how myapp sets the locale in before_action
def set_locale
I18n.locale = params[:locale]
end
And this request http://localhost:3000/users/invalid_id?locale=en
renders en
and http://localhost:3000/users/invalid_id?locale=fr
renders french
My guess would be that you are not setting locale properly in before_action
.
Do Rails.logger.info I18n.locale
to log used locales in your before_action
to debug it further.
One way to add internationalization to your error pages would be to add custom route to a controller and using yml file on config/locales
to implement content in different languages.
First, define error routes and set up a controller to handle those routes
config/routes.rb
AwesomeApp::Application.routes.draw do
# custom error routes
match '/404' => 'errors#not_found', :via => :all
match '/422' => 'errors#unprocessable_entity', :via => :all
match '/500' => 'errors#internal_server_error', :via => :all
...
end
app/controllers/errors_controller.rb
class ErrorsController < ApplicationController
def internal_server_error
render(:status => 500)
end
def not_found
render(:status => 404)
end
def unprocessable_entity
render(:status => 422)
end
end
Then, add I18n definitions configuration for different languages.
For example, for English and French:
config/locales/en.yml
en:
page_not_found: "The page you were looking for doesn't exist."
config/locales/fr.yml
fr:
page_not_found: "La page que vous recherchiez n'existe pas."
Then, use it on the corresponding view files of the ErrorController
's actions. Based on you I18n.locale
value, the views will be translated to desired language.
app/views/errors/not_found.html.erb
<div class="container">
<div class="row">
<div class="align-center">
<h3><%= t('page_not_found') %></h3>
</div>
</div>
</div>
This is a much cleaner way to setup error pages than maintaining different files for different errors on your public folder.
UPDATE
As suggested, this configuration is required on config/application.rb
for this to work:
config.exceptions_app = self.routes
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.