How Qbix Handles Text: Translation and International

Internationalization & Localization: Text Files, Overrides, Translation Pipelines, and Runtime Interpolation

This article extends the basic Qbix Text & View architecture by introducing a cohesive, production-ready internationalization system. Unlike the ad-hoc approaches used in many ecosystems — Linux .po files, Apple .strings, iOS/macOS .lproj bundles — the Qbix Platform provides a structured, layered, override-friendly, machine-translatable, and plugin-aware model for managing all text across your application.

All of this is expressed using simple JSON trees, combined by the same Q_Tree system that powers Config, Streams, Views, and Permissions.


Separation of Text by Plugin and Domain

Each plugin ships its own text bundle:

Users/text/email/en.json
Users/text/content/en.json
Communities/text/content/en.json
MyApp/text/content/en.json

This structure allows:

  • modular internationalization
  • plugin reuse across multiple apps
  • translation sharing across apps
  • app-level overrides without forking plugins
  • shipping machine translations immediately, fixing them later

Each JSON file is simply a tree of keys mapping to language strings, which may contain placeholders.


Placeholders & Safe Interpolation

Strings support positional and named placeholders:

"ThankForPayment": "Thank you for your payment to {{call 'publisher.displayName'}}"
"SeeYou": "See you at {{1}}!"
"ResetLink": "Click <a href='{{2}}'>here</a> to reset your passphrase."

Placeholders can refer to:

  • {{0}}, {{1}}, {{2}} … positional parameters
  • {{foo.bar.baz}} objects inside $fields, using Q::getObject
  • {{call 'publisher.displayName'}} custom code callbacks

Google-Translate-Safe Placeholders

The translation pipeline rewrites placeholders temporarily, preventing Google Translate from mangling them. For example:

{{1}} → __QBIX_PLACEHOLDER_1__

After translation, placeholders are restored.

This makes automated translation safe.


The Translation Pipeline (translate.php)

The Qbix CLI includes a translation utility that:

  • identifies all text bundles across core, plugins, and your app
  • maintains caches of previous translations
  • does not retranslate files unless explicitly asked
  • handles batch export/import
  • preserves all placeholders
  • provides targeted translation of specific paths

Key Capabilities

1. First-Pass Machine Translation

./translate.php --app
./translate.php --plugin Users

This produces all missing locales using Google Translate (or any configured provider).

2. Retain Manual Translator Work

By default, translations are only generated once.
To redo them:

./translate.php --retranslate Users/text/email
./translate.php --retranslate foo\/bar/baz

Slash-escaping lets you precisely target subtrees.

3. Incremental Translation Workflow

Perfect for:

  • shipping apps quickly with machine translations
  • letting real translators “clean up” later
  • reducing cost by translating only updated/added strings
  • adding new locales on demand

Runtime Loading of Text

All strings are loaded through Q_Text::get() and rendered via Q::interpolate() or Q::text().

Q::interpolate($expression, $fields)

  • Accepts:

  • Replaces placeholders using either:

    • positional parameters
    • or associative structures, even with dotted paths
  • Supports nested objects using Q::getObject()

Q::text($expression)

Same as Q::interpolate, but also applies HTML escaping.
Used for safely inserting text into views.


Overriding Text (Two Mechanisms)

Qbix supports overrides at multiple levels: core → plugins → your app.

1. In-File Overrides Using @override

Your app’s text file can contain:

"@override": {
    "Users/content": {
        "login": {
            "prompt": "Let friends recognize you:"
        }
    },
    "Communities/content": {
        "events": {
            "MakeReservation": "Request to Join"
        }
    }
}

During translation:

  • overrides generate proper per-language files
  • overrides cascade into all languages
  • no need to edit plugin files

Internally uses Q_Tree->merge().

Works both server-side and client-side.


Path-Based Overrides via Config

The second override mechanism works via:

"Q": {
  "text": {
    "Hebrews": {
        "dashboard.php": ["Hebrews/content"],
        "content": {
            "activate.php": ["Users/content", "Hebrews/content"],
            "*": ["Hebrews/content"]
        },
        "email": {
            "*": ["Hebrews/email"]
        }
    },
    "Communities": {
        "controls": {
            "eventReservation.php": ["Communities/content", "Hebrews/content"]
        }
    }
  }
}

Whenever Qbix renders a view (PHP, Handlebars, or custom):

Q::view($template, $fields)

The system:

  1. Looks up the template in the Q/text mapping.
  2. Loads additional text bundles.
  3. Merges all relevant text trees.
  4. Makes them available during that view render.

This allows:

  • view-specific text overrides
  • entire locale-specific content packs
  • community-specific language variants
  • theming and rebranding per domain/app

Client-Side Text Loading

The client mirrors the server model.

Calling:

Q.Text.get("MyApp/content")

fetches text bundles from backend, merges overrides automatically, and makes them available for client-side rendering and interpolation.

This guarantees:

  • consistent text across PHP, JS, Handlebars
  • single source of truth
  • ability to override text without editing templates
  • uniform behavior across plugins

Why This System Works Better Than Existing Standards

Most systems use one of the following:

  • GNU gettext (.po) — brittle placeholders, difficult merging
  • Apple .strings — flat key–value, no hierarchy, hard to organize
  • JSON catalogs in JS frameworks — no merging, no plugin inheritance
  • Ad-hoc YAML or PHP arrays — inconsistent, hard to machine translate

Qbix solves all of these by providing:

  • structured trees (nested JSON)
  • built-in merging and overrides
  • plugin-aware hierarchy
  • app-level layer on top
  • safe placeholder processing
  • integration with views
  • client/server uniformity
  • automated translation pipeline
  • machine-translation bootstrap with human refinement

It is the first system designed from the ground up for:

Modular apps, plugin ecosystems, and multi-tenant deployments.


Example Use Cases

1. Apps with 15–50 Languages

Ship instantly with machine translations, hire translators only where adoption takes off.

2. Multi-Tenant Communities

Each community can introduce language overrides that reflect its culture or terminology.

3. Plugin Marketplaces

Third-party plugin authors ship translations for their own components without interfering with apps.

4. Rebranding & White-Labeling

Domains can override text for branding without touching plugin or app code.

5. Advanced Dynamic Views

Templates automatically load the text bundles they need, based on config.


Bringing It All Together

By combining:

  • text files per plugin
  • safe placeholder interpolation
  • a layered override model
  • a flexible translation pipeline
  • config-based text injection
  • unified client/server loading

…the Qbix Platform provides a robust internationalization architecture far beyond traditional systems. It solves the real-world needs of:

  • large apps
  • modular plugins
  • multi-community systems
  • machine translation bootstrapping
  • human refinement workflows
  • deeply nested views & UI components

Your app can ship globally from day one — while keeping translation costs low, maintainability high, and overrides simple.