Translations
Translatable items
Items that are "translatable" are ones which contain text which can be extracted by Grow into message catalogs for translation. Message catalogs can be used to generate translated content.
Grow takes a what you tag is what you translate approach: only things that you deem translatable will be extracted for translation, and then subsequently translated upon request.
Views
UI strings (and other text) in views are translatable. UI strings must be tagged with a template function that indicates the text is translatable. This template function, gettext
, has been aliased to {{_(text)}}
.
<!-- /views/pages.html --> <!DOCTYPE html> <meta charset="utf-8"> <title>{{_('Hello World!')}}</title> <h1>{{_('Page Title')}}</h1> <ul> {% for callout in g.doc.callouts %} <li>{{_(callout.title)}} – {{_(callout.description)}} {% endfor %} </ul> <!-- Using Python-format placeholders. --> <p>{{_('Posted: %(date)s', date='12/25/86')}}
Since Grow translations are opt-in instead of opt-out, it's possible to show translated text from a content document right next to untranslated text.
{{doc.title()}} <!-- Untranslated --> {{_(doc.title())}} <!-- Translated -->
Text replacement
When doing translations there are two ways to text replacement:
{{_('Test out %(name)s in %(text)s', name='Julie', text='indecipherable')}}
{{_('Test out {name} in {text}', name='Julie', text='indecipherable')}}
Named placeholders should be used as other languages may not use the words in the same order.
Content documents
Field names postfixed with an @
symbol are translatable. Note that you should omit the @
when referring to the field in a template. The @ is simply used to tag the field for translation in the YAML front matter.
# /content/pages/page.yaml (content document) $title@: Hello World! sections: - title@: Section A # Extracted for translation. content@: A's content. - title@: Section B # Extracted for translation. content@: B's content. - title: Section C # Not extracted for translation. content: C's content. items@: # Tagged list of strings. - Item 1. - Item 2.
# /views/pages.html (sample usage in a view) {% for section in doc.sections %} <li>{{_(doc.title)}} <!-- Translated. --> <li>{{doc.content}} <!-- Not translated. --> {% endfor %}
CSV files
Messages can be extracted from CSV files by appending @
to a header cell's value.
header1,header2@,header3 Not extracted,Extracted,Not Extracted
Translator comments
You can provide clarifying details about strings to translators by using translator comments. Upon extraction, translator comments appear alongside their corresponding messages in message catalogs. Translators may then reference the comment in order to produce a more accurate translation.
Translator comments are particularly useful to convey restrictions about a string (such as its length) or to clarify context when a string may be ambiguous.
# Translator comments in YAML. prop@: Text to translate prop@#: Comment for translator.
# Translator comments in templates. {#: Comment for translator. #} <h1>{{_('Text to translate')}}</h1>
Extracting translations
To extract translations into a message catalog, tag all translatable items as explained above, and then use the grow translations extract
command. Messages will be extracted to a file /translations/messages.pot
. The message catalog (messages.pot) contains all of your pod's extracted messages.
This file can then be used to create translation catalogs manually using a PO file editor, or integrated with a translation provider such as Google Translator Toolkit.
grow translations extract
Extracted translations can also be audited to find content that is untagged for translation.
grow translations extract --audit
Compiling translations
Grow automatically recompiles translations when the development server starts, builds a pod, and during deployment. Translations must be recompiled before they're visible on your site.
Importing translations
Grow can import translation PO files from external sources. Currently Grow expects a zip file containing one directory named after its locale. Within each directory should be a messages.po
file. Alternatively, you can specify a directory instead of a zip file.
# Structure of source zip file. /foo.zip /de /messages.po /it/ /messages.po
grow translations import --source=<path to zip file or directory of locales>
Untranslated content
To help find content that is in use, but not yet translated you can generate a summary of the missing translations.
# Builds pod and shows untranslated strings.
grow build --locate-untranslated
You can also update the configuration in your podspec to prevent specific deployments when there are untranslated content.