Rails では yaml の定義で言語の変更ができるのですが、「少し込み入ったことをしたいなぁ」と試したので、メモです。
参考
やりたかったこと
言語の切り替え機能を維持しつつ、デフォルトではパスに言語を含まないものも許容したい。
要は以下の URL すべてを満たしたい。それも少ない労力で。
- hogehoge.jp/home
- hogehoge.jp/ja/home
- hogehoge.jp/en/home
とりあえず、作ってみる
application.rb
config/application.rb の記述は、Rails ガイドに親切に書かれているので、そのまま踏襲。
1 | require_relative "boot" |
routes.rb
ルーティングは、以下のようにしておく。
1 | Rails.application.routes.draw do |
コントローラー
routes.rb で取り出した locale を i18n の設定として記述する設定を記述。
1 | class ApplicationController < ActionController::Base |
特に変数の設定はしないのでコントローラを作っておくだけ。
1 | class HomeController < ApplicationController |
view
言語の切り替えだけを確認したいので、非常に簡単な実装で。
1 | <%= link_to "en", "/en/home" %> <%= link_to "ja", "/ja/home" %> <%= t(".hello") |
locales
locales は、ja と en を両方用意。
1 | ja: |
1 | en: |
確認
ここまでの実装で起動すると<%= t(".hello") %>
の部分が変わる。
パスと、表示の内容の組み合わせは以下の通り。
- hogehoge.jp/home => ハロワ
- hogehoge.jp/ja/home => ハロワ
- hogehoge.jp/en/home => Hello world
とりあえずできることは確認。
ここで問題 パスが増えたら辛くない?
例えば以下のような状態。
- hogehoge.jp/home
- hogehoge.jp/ja/home
- hogehoge.jp/en/home
- hogehoge.jp/users
- hogehoge.jp/ja/users
- hogehoge.jp/en/users
- hogehoge.jp/users/:id
- hogehoge.jp/ja/users/:id
- hogehoge.jp/en/users/:id
など多数の時。
1 | Rails.application.routes.draw do |
こんな形で locale を含んだパスと、含まないパスをそれぞれ書くのか?という問題。
draw で解決した
この件、drow を使ってまとめてあげると解決。
以下のようにルーティングを記述。
1 | get "home", to: "home#index" |
準備した、root.rb を routes.rb で呼び出す。(名前は変えた方がよかっただろうな。)
1 | Rails.application.routes.draw do |
この書き方をすると、root.rb でパスを記述しておくと、locale 有り無しにまとめて対応できたのでとても楽。
そして、変更箇所が一か所で済むのでとてもベスト。
そのほか小ネタ
いろいろ試していて、気が付いたこと。
パラメータつきの URL を維持したまま、言語切り替え
言語を切り替えるリンクを踏むと、そのページを表示するために使っていた GET クエリパラメータが消えてしまう。
もちろん?a=1
というパラメータを持っていた場合には、次のように対応できる。
<%= link_to "index", home_path(locale: locale, a: params[:a]) %>
が、各ページ作るのは面倒だし、検索ページなどパラメーターが増えた時煩雑すぎる。
こんな形で対応できた。
1 | <% non_locale_path = request.fullpath.gsub(/^\/.*\//, '') %> <%= link_to "en", |
request.fullpath
がパラメーターを含んだパス。
例えば、/ja/home?a=1
というパスが有ったら、home?a=1
だけ切り出して、言語部分と連結してリンクを作る。
これだと、クエリを維持したまま、言語切り替えするリンクが作れる。
draw
を使うと割と解決できてしまうところがわかったのでよかった。
同じことを複数書かなくていいのはやはりいいなと感じるところ。
ではでは。