-
Notifications
You must be signed in to change notification settings - Fork 68
Recursively merge language specific site.data
.
#59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
You can see this addressing the problem in #58 in my partially-translated--fixed branch. It takes the commit from #58 which reproduces the problem, and rebases it on this branch. |
Thanks for the PR @pserwylo ! I'll take a look at it later tonight. I have a few other changes I've been procrastinating on, so I'd like to get those in along with any other changes before potentially cutting a new release 👍 |
No worries @untra, thanks for letting me know. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made changes last night that will assist with developing a 1.3.0 branch. Among these is getting tests going for coordinate. Please modify your changes to the coordinate.rb
file, and add in a test for the coordinate_spec.rb
file
I'll make adding the test super easy: right here, add: it 'should recursively merge the site.data.active_lang to the site.data' do
@site.active_lang = 'fr'
hook_coordinate(@site)
expect(@site.data['strings']['ice cream']).to eq('crème glacée')
expect(@site.data['strings']['apple']).to eq('apple')
end |
Oh how of course writing tests makes me realise my broken assumptions. It turns out that this is the structure we are using in our data files:
With our blank
@untra: Is the intent that you expect people to put their default strings directly in their I can change the merging logic to do the following:
Right now it only:
Without that, then the test above wont pass because site.data['en'] never gets merged in when the active lang is 'fr'. |
Specifically, I'd change it to this: def hook_coordinate(site)
# Copy the language specific data, by recursively merging it with the default data.
# See: https://www.ruby-forum.com/topic/142809
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
if site.data.include?(site.default_lang)
site.data = site.data.merge(site.data[site.default_lang], &merger)
end
if site.data.include?(site.active_lang)
site.data = site.data.merge(site.data[site.active_lang], &merger)
end
site.collections.each do |_, collection|
collection.docs = site.coordinate_documents(collection.docs)
end
site.pages = site.coordinate_documents(site.pages)
end Which makes the following test pass: it 'should fall back to the default_lang when using translated site data' do
@site.active_lang = 'fr'
hook_coordinate(@site)
expect(@site.data['foo']).to eq('frbar')
expect(@site.data['baz']).to eq('databaz')
expect(@site.data['strings']['ice cream']).to eq('crème glacée')
expect(@site.data['strings']['apple']).to eq('apple') # This is populated from @site.data['strings'][@site.default_lang]['apple']
end |
Good new solution. I like that you're looking out for the edge cases. With your default strings in the data directory you can still achieve the best of both worlds. I'll need to write some documentation about how to properly lay out strings in the data directory.
I would like to accommodate both approaches, however I do believe that combined with your #60 approach to all language subdirectories, this new solution should have a proper configuration that will ensure fallback to a default set of strings, even when a
I think that is certainly the correct approach. Because it merges recursively, it will favor Thanks for your help with this! Make the changes to the PR at your conveience, add the test(s), and I'll give it the 👍 |
Previously this would only overwrite the entire data files contents with that of a language specific version. Now it merges the language specific data file with the default, overriding whenever a new value is found in the language specific version. This ensures that untranslated strings revert back to their default value if a data file is only partially translated.
Supports first prefering language specific strings for the active_lang, then falling back to those from default_lang (if they exist). Finally, if neither exist, it will try to fall back to the non-language specific default strings.
ea0b78b
to
0a32d13
Compare
Alright, I've ammended the first commit to support defaulting to |
Previously this would only overwrite the entire data files contents with
that of a language specific version. Now it merges the language specific
data file with the default, overriding whenever a new value is found in
the language specific version. This ensures that untranslated strings
revert back to their default value if a data file is only partially
translated.
Note that this doesn't try to do anything smart with arrays. If both the original data file and the language specific version contain an array, then the array from the language specific version should get chosen.
Fixes #58.