Localization & Internationalization
Total CMS provides comprehensive support for localizing dates, numbers, currencies, and relative time strings. This guide covers the supported languages and how to use localization features in your Twig templates.
Setting the Default Locale
Section titled “Setting the Default Locale”The default locale is configured in Settings > General > Locale. This affects all date, number, and currency formatting throughout your site.
Supported Languages
Section titled “Supported Languages”The following languages have full localization support, including translated relative time strings:
| Language | Locale Code | Example Relative Time |
|---|---|---|
| Arabic | ar_SA | ”منذ شهرين” |
| Czech | cs_CZ | ”před 2 měsíci” |
| Danish | da_DK | ”for 2 måneder siden” |
| Dutch | nl_NL | ”2 maanden geleden” |
| English (US) | en_US | ”2 months ago” |
| English (UK) | en_GB | ”2 months ago” |
| English (Canada) | en_CA | ”2 months ago” |
| English (Australia) | en_AU | ”2 months ago” |
| English (Singapore) | en_SG | ”2 months ago” |
| French (France) | fr_FR | ”il y a 2 mois” |
| French (Canada) | fr_CA | ”il y a 2 mois” |
| German | de_DE | ”vor 2 Monaten” |
| Hungarian | hu_HU | ”2 hónapja” |
| Italian | it_IT | ”2 mesi fa” |
| Japanese | ja_JP | ”2 か月前” |
| Khmer (Cambodia) | km_KH | ”2 months ago” * |
| Norwegian | no_NO | ”for 2 måneder siden” |
| Polish | pl_PL | ”2 miesiące temu” |
| Portuguese (Brazil) | pt_BR | ”há 2 meses” |
| Portuguese (Portugal) | pt_PT | ”há 2 meses” |
| Russian | ru_RU | ”2 месяца назад” |
| Spanish (Spain) | es_ES | ”hace 2 meses” |
| Spanish (Mexico) | es_MX | ”hace 2 meses” |
| Turkish | tr_TR | ”2 ay önce” |
| Ukrainian | uk_UA | ”2 місяці тому” |
| Vietnamese | vi_VN | ”2 tháng trước” |
| Chinese (Simplified) | zh_CN | ”2 个月前” |
* Khmer has partial support - date/number formatting works but relative time falls back to English.
Multilingual Sites
Section titled “Multilingual Sites”For sites with multiple languages, you can change the locale dynamically within your templates.
Setting the Locale
Section titled “Setting the Locale”Use cms.locale.set() at the top of your template to change the locale for all subsequent formatting:
{# Set locale based on page language #}{{ cms.locale.set('de_DE') }}
{# All formatting now uses German #}{{ post.date|dateRelative }}{# Output: "vor 2 Monaten" #}Getting the Current Locale
Section titled “Getting the Current Locale”{{ cms.locale.get() }}{# Output: "de_DE" #}Dynamic Locale from Content
Section titled “Dynamic Locale from Content”If your content has a language field, you can set the locale dynamically:
{# Assuming page.locale contains the locale code #}{{ cms.locale.set(page.locale) }}
<article> <h1>{{ page.title }}</h1> <time>{{ page.date|dateRelative }}</time></article>Date Formatting
Section titled “Date Formatting”Relative Time
Section titled “Relative Time”The dateRelative filter displays dates in a human-readable relative format:
{{ post.date|dateRelative }}{# Output varies by locale: #}{# en_US: "2 months ago" #}{# de_DE: "vor 2 Monaten" #}{# fr_FR: "il y a 2 mois" #}{# ja_JP: "2 か月前" #}Formatted Dates
Section titled “Formatted Dates”Use format_date for locale-aware date formatting:
{# Short format #}{{ post.date|format_date('short') }}{# en_US: "12/31/25" #}{# de_DE: "31.12.25" #}
{# Medium format #}{{ post.date|format_date('medium') }}{# en_US: "Dec 31, 2025" #}{# de_DE: "31.12.2025" #}
{# Long format #}{{ post.date|format_date('long') }}{# en_US: "December 31, 2025" #}{# de_DE: "31. Dezember 2025" #}
{# Full format #}{{ post.date|format_date('full') }}{# en_US: "Wednesday, December 31, 2025" #}{# de_DE: "Mittwoch, 31. Dezember 2025" #}Date and Time
Section titled “Date and Time”Use format_datetime for both date and time:
{{ post.date|format_datetime('medium', 'short') }}{# en_US: "Dec 31, 2025, 3:30 PM" #}{# de_DE: "31.12.2025, 15:30" #}Time Only
Section titled “Time Only”{{ post.date|format_time('short') }}{# en_US: "3:30 PM" #}{# de_DE: "15:30" #}Number Formatting
Section titled “Number Formatting”Numbers are formatted according to locale conventions:
{{ 1234567.89|format_number }}{# en_US: "1,234,567.89" #}{# de_DE: "1.234.567,89" #}{# fr_FR: "1 234 567,89" #}Percentages
Section titled “Percentages”{{ 0.1525|format_percent_number }}{# en_US: "15%" #}{# de_DE: "15 %" #}Scientific Notation
Section titled “Scientific Notation”{{ 1234567|format_scientific_number }}{# Output: "1.234567E6" #}Spelled Out Numbers
Section titled “Spelled Out Numbers”{{ 42|format_spellout_number }}{# en_US: "forty-two" #}{# de_DE: "zweiundvierzig" #}Currency Formatting
Section titled “Currency Formatting”Currencies are formatted with proper symbols and decimal placement:
{{ 99.99|format_currency('USD') }}{# en_US: "$99.99" #}{# de_DE: "99,99 $" #}
{{ 99.99|format_currency('EUR') }}{# en_US: "€99.99" #}{# de_DE: "99,99 €" #}
{{ 99.99|format_currency('JPY') }}{# ja_JP: "¥100" (no decimals for Yen) #}
{{ 99.99|format_currency('SGD') }}{# en_SG: "S$99.99" #}Localized Names
Section titled “Localized Names”Country Names
Section titled “Country Names”{{ 'US'|country_name }}{# en_US: "United States" #}{# de_DE: "Vereinigte Staaten" #}{# ja_JP: "アメリカ合衆国" #}Language Names
Section titled “Language Names”{{ 'de'|language_name }}{# en_US: "German" #}{# de_DE: "Deutsch" #}{# fr_FR: "allemand" #}Currency Names
Section titled “Currency Names”{{ 'EUR'|currency_name }}{# en_US: "Euro" #}{# de_DE: "Euro" #}{# ja_JP: "ユーロ" #}
{{ 'USD'|currency_symbol }}{# Output: "$" #}Timezone Names
Section titled “Timezone Names”{{ 'America/New_York'|timezone_name }}{# en_US: "Eastern Time" #}{# de_DE: "Nordamerikanische Ostküstenzeit" #}Complete Example
Section titled “Complete Example”Here’s a complete example of a multilingual blog post template:
{# Set locale from page content #}{{ cms.locale.set(post.locale|default('en_US')) }}
<article class="blog-post" lang="{{ post.locale|default('en_US')|slice(0,2) }}"> <header> <h1>{{ post.title }}</h1> <div class="meta"> <time datetime="{{ post.date|date('c') }}"> {{ post.date|format_date('long') }} </time> <span class="relative-time"> ({{ post.date|dateRelative }}) </span> </div> </header>
<div class="content"> {{ post.content|raw }} </div>
{% if post.price %} <div class="price"> {{ post.price|format_currency(post.currency|default('USD')) }} </div> {% endif %}</article>Date Format Options
Section titled “Date Format Options”Available format options for format_date, format_datetime, and format_time:
| Option | Description | Example (en_US) |
|---|---|---|
none | No output | - |
short | Abbreviated | ”12/31/25” |
medium | Standard | ”Dec 31, 2025” |
long | Full month name | ”December 31, 2025” |
full | Complete with weekday | ”Wednesday, December 31, 2025” |