Skip to main content

i18n / Translatable Schema Fields

Filinq adopts OpenRegister's register-i18n foundation to serve and store per-language variants of user-facing string fields on its registered schemas. Translations live in the existing object JSON column — no DB migration is required.

See OR's register-i18n spec and the i18n-api-language-negotiation spec for the foundation contract. This page documents only how Filinq consumes that contract.

Translatable fields by schema​

Filinq's register is at v5.5.0. The following user-facing string fields carry "translatable": true and are picked up automatically by OR's TranslationHandler::getTranslatableProperties() at render time:

SchemaSchema versionTranslatable fields
templatev1.1.0name, description, content, category
templateVersionv1.1.0name, description, changelog
dossierv1.1.0name, description
huisstijlv1.1.0name
basev1.1.0name, description
correspondencev1.1.0templateName
signingRequestv1.1.0documentName
signingSessionv1.1.0documentName
signerRecordv1.1.0displayName, declineReason
publicationConsentv1.1.0notes, objectionReason, publicationDecision
publicationProhibitionv1.1.0primaryName, reason, notes
batchCorrespondenceJobv1.1.0templateName

Adding a new translatable field is a schema-version-bump-only operation — set "translatable": true on the property and bump the schema's version. OR's normalizeTranslationsForSave() will wrap existing simple string values under the register's default language on the next write.

Language negotiation in Filinq​

Filinq registers LanguageNegotiationMiddleware in Application::register() so requests that hit filinq routes (not just OR's own routes) push the resolved language onto OR's request-scoped LanguageService. TranslationHandler reads that service when rendering objects, so the right variant comes out.

Priority order (mirrors OR's LanguageMiddleware):

  1. ?_lang=<bcp47> query parameter (canonical override)
  2. ?language=<bcp47> query parameter (alias)
  3. Accept-Language header (RFC 9110)
  4. Register default language (resolved at render time by OR)
  5. Hardcoded nl fallback

Examples — all serve the Dutch variant of the template.name field for a filinq object served at /apps/filinq/api/objects/template/{uuid}:

# Query override (canonical)
curl 'https://example.tld/index.php/apps/filinq/api/objects/template/abc?_lang=nl'

# Accept-Language header
curl -H 'Accept-Language: nl,en;q=0.8' \
'https://example.tld/index.php/apps/filinq/api/objects/template/abc'

# Return-all override
curl 'https://example.tld/index.php/apps/filinq/api/objects/template/abc?_translations=all'

Write side​

POST / PUT / PATCH requests honour X-Translation-Target-Language: <bcp47> — OR's TranslationHandler stores translatable string values under that language code:

curl -X PATCH \
-H 'Content-Type: application/json' \
-H 'X-Translation-Target-Language: en' \
-d '{"name":"Dossier with the citizen"}' \
'https://example.tld/index.php/apps/filinq/api/objects/filinq/abc'

When X-Translation-Target-Language is absent, OR falls back to the register's default language.

Response headers​

Every response from a filinq controller emits:

  • Content-Language: <resolved-tag> — the language actually served
  • X-Content-Language-Fallback: true — present only when OR fell back because the requested language was unavailable on the object

Administrative configuration​

The register's default language is set via OR's admin-settings surface (see OR's register-i18n admin panel). Filinq does not duplicate this configuration; operators configure it once in OR and every filinq object inherits the same default.

Operational notes​

  • No DB migration is required when adding a new translatable field. Existing simple string values are wrapped under the register's default language on the next write by OR's normalizeTranslationsForSave().
  • The OPcache must be cleared after a register-version bump for the new translatable flags to be picked up.
  • If a request asks for a language the object does not have, OR falls back through the register's configured language priority list and emits X-Content-Language-Fallback: true.

See also​

  • openspec/changes/register-i18n/ — the Filinq adoption change
  • OpenRegister's LanguageMiddleware, LanguageService, and TranslationHandler — the foundation contract
  • tests/unit/Middleware/LanguageNegotiationMiddlewareTest.php — 10 tests covering the filinq-side bridge