@spec primary_language() :: String.t()
Gets the primary (default) language code. Returns the Languages module default, falling back to "en-US".
Multi-language data transformation helpers for entity data JSONB.
Multi-language support is driven by the Languages module globally. When the Languages module is enabled and has more than one language, all entities automatically support multilang data. There is no per-entity toggle — languages are configured system-wide.
The data JSONB column stores a nested structure:
%{
"_primary_language" => "en-US",
"en-US" => %{"_title" => "Acme", "name" => "Acme", "tagline" => "Quality products"},
"es-ES" => %{"_title" => "Acme España", "name" => "Acme España"}
}The primary language always has complete data. Secondary languages store only overrides — fields that differ from primary. Display merges primary values as defaults with language-specific overrides.
The _title key stores the record title alongside custom fields,
unifying title translation with the same override-only storage pattern.
The title DB column remains a denormalized copy for queries/sorting.
Builds language tab data for the UI from the Languages module. Returns a list of maps with code, name, flag, and is_primary fields.
Checks if multilang is enabled globally. Returns true when the Languages module is enabled and has more than one language.
Gets the list of enabled language codes. Returns at minimum the primary language.
Converts multilang data back to flat structure. Returns primary language data.
Extracts the data map for a specific language from a record's data.
Gets the primary language data from a record (for display in lists etc).
Gets raw (non-merged) language-specific data for a language. Used by the form UI to detect which fields are overridden vs inherited.
Checks if data needs re-keying (embedded primary != global primary). Returns re-keyed data if needed, original data otherwise.
Converts existing flat data to multilang structure.
Checks if a data map uses the multilang structure.
Presence of _primary_language key indicates multilang.
Gets the primary (default) language code. Returns the Languages module default, falling back to "en-US".
Merges language-specific form data into the full multilang JSONB.
Re-keys multilang data to a new primary language.
@spec build_language_tabs() :: [map()]
Builds language tab data for the UI from the Languages module. Returns a list of maps with code, name, flag, and is_primary fields.
@spec enabled?() :: boolean()
Checks if multilang is enabled globally. Returns true when the Languages module is enabled and has more than one language.
@spec enabled_languages() :: [String.t()]
Gets the list of enabled language codes. Returns at minimum the primary language.
Converts multilang data back to flat structure. Returns primary language data.
Extracts the data map for a specific language from a record's data.
For multilang data: returns merged data (primary as base + overrides). For flat data: returns data as-is (backward compat).
Gets the primary language data from a record (for display in lists etc).
Gets raw (non-merged) language-specific data for a language. Used by the form UI to detect which fields are overridden vs inherited.
Checks if data needs re-keying (embedded primary != global primary). Returns re-keyed data if needed, original data otherwise.
Converts existing flat data to multilang structure.
Checks if a data map uses the multilang structure.
Presence of _primary_language key indicates multilang.
@spec primary_language() :: String.t()
Gets the primary (default) language code. Returns the Languages module default, falling back to "en-US".
Merges language-specific form data into the full multilang JSONB.
For primary language: stores ALL fields. For secondary language: stores only fields that differ from primary.
Re-keys multilang data to a new primary language.
Updates _primary_language to the new primary and ensures the new
primary has complete data (fills missing fields from the old primary).
All secondary languages are recomputed: their overrides are recalculated
against the new promoted primary, and languages with zero overrides are removed.
Returns data unchanged if already using the given primary or not multilang.