Skip to content

Customizing Texts ​

A Customizing catalog's human-readable columns, the ones the entry lists in translatable(), are stored as their source-language literal. That keeps them queryable, sortable and always available as a fallback. What the user sees comes from the bundle.

The key ​

customizing.<catalog>.<code>.<column>

For example customizing.document_types.invoice.name. The key lives in the bundle of the module that declares the row: its app's i18n.properties, or its library's messagebundle.properties, shipped with your package, base file and every locale:

properties
# i18n/i18n.properties
customizing.document_types.invoice.name=Invoice
# i18n/i18n_de.properties
customizing.document_types.invoice.name=Rechnung

When two modules add rows to one catalog, each brings the keys of its own rows. A field whose literal is null needs no key. A key missing from the base bundle stops ui5:sync; php artisan ui5:i18n lists every missing one beforehand (Module Bundles).

The table reads in the user's language ​

ui5:sync reads the keys with the rows and writes the texts, in every language of the bundle, to sdk_texts, beside the catalog projection. Name the Eloquent model of your catalog once, with the entry class that declares its rows:

php
// config/ui5.php
'i18n' => [
    'customizing' => [
        \App\Models\DocumentType::class => \App\Customizing\DocumentType::class,
    ],
],

From then on the catalog's columns arrive translated, with no reader code: the request's language, then English, then the base bundle, and the literal where a row has no text. An OData set behind discoverModel translates too, and $filter, $orderby and $search run on the text: name eq 'Rechnung' finds the invoice under German.

A query without the model reads the literals. How a raw-SQL entity set joins the text is on Synced Texts.

The SDK's own catalogs ​

The SDK's partner catalogs, relationship types and partner roles, are wired this way already. Their texts ship with the SDK; ui5:sync writes them with the rows.