Guidance on translating plugins
This page describes a recommended approach to writing plugins which can be internationalised.
- As far as possible, put all text in templates. This includes things like pageTitle().
render()it into a string.
- Prefer to translate the actual text in your default locale. But if doing that would be ambiguous for the translator, do it as an identifier, and put the text in your
- Don’t put leading or training whitespace in a translated string, as there’s too much risk it’ll get lost when it’s translated. In a template, write
i("Confirm:") " ", don’t translate the string
- Always use interpolation rather than assembling the output from component parts. Languages change the order, and translators need to see the full context of the string.
- Only translate
O.stop()messages if it’s intended the user will see them. Eg
"Workflow not implemented"should never be seen, but
"You've exceeded your quota"probably should be translated.
- Don’t translate exception messages, because only developers will see them.
- Remember that the translation has to be performed when handling the request, when the user’s locale is known, so you can’t do the translations in ‘setup’ code when the plugin is loaded.
- Use i18n debugging to check you have got all the text.
- Do the actual translations last, when all the text is complete.
Writing a new plugin
- Write translatable code in the first place. It’ll be quicker to do this, than have to come back and mark it up later, as you’ll be writing code in a way that’s amenable to translation.
Translating an existing plugin
- Do a first pass where you do all the easy changes, and mark the complex tasks with
TODO I18Nso it’s easy to find the missing bits later.
- Your plugin may have some “administrative” user interface for troubleshooting. Consider whether it’s necessary to translate this, as it will take you longer to translate the plugin, and the cost of translation will be higher.
- If you are trying to translate text in ‘setup’ code, you might find defining a getter with
__defineGetter__allows you to get request time translation without having to rewrite the code which uses the data structures.
- Define macros in your text editor to make surrounding text with
ia single keypress.
- Legacy Handlebars templates will need to be converted to HSVT.
- Test the full functionality of the plugin to make sure you have got all the text, and the UI still works.
- If you are translating a large application composed of many plugins, rather than small self-contained plugins, it may be easier to extract all the text, then translate it in as a single unit. Place the translated files into a single plugin as