Reference → Languages — Reference

Languages — Reference

The Languages surface is the locale-registration plane for an SGEN site. It owns the catalog of language locales the site supports — locale codes, display names, fallback chain, default-locale designation, right-to-left flag, and the per-locale enabled-on-storefront flag. Anything that decides which language to render, which fallback to follow when a string is missing, or which direction to lay out the page traces back to a record managed here.

This page is a reference for platform engineers and integrators who need to understand the surface before extending it, scripting against it, or scoping a localization model. Customer-facing how-tos live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.

This surface is distinct from Translations. Languages registers the locales the site supports — the menu of languages the storefront can switch into, the default for new visitors, and the fallback chain when a string in the active locale is missing. Translations holds the actual translated strings per locale. A locale must be registered here before a translation can be authored against it.


Overview

Languages lives under the Settings module in SG-Admin, in the localization group. The module renders three primary views — the locale list, the locale detail / edit form, and the fallback-chain editor — and exposes a small set of write operations for register, unregister, edit fallback chain, set default locale, and toggle storefront-enabled.

The module is paired by convention: one half renders the views and prepares the catalog data, the other half handles writes and returns AJAX responses. Engineers reading the SG-Admin source will see this split across two controller files; the reference below describes the combined surface as it appears to a calling integration.

A locale identifier is a tuple of a language code and an optional region code — en, en-PH, fr-CA, pt-BR. The Languages surface accepts both bare-language and language-region forms. Region codes resolve against the Countries catalog when present; bare-language locales bypass the country reference.

Where it lives in SG-Admin:

  • Sidebar: SG-Admin → Settings → Localization → Languages
  • URL prefix: /sg-admin/languages/
  • View templates: application/views/Admin/Settings/Languages/
The module surface is intentionally small. The translated strings themselves, the import-export workflow for translation files, and the per-product / per-page locale overrides live in adjacent surfaces (Translations, Pages, Products) — this page covers only the locale registration and the fallback resolution logic.
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Settings → Localization → Languages [ + Register ] │├──────────────────────────────────────────────────────────────────────┤│ Locale Display name Direction Fallback chain Storefront││ ─────── ─────────────── ───────── ────────────────── ──────────││ en English (default) LTR — ✔ enabled││ en-PH English (PH) LTR en-PH → en ✔ enabled││ tl Tagalog LTR tl → en ✔ enabled││ fr Français LTR fr → en ✔ enabled││ ar العربية RTL ar → en — paused ││ zh-Hant 繁體中文 LTR zh-Hant → zh → en ✔ enabled││ ││ Registered: 6 · Default: en · RTL enabled: 1 ││ [ Edit ] [ Edit fallback ] [ Set as default ] │└──────────────────────────────────────────────────────────────────────┘

Actions

The Languages surface exposes the following operations. Each is described by what it does to the data, not by its internal method name.

List and filter

Returns the registered-locale catalog paginated, with locale code, display name, text direction (LTR or RTL), default-locale flag, storefront-enabled flag, and a fallback-chain summary. Supports filter by enabled state, by direction, and by free-text on display name. The default locale is pinned to the top of the list regardless of sort.

View locale

Returns the full record for a single locale — locale code, display name, text direction, default flag, enabled flag, fallback chain (ordered list of locales to consult when a string is missing in this locale), country binding (if a region code is present), and the translation-completeness summary computed against the Translations surface.

Register locale

Opens an empty registration form. Required fields at minimum: locale code, display name, text direction. Optional fields cover initial fallback chain, country binding (auto-suggested when a region code is supplied), and the enabled flag. On submit, the surface validates the locale code against the BCP-47 grammar, validates uniqueness, persists the record, and returns the new identifier.

Edit locale

Loads the locale record into the registration form, pre-populated. Submit replaces the stored locale metadata with the posted values. The locale code itself is read-only after registration — to rename a locale, unregister and re-register (which forfeits the translation completeness state).

Edit fallback chain

Opens a dedicated reorderable editor for the fallback chain. Each step is a locale that already exists in the catalog. The chain terminates implicitly at the default locale — even an empty chain falls back to default. Cycles are rejected at write time (a chain cannot reference itself directly or transitively).

Set default locale

Designates a registered locale as the site default. The default locale is the terminal fallback for every other locale and the locale a visitor sees on first arrival when no preference is captured. Exactly one locale carries the default flag. Setting a new default clears the flag on the previous default.

Toggle storefront enabled

Dedicated toggle that flips the enabled flag. A disabled locale does not appear in the storefront language selector but remains queryable in admin views and remains attached to historical translations. The default locale cannot be disabled — the surface returns a structured rejection.

Unregister locale

Removes a locale from the catalog. The translation strings attached to the locale are not deleted — they remain in the Translations store, orphaned, until cleaned up separately. The default locale cannot be unregistered; rotate the default first.

Engineering note. Unregistering a locale that other locales fall back to is permitted — the fallback chains rewriting is automatic, with each chain rewritten to skip the unregistered step. The Activity Log captures the chain rewrites as part of the unregister event.

Data model

A locale record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.

FieldTypeNotes
idintegerPrimary key. Stable across edits.
codestringBCP-47 locale identifier. Unique. Read-only after registration.
language_codestringThe language half of the locale code (en, tl, fr).
region_codestringThe region half of the locale code, if present (PH, CA, BR). Optional.
display_namestringOperator-facing display name (also surfaced in storefront selector).
directionenumltr or rtl.
is_defaultbooleanExactly one locale carries true.
enabledbooleanWhether the locale appears in the storefront language selector.
country_idintegerForeign key into Countries when region code is present. Null otherwise.
fallback_chainjsonOrdered list of locale codes. Empty means fall back directly to default.
created_attimestampSet on register, immutable.
updated_attimestampTouched on any edit.
Fallback semantics: when the storefront renders a string in locale L, it consults the Translations store for L first. On miss, it walks fallback_chain in order, returning the first hit. If the chain is exhausted, it consults the default locale. If the default locale also misses, the storefront renders the message key itself (so a missing translation is visible in operator review rather than rendering as empty).

Right-to-left rule: the direction flag is read by the storefront layout engine at render time. Switching a locale to RTL automatically applies the RTL layout template to pages rendered in that locale — no per-page edit is required.

Country binding: when a locale carries a region code, the surface auto-suggests the matching country record. The binding is informational — it surfaces in admin views and in the storefront country/locale selector, but does not affect translation resolution.

RENDER REQUEST (locale = fr-CA)│▼┌───────────────────────────────────────────┐│ Translation lookup ││ ││ Step 1: fr-CA store miss ││ Step 2: fr-CA fallback[0] = fr hit ✔ │ → return "Bienvenue"│ Step 3: (skipped — hit found) ││ ││ if all steps miss: ││ consult default locale (en) ││ if default also misses: ││ render the message key │└───────────────────────────────────────────┘

Permissions

Access to the Languages surface is gated at two layers.

Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the Languages surface.

Layer 2 — per-action capability. Within SG-Admin, each Languages action checks a capability associated with the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and the capability map is:

CapabilityAdministratorEditorViewer
List locales
View locale detail
Register locale
Edit locale metadata
Edit fallback chain
Toggle storefront enabled
Set default locale
Unregister locale
Custom roles defined under Settings → Roles override the default map. The capability slugs are stable; the role slugs are configurable.

Self-protection rules. The default locale cannot be disabled. The default locale cannot be unregistered — rotate the default first. The fallback chain cannot reference itself directly or transitively (cycles are rejected at write time). At least one locale must remain registered at all times — the surface returns a structured rejection on the unregister that would leave zero.

Audit. Every write — register, edit, fallback edit, default rotation, enable, disable, unregister — emits an Activity Log entry. The log records the acting operator, the locale identifier, and the change shape. Default rotations and unregistrations write dedicated event types for audit clarity.

REQUEST│▼┌───────────────────────────┐│ Admin gate │ unauth → reject│ (every /sg-admin/* call) │└─────────────┬─────────────┘│ authed▼┌───────────────────────────┐│ Capability check │ role lacks cap → reject│ (per-action) │ (custom roles override defaults)└─────────────┬─────────────┘│ allowed▼┌───────────────────────────┐│ Self-protection rules │ default-disable / fallback cycle /│ │ zero-registered → reject└─────────────┬─────────────┘│ passes▼action executes│▼Activity Log entry

Related references

  • Translations — Reference. Holds the actual translated strings per locale. A locale must be registered here before a translation can be authored. Unregister-with-orphaned-translations is documented there.
  • Countries — Reference. Region codes in locale identifiers resolve against the Countries catalog. The binding surfaces in admin views and the storefront country/locale selector.
  • Pages — Reference. Per-page locale overrides reference locales registered here. A page can be excluded from selected locales.
  • Products — Reference. Per-product locale overrides reference locales registered here. A product can be hidden in selected locales.
  • Currencies — Reference. A locale and a currency are independent — a visitor can browse in fr-CA while paying in PHP. The two surfaces are paired by visitor choice, not by configuration.
  • Settings — Reference. Owns the default direction handling, the locale-selector visibility rule on the storefront, and the BCP-47 grammar configuration. Changes there reshape the registration validation.
For the corresponding customer-facing walkthrough — adding a locale, configuring the fallback chain, switching the default — see the Languages section of the customer docs at /docs/languages.
On this page