Internationalization (i18n)
OCapistaine supports multiple languages through a simple JSON-based translation system.
Supported Languages
| Code | Language |
|---|---|
fr | Français (default) |
en | English |
File Structure
app/
├── i18n.py # Translation utilities
└── translations/
├── fr.json # French translations
└── en.json # English translations
Usage
Basic Translation
from app.i18n import _
# Simple key lookup
st.title(_("app_title"))
# With format variables
st.caption(_("sidebar_session_id", user_id="abc123"))
# Output: "ID: `abc123...`"
Language Selector Widget
from app.i18n import language_selector
# Place in sidebar
with st.sidebar:
language_selector()
Check Current Language
from app.i18n import get_language, set_language
lang = get_language() # Returns "fr" or "en"
set_language("en") # Switch to English
Adding a New Translation Key
Step 1: Add to French translations
Edit app/translations/fr.json:
{
"existing_key": "Texte existant",
"my_new_key": "Mon nouveau texte en français"
}
Step 2: Add to English translations
Edit app/translations/en.json:
{
"existing_key": "Existing text",
"my_new_key": "My new text in English"
}
Step 3: Use in code
from app.i18n import _
st.write(_("my_new_key"))
Adding Format Variables
For dynamic content, use {variable} placeholders:
fr.json:
{
"welcome_user": "Bienvenue, {name} !"
}
en.json:
{
"welcome_user": "Welcome, {name}!"
}
Usage:
st.write(_("welcome_user", name=user.display_name))
Adding a New Language
Step 1: Create translation file
Create app/translations/de.json (example for German):
{
"app_title": "Ò Capistaine",
"app_subtitle": "Bürgerliche Transparenz für Audierne",
...
}
Step 2: Register the language
Edit app/i18n.py:
LANGUAGES = {
"fr": "Français",
"en": "English",
"de": "Deutsch", # Add new language
}
Key Naming Conventions
Use descriptive, hierarchical key names:
| Pattern | Example | Use Case |
|---|---|---|
section_element | sidebar_session | Section headers |
section_action | sidebar_new_conversation | Buttons/actions |
feature_state | contributions_status_open | Status labels |
feature_message | chat_welcome | User-facing messages |
Fallback Behavior
If a key is not found in the current language:
- Returns the key itself (useful for debugging)
- No error is thrown
_("nonexistent_key") # Returns "nonexistent_key"
Translation Files Reference
See the complete list of available keys in:
app/translations/fr.json(source of truth)app/translations/en.json