Skip to content

Synced Texts ​

A bundle is read by key, one text at a time. That is enough for a label, and not enough for a list: a table of document types sorted by name has to sort by the name in the user's language, inside the query. So ui5:sync copies every declared text it syncs into a table, sdk_texts, and the models read their translated columns from there.

What the sync writes ​

For each row it syncs, the worker that owns the row writes the row's texts, in the same run, in every language of the declaring module's bundle (default is the base bundle):

FamilyRowsColumns
Customizingeach catalog's rowsthe columns the entry lists in translatable()
Abilitysdk_abilitiestitle, description
Rolesdk_rolestitle, description
Settingsdk_settingstitle, description
Artifactsdk_artifactstitle, description

The texts are code-owned like the rows: a text the bundle no longer carries is removed, and a row declared away takes its texts with it. Never write to sdk_texts; change the bundle and sync.

How a model reads them ​

A model you name under ui5.i18n gets a global scope that joins sdk_texts and replaces each translated column by its text in the request's language. Where a row has no text, the column shows its literal. Because the column itself carries the text, everything that reads the column follows:

  • an OData entity set behind discoverModel answers in the user's language;
  • $filter, $orderby and $search run on the text: name eq 'Rechnung' finds the invoice under German, and a list sorted by name sorts in German.

The read costs one LEFT JOIN per translated column at one effective language, asked once per request. There is no subquery per row.

The configuration ​

php
// config/ui5.php
'i18n' => [
    'customizing' => [
        \App\Models\DocumentType::class => \App\Customizing\DocumentType::class,
    ],
    'models' => [
        // a model of yours => its LocalizedTableInterface adapter
    ],
],
  • customizing maps the Eloquent model of a catalog to the Customizing entry class that declares its rows. This is the line you add for a catalog of your own (Customizing).
  • models maps any other model to an adapter that says which family and catalog its rows belong to. The SDK's own models are wired here already: artifacts, abilities, roles.

Both are maps and merge key by key with the SDK's defaults: a host adds its own models and keeps the SDK's.

Reading past the model ​

A query that does not go through the model, DB::table(), reads the literals. A raw-SQL entity set that joins a translated table asks LocalizedTexts for the column:

php
use LaravelUi5\Sdk\I18n\Adapters\CustomizingLocalizedTable;
use LaravelUi5\Sdk\I18n\LocalizedTexts;

$query = DB::table('documents as d')->join('document_types as t', 't.id', '=', 'd.type_id');

$name = app(LocalizedTexts::class)->column(
    $query, new CustomizingLocalizedTable(DocumentTypeEntry::class), 'name', request()->getLocale(), 't', 'type_name',
);

$query->select(['d.id', $name]);

See also ​