Read a translatable attribute in one language with a fallback, loop over the channel's languages, and output attribute labels per language.
A translatable attribute holds one value per language, so reading it needs a language code — through i18n.t. Read it bare and you get the whole list of translations as {key: "de", value: ...} pairs, not a value. This page covers i18n.t and i18n.has, the channel’s languages in export.culture_codes, and translated attribute labels.
Read one language — i18n.t
Section titled “Read one language — i18n.t”{{ record.my_translatable_attr | i18n.t 'en-US' }}With a fallback when that language has no entry:
{{ record.my_translatable_attr | i18n.t 'en-US' 'No value available' }}A value stored as an empty string is an entry, so the fallback does not replace it. For “non-empty, or the fallback”, add object.default:
{{ record.my_translatable_attr | i18n.t 'en-US' | object.default 'No value available' }}Which code finds what
Section titled “Which code finds what”The codes are the ones configured under Settings → Languages. A code with a region also answers to its bare language code; the reverse is not true.
| Configured in the account | i18n.t 'en-US' |
i18n.t 'en' |
|---|---|---|
en-US |
finds it | finds it |
en |
finds nothing | finds it |
de-DE and de-AT |
— | 'de' resolves to just one of them; pass the full code |
Check whether a language has a value — i18n.has
Section titled “Check whether a language has a value — i18n.has”True if the attribute has an entry stored for exactly that language.
{{ if record.my_translatable_attr | i18n.has 'de-DE' }} <description>{{ record.my_translatable_attr | i18n.t 'de-DE' }}</description>{{ end }}The channel’s languages — export.culture_codes
Section titled “The channel’s languages — export.culture_codes”export.culture_codes lists the languages in this channel — the ones selected, or all configured languages. export.language_codes gives the language part only, without the region.
{{ for code in export.culture_codes }}{{ code }} {{ end }}en-US fr-FRThat is what lets one template serve every language:
{{ for c in export.culture_codes }} <name lang="{{ c }}">{{ record.my_translatable_attr | i18n.t c }}</name>{{ end }}export.culture_code_uc swaps the dash for an underscore, which some systems require:
{{ for code in export.culture_codes }}{{ code | export.culture_code_uc }} {{ end }}en_US fr_FRAttribute labels in each language
Section titled “Attribute labels in each language”export.attr_label
Section titled “export.attr_label”An attribute’s label in one language, falling back to the attribute name when no translation exists.
{{ export.attr_label 'color' 'en-US' }}export.xml_attr_labels
Section titled “export.xml_attr_labels”Builds a set of XML attributes carrying an attribute’s label in every language of the channel.
<field {{ export.xml_attr_labels 'color' 'label_' }}/><field label_en-US="Color" label_de-DE="Farbe" />Pass true as a third argument to use underscores in the language codes (label_en_US).
For the other attribute metadata — name, whether it is required or translatable — see attribute metadata.
What to read next
Section titled “What to read next”- The data in a template —
record,variants, and plain attributes - Template function reference — everything callable
- Testing and debugging templates — when a value comes out empty

