In the previous part of this series, we talked in detail about translations for nodes. For this next piece, I've promised to cover site settings and layout (blocks and friends). As the multilingual landscape progressed (Jose Reyero released the first beta version of the Internationalization module for Drupal 7!), I decided to dedicate this piece to site settings only. That sounds pretty basic and boring, but we have some good news and improvements here that developers should hear too! Read on for more information on how this crucial piece of the puzzle looks like in Drupal 7.
No widgets or registry for variables
In the previous piece, we discussed that translating nodes involves either translating their fields individually or making translation sets of nodes. Both are great, and this whole spectrum of features is made possible by fields API providing ways for module developers to describe their fields and the widgets used to edit them as well as storage methods to be implemented independently of those. Now, while site settings are critical pieces to your site's functioning (such as setting primary and secondary links, the default home page, first day of the week or the date format used), there is no standard way to present widgets for these. First day of the week uses a dropdown of fixed items, while default menu settings have a select list fed by the list of menus on the system with the date format selector even revealing a nifty custom date field with JavaScript if needed. So it is not possible to provide an editing UI consistent with the original settings UI somewhere else.
What's an even bigger problem is that we don't even know which variables might be on the system (that is, until the user saves the corresponding settings page at least once), because Drupal has this nice feature to use default values for variables until they get saved.
Attempts to get variables defined
There is a core issue that is being worked on forever that would introduce a variable registry to core. Jose Reyero has especially poured a lot of time into this back then for Drupal 6, and it was picked up again for Drupal 7, but was not ready on time. Because a list of variables was not available and widgets for the variables cannot be defined, in Drupal 6, the solution for translating site settings was to go into your settings.php and define an $conf['i18n_variables']
array that listed internal names of the variables to offer for translation. Then when you visited the corresponding settings pages in some alternate language, the setting was saved as related to that language.
Because a better solution was clearly needed, Jose went ahead and built a variable API in contrib. What does it give you? Well, you (as a developer) can define your module's variables in a standardized format, which information then can be used to automatically remove them when your module is uninstalled or to present standard settings pages for simpler modules. The API also includes support for altering defaults and change tracking via hooks, so other modules can react to settings changes. Tokens are provided for your variables to be used in all kinds of ways. In other words, its Drupal settings API as it should have been! Why is this not in core yet? Well, look back at the ongoing core issue and help get core support these cool things.
For now, since this cannot be put into Drupal 7 anymore, the Internationalization module will rely on the Variable module for settings translation. Now since we know about variables, they can be listed on a settings page to pick which ones should be multilingual-enabled! Let's see how that works!
Putting Variable module to work
Grab the beta1 version of Variable and Internationalization, both released yesterday. You'll see that the main Internationalization module now requires Variable API additionally to the Locale module. You should also notice, that the Internationalization project for Drupal 7 is a whole big family of modules, all trying to fill in one specific role, more fine grained then in Drupal 6. So to have site settings translation, you need to enable the "Multilingual variables" submodule as well (which in turn has more dependencies in the Variable project).
Multilingual settings for Internationalization module can be found at Administer » Configuration » Multilingual settings, and with the Multilingual variables module enabled, you'll see a variables tab right there. While the table includes some variables defined which are not actually in Drupal 7 anymore (see issue), we can step aside that little problem for now, and enjoy that we can select the pieces we'll need translation for.
With this variable selection, when you visit your site settings page, each variable that was multilingual-enabled will have a note that it is handled as such and each will include language switcher links as well to display the same settings page in the selected language. This will of course only work if you have some kind of language negotiation setting based on paths or domains, so make sure to set that up as well like we discussed in earlier pieces of this post series. Otherwise your language switcher links will not actually work here.
Given all this setup, your settings will be translated to the right language as you browse around your site and change languages. Sounds simple, isn't it? Well, it is all made possible if contributed module maintainers consider defining their variables with Variable module's API. Please do! There is absolutely no need to depend on that module, you can merely provide this data and it will be picked up if Variable module is around. That will be of great service for multilingual sites for sure!
String translation and its versatile use
In the next piece I plan to introduce you to string translation, and where is that used to enable translation of various values, such as blocks.
In the meantime, you can still read part 4, part 3 and check out part 2 and part 1 of my series.
Thanks for reading!
Thanks, nice write up. I just
Thanks, nice write up.
I just want to mention all i18n modules (not just i18n_variable) now depend on Variable, as it is used to generate settings forms too for all of the modules.
However I wouldn't recommend this kind of hard dependency yet for other modules, as the variable module is still in beta, and the API may change a little bit. So just declaring your module's variables on a [module].variable.inc file is fine for now.
Please
"(...) make sure to set that up as well like we discussed in earlier pieces of this post series. Otherwise your language switcher links will not actually work here."
Please could you be more specific, since this early part of the building of a multilingual seems quite hard to me? Some links to your previous posts on that subject would be great. Thanks anyway for this series of posts.
Sorry
Sorry, I didn't see your links on the sidebar until a few seconds ago...
menu translation
thanks a lot for your explanations. they helped to me to understand multilingual in drupal 7.
the only thing that is not explained here and i am not been able to find a right way to solve is menu items.
i try to explain my confusion.
i create a node and in it, i assign a menu item in main menu.
i translate the content and i assign a menu item in main menu.
then i go to main menu and select the first menu item for editing and then to translate.
en/admin/structure/menu/item/xxx/translate
in the bottom part of this page, i get :
Translations
Enter items that will be considered as translations of each other.
----
but the select in the other languages have nothing...
if i change to spanish
es/admin/structure/menu/item/xxx/translate
then the select box in this language gets populated
if i save it is ok and it gets as translation, but if i do so with the other languages, since only the select of one language gets populated, they override one each other.
i imagine that i do something wrong in the preferences.
i have tried to variate with language neutral and more, but i dont find a way to do it.
can you explain how do you do it, please?
thanks a lot :)
solution to populate the selects
in admin/config/regional/language/language_switcher i had 'Only current language'. i changed to 'Selected languages from language block' and the selects got populated!
thanks a lot :)