Rails Devise Gem 和 i18n

如何讓 Devise 的登入與註冊頁面的 “錯誤訊息中文化”?

首先,先參考:Ruby on Rails 實戰聖經| 多國語系及時區

要有中文,先得要做好這兩步:

Gemfile加上gem "rails-i18n",然後執行 bundle
修改 config/application.rb 的預設語系:
config.i18n.default_locale = "zh-TW"

有了"rails-i18n",在 Devise 那邊的設定才會有生效。


回到 Devise,
先講結論,Devise 有兩種錯誤訊息的呈現方式,
一種是透過 helper,一種是透過 flash。

登入的頁面是: registrations / new.html.erb
註冊的頁面是:sessions / new.html.erb

稍微觀察一下,發現 registrations / new.html.erb 有這行:

<%= devise_error_messages! %>

但是 sessions / new.html.erb 卻沒有??

根據這邊的介紹,加上去看一下 Devise 官方文件”Configuring controllers”,登入頁是用 flash,而註冊頁是用 helper

Remember that Devise uses flash messages to let users know if sign in was successful or unsuccessful. Devise expects your application to call flash[:notice] and flash[:alert] as appropriate. Do not print the entire flash hash, print only specific keys. In some circumstances, Devise adds a :timedout key to the flash hash, which is not meant for display. Remove this key from the hash if you intend to print the entire hash.

所以要讓錯誤訊息中文化,就必須要分開做


先解決註冊: registrations / new.html.erb

根據 Devise 官方文件:Override devise_error_messages! for views
必須要新增一個 helpers / devise_helper.rb

module DeviseHelper
def devise_error_messages!
return "" unless devise_error_messages?

messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
sentence = I18n.t("errors.messages.not_saved",
:count => resource.errors.count,
:resource => resource.class.model_name.human.downcase)

html = <<-HTML
<div id="error_explanation">
<h2>#{sentence}</h2>
<ul>#{messages}</ul>
</div>
HTML

html.html_safe
end

def devise_error_messages?
!resource.errors.empty?
end

end

然後根據這個檔案裡面的東西去做修改,就可以做出自己想要的樣子。
假設覺得 “ The form contains 6 errors ” 這句話很怪(中文化後會更怪),想要把它拿掉,只要把這句話刪除就好:

<h2>#{sentence}</h2>

再來解決登入:sessions / new.html.erb

參考這篇:How To: Integrate I18n Flash Messages with Devise and Bootstrap加上這段就可以了:

<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>">
<ul>
<li>
<%= value %>
</li>
</ul>
</div>
<% end %>

除了可以放在登入頁面外,也可以把它做成

"app/views/layouts/_messages.html.erb"

用這樣來顯示

<%= render 'layouts/messages' %>

註冊跟登入頁面的錯誤訊息沒問題之後,可以開始來中文化了。

Name 不能是空白字元

這樣的錯誤訊息,對於一般人來講是很奇怪的。

所以我們可以在這個資料夾裡面,

config/locales/

新增任何以 .yml 結尾的檔案,都會被載入:

翻譯檔檔名叫events.yml、zh-TW.yml、en.yml什麼都無所謂,重要的是YAML結構中第一層要對應locale的名稱,也就是zh-TW,Rails會載入config/locales下所有的YAML詞彙檔案。

不過,因為 Devise 已經有專門的中文化檔案了:I18n

可以找到繁體中文:Chinese Traditional

Artoria2e5/devise.zh-TW.yml

複製貼上另存為 devise.zh-TW.yml 就可以了,以檔案名稱來方便辨識為 devise 專用的中文化檔案。

如果有其他的 model 需要使用,譬如說 Post Model 中有其他 attribute 需要用到 validates ,就可以另外用一個 zh-TW.yml

zh-TW:
activerecord:
attributes:
post:
title: "標題"
description: "內容"
subject: "主題"
phase_id: "目前所處階段"
issue_id: "相關徵狀"
user:
nickname: "暱稱"
email: "信箱"
password: "密碼"
password_confirmation: "重覆密碼"

參考資料:

Rails-i18n 國際化初體驗
關於『Name,Email,Password』字樣如何自定義為合適的中文,這裡就要用到國際化的gem了 — — rails-i18n。

注册页的 errors.full_messages 错误提示样式如何修改
把field_with_errors消除

configs/environments/development.rb
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
html_tag.html_safe
end

Rails — 表單 Form:當 form 的錯誤訊息發生, 造成跑版
因為 label 及 text_field 會被 <div class="field_with_errors"> 包起來, 所以造成跑版

  • simple_form 讓表單寫起來更乾淨, 也支援 bootstrap 樣式, 推薦這套, 它也支援 devise
  • bootstrap_form 也是讓表單更簡單, 但預設使用的是 bootstrap 樣式

关于 Devise 的国际化的问题~~~
config.i18n.default_locale = :zh-CN, 重启服务器, 然后rails 就会到 locales文件夹下面去找 “zh-CN”: 开头的 yml文件。找不到会在 显示的地方提示错误的。
作者认为使用者最后总是会去写自己的view所以决定不做 i18n,而是推荐大家能使用 https://github.com/mcasimir/devise-i18n-views 来作 i18n。要记得这个 gem 要在 Gemfile 中摆在 devise 后面才有用处。

另外再加上一个可以利用文件夹的方式来管理本地语言包的配置方式:

config/application.rb
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**',
'*.{rb,yml}').to_s]
config.i18n.default_locale = :"zh-CN"

devise-i18n:devise用到一半才想到要用這個gem,已經來不及了
Assuming you have not previously generated Devise’s views into your project, that’s all you need to do. If you have previously done this, you will need to regenerate your views (see the next section) and then reapply whatever customizations that made you do this in the first place.

Devise 快速上手:很詳細的說明

rails-i18n:中文化