Asok Logo Asok
esc

Type to search across all documentation

1 min read
Edit on GitHub

Internationalization (i18n)#

Asok supports multiple languages out of the box using JSON locale files.

Setup#

Create JSON files in src/locales/:

// src/locales/en.json
{
  "welcome": "Welcome",
  "greeting": "Hello, {name}!"
}
// src/locales/fr.json
{
  "welcome": "Bienvenue",
  "greeting": "Bonjour, {name} !"
}

Usage in templates#

<h1>{{ __('welcome') }}</h1>
<p>{{ __('greeting', name='Alice') }}</p>

Usage in Python#

def render(request: Request):
    title = request.__('welcome')  # "Welcome" or "Bienvenue"
    return request.html('page.html', title=title)

Language detection#

Asok detects the language in this order:

  1. Query parameter: /about?lang=fr
  2. Cookie: asok_lang (set automatically when ?lang= is used)
  3. Accept-Language header: from the browser
  4. Config default: LOCALE in config (default: en)

The language cookie persists for 1 year.

Current language#

request.lang  # "en", "fr", etc.
<html lang="{{ request.lang }}">

Language switcher#

<a href="{{ request.path }}?lang=en">EN</a>
<a href="{{ request.path }}?lang=fr">FR</a>

Clicking sets the cookie and stays on the current page.

Dynamic values#

Use {name} placeholders in your translations:

{
  "items_count": "You have {count} items.",
  "welcome_user": "Welcome, {name}!"
}
{{ __('items_count', count=5) }}       → "You have 5 items."
{{ __('welcome_user', name='Alice') }} → "Welcome, Alice!"

Missing keys#

If a translation key is not found, the key itself is returned:

{{ __('nonexistent_key') }}  → "nonexistent_key"

Translating forms#

Form labels and validation errors are translatable. See Forms and Validation.

__ = request.__

form = Form({
    'name':  Form.text(__('form_name'), 'required|min:2'),
    'email': Form.email(__('form_email'), 'required|email'),
}, request)

Validation errors use v_ prefixed keys automatically:

{ "v_required": "Ce champ est obligatoire.", "v_email": "Adresse email invalide." }

Default language#

In wsgi.py:

app = Asok()
app.config['LOCALE'] = 'fr'  # Default to French