-
Notifications
You must be signed in to change notification settings - Fork 105
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
Multilingual solution based on data language files #45
Comments
I would love to read an answer about this. I have a site to make in two languages and I don't know how to do it with panini. |
Me too. My company sends newsletter (I use foundation for emails) to 8 different countries. Would be awesome to have a solution! |
That would be awesome! Actually we do it like that (out of the box):
Each page contains localization inside the front matter block. Downside: For common partials like footer or header, all translations are duplicated. After compiling we have a batch script wich generates npm packages for each template namespace to use it in our services. |
Nothing new here? |
@XmlmXmlmX I ended up mirroring the project on GitLab and tweak it to my needs on a custom branch. |
@fdeneux can you share your work or make a PR here? |
@XmlmXmlmX Looks like @fdeneux's work is here. I'm in need of a similar solution, but I haven't tried this fork yet. |
Hey, I have published my solution in a gist here. It's a bit more complex, because the requirements are very high (currently 12 pages * 31 languages = 372 different emails). Hopefully this enhancement will be integrated sometime. @gakimball Is it worth to make a pull-request? |
@XmlmXmlmX This looks great! Let's talk a little about how we can simplify it. In general I want to give people one way to do things. Here are a few ideas and questions. HelperFor the {{#i18n 'path.to.key'}} Locale StringsFor file structure, I think we should enforce one method of organizing and one style of writing file names. A basic structure might look like this (taking inspiration from other i18n libraries I've used):
That being said, some folks will mostly likely have too many translation strings to reasonably fit in one file, so an alternative way would be:
Now, that is perhaps giving people two ways to do things, but the hierarchy is the same. If a locale is a single file, accessing it involves writing the object path to the key. If a locale is multiple files, it's still an object path, but the first key is the name of the file. Notably, this doesn't enforce any particular style of organizing translation strings. If you want to go by page, you can do that, or if you want to keep things in one place, you can do that as well. This does differ from your approach in that it doesn't automatically load a set of translation strings based on the page. With this approach, you'd have to specify the page each time, like so: <h1>{{#i18n 'home.title'}}</h1>
<p>{{#i18n 'home.subtitle'}}</p> This would make mixing global and page-specific strings easier, however. It also matches the way data files are loaded: one file = one object with name of file. Thoughts on this approach? |
Hey! I've implemented the basics of this in 8b2d617. Here's what the input/output looks like: |
Closing this as the basics of i18n are in place. If people have more ideas we can definitely talk about them :) |
@gakimball Trying to use your solution, by changing
|
@XAMelleOH The API has changed. Try this: const panini = require('panini/gulp');
gulp.task('pages', () => {
return panini('src', {/* options */})
// Put the usual plugins like Inky here
.pipe(gulp.dest('dist'));
}); |
@gakimball Thank you, it works as expected. The only question, when we used
How can we achieve the same when panini handles that by itself? Also, how could I reset Panini's cache of layouts and partials? (previously it was just |
The folder structure is a bit more stringent now, which is an intentional simplification of the library. What's your use case for wanting to ignore specific pages? (As a temporary workaround, you can use gulp-filter to filter out the processed files.)
This is another part of the API that isn't finalized yet. When used standalone or in a CLI, Panini will do this refreshing automatically, but I haven't yet worked out how it should be handled within Gulp. To get around it for now, you can create a new Panini instance every time your task runs. const panini = require('panini/gulp').create;
gulp.task('pages', () => {
panini()('src', {})
.pipe(gulp.dest('dist'));
}); Thanks for bearing with me :) |
Hi @gakimball, first thank you for the integration of this function. Now I finally found time to look at it more closely. For me the i18n-helper does not work. Localized folders are created, but with errors. In one of my pages I use
The result is: Panini Error
Stack Trace:
Is |
@XmlmXmlmX Here is a new docs (wip): https://gist.github.com/gakimball/e1016f4003b683277d8fd1b3323ad9d9 So, the correct syntax |
@XAMelleOH What should the options part look like to make it work with Foundation Emails?
|
@mescie Here are all the current options. Most of them are just for the names of folders, so if you use the defaults, you probably won't need to change anything. |
Ok, this works pretty good now. Next level would be to be able to use helpers in combination, just like this:
|
I've added the default options, but it wont run for me yet.
I get the following error.
Im kind of new to javascript, any tips on how to fix this? |
@XmlmXmlmX You should be able to do this with Handlebars subexpressions. By wrapping a Handlebars statement in parentheses, you get a self-contained value that you can pass to another statement. So if you wanted to iterate through an array pulled from a locale file, you should be able to do this: {{#each (translate 'disclaimer.paragraphs') }}
{{/each}} @mescie Remove the entire options object and see if that works. By default now, pages go in a |
Thank you @gakimball. |
Sorry for spamming you @gakimball :) Since I use Panini Error
Stack Trace:
|
@XmlmXmlmX No worries, thanks for bearing with me! You're one of the first people to use this besides me, so this is very useful. The way helpers work is changing around in Panini 2.0. Instead of separate {{#if (currentPage 'index')}}
{{else}}
{{/if}} |
I was having problems with the reload on Gulp too. The solution to use the |
I have successfully added localization using the above approach. I'm wondering how it's possible to pass the localized strings for meta data as well, which seems to involve passing data from the page or partial to the layout where the meta data exists. I tried using the {{ translate 'string' }} method
but I just get [object object] for the returned string. Anybody have experience with this? |
@gakimball after more digging, looks like my question is answered in here #66 (not possible to use helpers in front matter). Do you have any other ideas? I'm trying to figure out how to get translations for the meta tags like title/description, etc. which exist in the layout (though it will vary by page) perhaps if there were a way to make the translation key dynamic, it could be used to create a new key based on a page. maybe using a subexpression to make the key dynamically generated? |
I was able to resolve by using subexpressions: simple execution:
for_key.js
basically what it does is dynamically update the key passed to the translate helper based on the page/view context. Perhaps there are ways to improve this, but it seems to be working for now :) |
@eliotc1986 I think that's a solid solution. In Panini, any data/translations you define are global, so there's not really a concept of page-specific data. In some cases this is maybe unwieldy, but Panini is generally designed for small- to medium-sized sites. You could also use Handlebars inline partials, which would allow you to change the HTML of a layout from within a page: <!-- Layout -->
<title>{{> page_title}}</title>
<!-- Page -->
{{#* inline 'page_title'}}
{{ translate 'regions.tohoku.meta.title' }}
{{/inline}} However, it's a little more verbose. My only suggestion for your approach would be to change the |
@gakimball Thank you for the reply and for the advice! I really appreciate it. Using a you mean to do this right:
|
Yep, that's the idea.
Thank you so much! :) I haven't had time to work on it in a minute, but I'm glad people are still finding it useful. If you have any feedback or bugs, feel free to open a new issue. |
Several people asked for multilanguage/i18n solutions for panini (foundation#180, foundation#45). Adding this to the readme can help others.
Hello, first of all great work on panini!
I'm looking for a specific multilingual solution, where you have a single multilingual structure (page) that is compiled to language specific html files for every language file in data.
Example:
This can be achieved with the combination of
gulp-swig
andgulp-data
, but I'd like to know if such a solution is possible with panini as I really like the generator.An even better solution is to compile to a folder for every language:
Another interesting solution is to have a structured languages data subfolder, that would allow you to split your data files.
The text was updated successfully, but these errors were encountered: