Building a Multilingual Page

SmallBlock CMS supports multilingual publishing out of the box. In this tutorial, you’ll configure language support, create localized versions of a page, and update your templates to switch languages dynamically based on user selection.

By the end, your site will support both static translation (interface text) and dynamic translation (page content stored in the database).

Before You Begin

Make sure you have:

  • Completed the Build Your First Site tutorial.

  • A working PostgreSQL or MariaDB installation with UTF-8 encoding.

  • Basic familiarity with editing templates and configuration files.

How Multilingual Rendering Works

When multilingual mode is enabled, SmallBlock performs the following steps:

  1. Reads the user’s desired language (query string, session, or default)

  2. Loads translations for the page (if available)

  3. Injects template variables such as: - language (active language code) - _() (translation helper)

  4. Renders the page using localized content

The flow looks like this:

digraph G {
    rankdir=LR;
    node [shape=box, style="rounded,filled", fillcolor="#eef3f8"];

    A [label="User Request\n?lang=es"];
    B [label="Language Resolver"];
    C [label="Load Translations\n(database)"];
    D [label="Template Engine"];
    E [label="Rendered Page\n(in Spanish)"];

    A -> B -> C -> D -> E;
}

Step 1 — Enable Multilingual Mode

Open config/settings.ini and add:

[i18n]
enabled = true
default_language = en
supported_languages = en, es, fr

This enables English, Spanish, and French as selectable languages.

Restart the development server:

smallblock runserver

Verify

Run:

smallblock check

You should see:

Multilingual mode enabled (languages: en, es, fr).

Step 2 — Create Localized Pages

Pages can store multiple language versions. You can add translations via the admin interface or from the command line.

### Option A — Admin Interface

  1. Navigate to Pages → Home.

  2. Under Translations, click Add Translation → Español.

  3. Provide a translated title and body.

  4. Save the translation.

  5. Repeat for French.

### Option B — Command Line

smallblock addtranslation home es "Inicio" "Bienvenido a nuestro sitio"
smallblock addtranslation home fr "Accueil" "Bienvenue sur notre site"

Each translation is stored in the translations table.

Verify

Check with SQL:

SELECT page_id, language, title FROM translations;

You should see entries for en, es, and fr.

Step 3 — Add a Language Switcher

In your main template (templates/base.html), add:

<header>
    <nav class="language-selector">
        <a href="?lang=en">English</a>
        <a href="?lang=es">Español</a>
        <a href="?lang=fr">Français</a>
    </nav>
</header>

<main>
    {{ content }}
</main>

SmallBlock automatically reads ?lang= and updates the active language context.

Verify

Navigate to:

http://127.0.0.1:8000/?lang=es

You should see the Spanish version of your content.

Step 4 — Display Localized Interface Text

Use the translation helper _() for static UI strings.

In your templates:

<footer>
    <p>{{ _("All rights reserved.") }}</p>
</footer>

In plugins:

from smallblock.i18n import _

def register(app):
    app.logger.info(_("Plugin loaded successfully."))

When a translation is missing, the default language text is used.

Step 5 — Add Language-Specific Assets (Optional)

To display localized banners, icons, or other assets:

{% if language == "es" %}
    <img src="/static/images/banner_es.png" alt="Banner Español">
{% elif language == "fr" %}
    <img src="/static/images/banner_fr.png" alt="Bannière Française">
{% else %}
    <img src="/static/images/banner_en.png" alt="English Banner">
{% endif %}

Verify

Switch languages and confirm the asset updates.

Step 6 — Test the Full Experience

  1. Visit the home page → English version should render

  2. Visit /?lang=es → Spanish content should appear

  3. Visit /?lang=fr → French content should appear

  4. Check that: - Titles are translated - Body content updates - Static strings use proper translations - Language-specific assets appear

Troubleshooting

Translations not appearing

  • Ensure multilingual mode is enabled:

    [i18n]
    enabled = true
    
  • Language codes must be lowercase.

  • Verify translation entries exist in the database.

  • Restart the server (tags and translations load at startup).

Language switcher not working

  • Confirm templates include ?lang=xx links.

  • Check that your base template includes the language context variable.

Static strings not translating

  • Make sure they’re wrapped in _().

  • Confirm translation catalogs (if used) are generated and loaded.

Next Steps

Continue exploring advanced customization with: