Snippets Localization
Elemental CMS provides a flexible system for managing snippets across multiple languages. This guide explains how snippets work with localization and translation features.
How Snippets Work with Languages
Unlike pages, snippets in Elemental CMS are language-agnostic by design. This means:
- Snippets are shared across all languages
- No language-specific snippet folders or files
- Translation happens within the snippet content itself
Translation System
Elemental CMS uses Flask-Babel for internationalization. Snippets can include translatable content using the following methods:
1. Using Translation Functions
In your snippet HTML content, you can use Flask-Babel translation functions:
<div class="welcome-message">
{{ _("Welcome to our website") }}
</div>
<div class="navigation">
<a href="/">{{ _("Home") }}</a>
<a href="/about">{{ _("About") }}</a>
<a href="/contact">{{ _("Contact") }}</a>
</div>
2. Using Translation Keys
You can also use translation keys for more complex scenarios:
<div class="product-card">
<h3>{{ _("product.title") }}</h3>
<p>{{ _("product.description") }}</p>
<button>{{ _("product.add_to_cart") }}</button>
</div>
Language Context in Snippets
When snippets are rendered, they have access to the current language context through the page specification:
Accessing Language Information
Snippets can access language information through the page
context:
<div class="language-specific-content">
<p>Current language: {{ page.language }}</p>
<p>Language code: {{ lang_code }}</p>
</div>
Conditional Content Based on Language
You can render different content based on the current language:
{% if page.language == 'es' %}
<div class="spanish-content">
<h2>{{ _("Bienvenido") }}</h2>
<p>{{ _("Contenido en español") }}</p>
</div>
{% elif page.language == 'en' %}
<div class="english-content">
<h2>{{ _("Welcome") }}</h2>
<p>{{ _("Content in English") }}</p>
</div>
{% endif %}
Translation File Management
Translation files are managed in the elementalcms/translations/
directory:
- Translation files:
.po
files containing translation strings - Compiled translations:
.mo
files for runtime use - Language folders: Each language has its own folder (e.g.,
es/
,en/
)
Adding New Languages
To add support for a new language:
- Create a new language folder in
elementalcms/translations/
- Create
LC_MESSAGES/
subfolder - Add
messages.po
file with translations - Compile to
messages.mo
using Flask-Babel
Best Practices
1. Use Translation Keys
Instead of hardcoding text, use translation keys for better maintainability:
<!-- Good -->
<h1>{{ _("page.title") }}</h1>
<!-- Avoid -->
<h1>Welcome to our site</h1>
2. Keep Snippets Language-Neutral
Design snippets to work across all languages by using translation functions:
<div class="navigation-menu">
<nav>
<a href="/">{{ _("nav.home") }}</a>
<a href="/about">{{ _("nav.about") }}</a>
<a href="/services">{{ _("nav.services") }}</a>
<a href="/contact">{{ _("nav.contact") }}</a>
</nav>
</div>
3. Use Context-Aware Translations
Provide context for translators to understand the usage:
<!-- In your snippet -->
<button>{{ _("button.submit") }}</button>
<!-- In messages.po -->
msgid "button.submit"
msgstr "Submit"
# Context: Submit button in forms
msgctxt "form"
msgid "button.submit"
msgstr "Submit"
Configuration
Language-related configuration in your settings:
{
"cmsCoreContext": {
"LANGUAGE_MODE": "multi",
"DEFAULT_LANGUAGE": "en",
"AVAILABLE_LANGUAGES": ["en", "es", "fr"]
}
}
Language Mode Options
- single: Single language mode (no translation support)
- multi: Multi-language mode with translation support
Working with Translated Snippets
Creating Snippets with Translations
When creating snippets that will be used across languages:
- Create the snippet using
elemental-cms snippets create
- Edit the HTML content to include translation functions
- Add translation strings to your
.po
files - Compile translations
- Test across different languages
Example: Multi-language Navigation Snippet
Here's an example of a navigation snippet that works across languages:
<!-- nav-bar.html -->
<nav class="main-navigation">
<ul>
<li><a href="/">{{ _("nav.home") }}</a></li>
<li><a href="/about">{{ _("nav.about") }}</a></li>
<li><a href="/services">{{ _("nav.services") }}</a></li>
<li><a href="/contact">{{ _("nav.contact") }}</a></li>
</ul>
</nav>
Translation file entries:
# English (messages.po)
msgid "nav.home"
msgstr "Home"
msgid "nav.about"
msgstr "About"
msgid "nav.services"
msgstr "Services"
msgid "nav.contact"
msgstr "Contact"
# Spanish (messages.po)
msgid "nav.home"
msgstr "Inicio"
msgid "nav.about"
msgstr "Acerca de"
msgid "nav.services"
msgstr "Servicios"
msgid "nav.contact"
msgstr "Contacto"
Testing Translations
To test your translated snippets:
- Switch your browser language or use language-specific URLs
- Check that all translation functions render correctly
- Verify that fallback to default language works
- Test with different content lengths (some languages need more space)
Common Issues and Solutions
Missing Translations
If a translation is missing, Flask-Babel will show the original string. To fix:
- Add the missing translation to your
.po
file - Compile the translations
- Restart your Flask application
Translation Not Updating
If translations aren't updating:
- Make sure you've compiled the
.po
files to.mo
- Clear your browser cache
- Restart the Flask application
- Check that the language is properly set in the session
Advanced Features
Pluralization
For content that changes based on quantity:
<div class="item-count">
{{ ngettext('%(num)d item', '%(num)d items', count) }}
</div>
Date and Number Formatting
Use locale-specific formatting:
<div class="date-display">
{{ moment(date).format('LL') }}
</div>
This comprehensive localization system allows you to create truly international snippets that work seamlessly across all supported languages in your Elemental CMS installation.