Rails I18n multiple files aliasing
I was wondering if it's possible to have multiple files of a locale, maybe organized in directories and still use the YAML aliases, for example:
in a common file:
# config/locales/common/en.yml
en:
first_name: &first_name "First name"
last_name: &last_name "Last name"
and in a more specific file:
# config/locales/models/user/en.yml
en:
helpers:
label:
user:
first_name: *first_name
last_name: *last_name
This will help minimize translations and change in translations. in my rails config, i set it 开发者_运维知识库to load all locale file in subdirectories. This setup does not work for me, i get a bad alias error when i load a page.
I tried having an init script that compiles all the en.yml into one and just use that one file, and the alias works and all, but i cant have the keys merging. For example, the if i have another "helpers" in some other file, it just uses whatever was specified last (in fact, the "en" keeps getting overridden, too) instead of merging the keys.
Or is there a better pattern to all of this? Thank you very much!
As far as I understand you want to either have multiple .yml files with anchors and aliases or have a single file with the key merging feature.
Unfortunately both things are impossible, because of the way Rails works.
Technical background:
There are two major steps which are performed by the I18n backend of Rails using two separate systems:
- Each
.yml
file is loaded individually using a YAML library. That's where the anchors and aliases are resolved and a Ruby hash is built. Duplicate nodes are not allowed in this step, i.e. every node overrides a previous node with the same name and parent. - The resulting Ruby hashes are then merged (deeply). At this point duplicates from different files are allowed, but aliases are no longer available.
That is why anchors and aliases cannot span multiple files. On the other hand you get a neat merge feature which isn't supported by YAML.
In other words: By concatenating everything into a giant file you'd potentially gain the "global alias" feature, but you'd loose the merge/duplicate keys feature. You can have one or the other, but not both. In terms of maintainability the multiple file approach is definitely more pleasant.
PS: Of course the duplication you mention makes me cringe a little, too, but it's better to focus on DRY keys and a good key structure than on DRY translations.
That's because translations often change in time: What was the same in the early stages of your application might be slightly different after your application has evolved. Perhaps at some places it must be "First name" and at another it must be "Enter your first name, please".
I also can imagine that having a canonical master translation doesn't work for every language, regarding grammar and other contexts which have no relevance in English.
So my personal advice would be: Stick with the method suggested by Rails (i.e. multiple files) and ignore some unavoidable duplication.
The default pattern to organize locales is presented here:
http://guides.rubyonrails.org/i18n.html#organization-of-locale-files
Try replace in application.rb default value of *config.i18n.load_path* parameter with that:
config.i18n.load_path += Dir[Rails.root.join('config/locales/**/*.yml').to_s]
It works for me.
精彩评论