While this post is intended for developers, it gives high level explanations of the concepts of contexts and comments which might be interesting for everyone who deals with translation of software.
Making original strings easier to translate
When creating code with translatable strings, developers might want to help translators by providing an explanation for the string.
Maybe they also know that translators are commonly presented just with the translatable string. They cannot see any adjacent code, and thus no variable names or other helpful pieces of surrounding text.
It turns out that there are two spots where additional information can be added to a string: via the second parameter of
_x(), or with a
/* translators: */ comment (or the
comment parameter of
Let’s start with the takeaway message first: don’t use context, use a comment.
That sounds quite rigid but brings it to the point. To understand why, let’s look at what context actually is and when it’s used.
Context – oh, at that spot you need to have it translated differently? We can do that!
Practically speaking, every translation requires knowledge of the context of the original string, and translators will commonly ask for it (for example through a screenshot). You could call context the whereabouts of a string.
To correctly translate a string, it can make a big difference what’s shown next to it. Yet, we encourage our developers not to add context when they first create a string. Why?
It’s in the developers nature to reuse things, and we also want to foster reuse: if a string is used in new code that already has been translated before, then consequently there is less work for translators and that part of the new UI is already localized.
When the already translated string has a context, the new string needs to have the exact same context so that the translation can be reused.
So doesn’t the advice to not specify context commonly create problems with wrong translations in some places?
Surprisingly, it doesn’t happen too often. Most of the times the same string is used in different locations with the same meaning.
Occasionally–commonly true for one-word strings–English is less precise than other languages and it turns out that the use of a word in position A needs to be translated differently than when it’s used in position B.
That’s when a translator will ping the developer and show them the two places where the English original string needs two different translations. They’ll agree on a useful context for one (or sometimes both) of the strings which will in turn help the translators of other languages.
The agreed upon context will then be added using
_x() (or the
context parameter of
translate()). Technically speaking, displaying a translation is done with a hash lookup, so both context and string are used for the lookup and therefore enables two separate translations.
As shown by the process above, a developer cannot judge whether the string will require more than one translation when it’s created. Consequently, a context should only be added upon request from translators, when they find that two (or more) separate translations are necessary.
The benefit of reusing more translations outweighs the extra effort to add context retrospectively.
Multilingual developers might already know that a string will need context when they create it, and we don’t want to prevent them from doing so. Just remember that we want to reuse existing translations, it is important to check if the string is already in our GlotPress with the right meaning.
In practice, simply leaving it without context is the easier route. The developer is trying to solve a different problem in the first place.
Comment – explain the original string for translators
We have spent a lot of time explaining context above but let’s come back to the start: developers want to help translators to find the right translation quickly!
The number one thing translators need explained is the variables that are used.
Remember that translators only see the translatable text. They don’t see variable names, they don’t see the code section or function name (for open source software there commonly is a code reference that can be used to look it up but translators cannot be expected to read code).
This is what such a comment looks like in code: (the comment must appear in the previous or actual line)
/* translators: %1$s: domain name, %2$s: date of renewal, %3$s: bundle name */ $body = __( 'The domain %1$s was last renewed on %2$s as part of %3$s.' );
Despite explaining variables being the most common use, any other explanation to translators is highly appreciated. Especially links to screenshots!
Comments don’t affect the lookup of strings. Multiple comments from different locations around the code will be concatenated, and might indicate to translators that a context might be needed to differenciate them.
Context – an example where it’s needed
This has all been very theoretical, so let’s conclude this post with a practical example of where context is required.
Let’s look at the string “Add New”. There are several occurances of it in the sidebar of the WordPress dashboard, where “Add New” can be a submenu item of “Posts” or “Media”.
For translating to Spanish it’s important to know what it actually is that’s going to be added because of the gender of the (imaginarily) following word.
_x('Add New', 'post') and
_x('Add New', 'add new media') have been used to allow translators to have different translations in Spanish and other languages (in the screenshot the grey box is the context):
You can also see that context has been given to strings that do have the same translation in Spanish. That’s because other languages have differences in those cases.
Hopefully with this post we were able to provide you with a better understanding of the two methods for providing translators with additional information, feel free to ask further questions in the comments.
You might also want to take a look at the i18n quiz on developer.wordpress.com for more details around code and translation.