What the compiler checks of translations
On this page
jadpo check checks every language file against the messages, enums,
emails and failures it words. Each problem has its own error, listed at the
end of the page.
Mistakes in a language file
- a member that no message, enum, email or failure declares
(
translation.member_unknown, with the nearest name); - a member written twice (
translation.member_duplicate); - a member in the wrong shape for what it words, such as a string where a
block of values is needed, or the reverse (
translation.wording_shape); - a wording that isn't a plain string with
{field}placeholders (translation.wording_invalid); - a variant that isn't a value of the enum, or a plural form the language
doesn't use (
translation.variant_unknown); - a missing variant or plural form (
translation.variant_missing); - a placeholder that isn't a field (
translation.placeholder_unknown); - an amount of money or a percentage written without its style, or a style
on another field (
translation.placeholder_style); - a field type a wording can't hold (
translation.field_type), or more than one enum orPluralCountfield (translation.too_many_selectors); - a language file that isn't named for a locale
(
translation.file_name_invalid), or is for one the application doesn't support (translation.locale_unsupported); - a call of no message (
translation.message_unknown); - a
locale:that isn't a supported locale (type.locale_unsupported); - translations in a project with no
locales { }(translation.locales_required).
Missing wording
Every supported locale must be complete, unless it is listed in
in_progress:. A message, a failure a route can answer with, or an enum
once any language words it, missing from such a locale is an error:
translation.file_missing for a locale with no language file,
translation.wording_missing for a file that lacks a member. The error's
next: names the file and the member to add, with the placeholders to use,
and ends (agent): your coding agent can add it itself.
A field no wording uses
A field that no wording in a language uses is translation.field_unused.
One variant leaving a field out is normal. Jadpo has no warnings, so this
is an error, but a judgement call: a person can answer it by writing
decline translation.field_unused: "<reason>" above the member
(Declining a judgement call).
That is right for a language that needs no such word.
Locales in progress
in_progress: is how you say a locale isn't finished. A locale it lists
falls back where its language file has no wording, with no error: to the
same language's regional sibling first (fr_ca tries fr_fr, if
supported), then to the default locale. The sentence is written entirely in
the language it came from.
Wording the file does give is checked as for any locale, so a mistake in
it is still an error. Removing the locale from in_progress: makes the gaps
errors again. Quality comes from the review setting below, not from
waiting. jadpo translations missing lists what an in-progress locale falls
back on.
Stale translations: sources.jadpo_record
A translation is stale when the wording it was translated from has changed
since. Jadpo knows from a file it writes in each translations/ folder,
sources.jadpo_record, which you commit. It is a record
(The record format) headed
record translations 1, written by jadpo translations update, listed by
jadpo records and merged by git's union merge.
It has one line for each translation outside the default locale, sorted,
with a hash of the default wording it was translated from (from) and of
its own wording when that was recorded (wording). A hash is the first 12
hex digits of BLAKE3 over the member's whole text, every value and plural
form in name order, so reordering a block changes nothing.
A translation whose from no longer matches today's default wording is
stale (translation.stale). That is an error until it is translated again
and recorded. An in-progress locale's stale translation is listed by jadpo translations missing instead.
A translation with no line yet isn't stale: it was never recorded, so
nothing says what it was made from. (With review required, it is new and
not accepted.) So a project that never runs jadpo translations update
sees no stale error.
A line Jadpo can't read is translation.sources_invalid, which jadpo translations update fixes. A header Jadpo didn't write, or lines out of
order, is record.edited, and a newer format is record.format_newer, as
for every record (Checking a record).
Review
By default a translation needs no one to accept it. To have a person accept
each one, set translations: { review: TranslationReview.required } in
application { }; the default is TranslationReview.none. Then every new
or changed wording outside the default locale is not accepted until a
person runs jadpo translations accept <locale>, which records the
acceptance in the same record. A line says a wording is accepted only while
the wording is the one the line hashes.
jadpo translations missing lists wording that isn't accepted. It isn't an
error, so jadpo check passes with it: your code review is the gate.
Jadpo can't tell who wrote a wording, so this means "changed and not yet
accepted", not "written by an agent".
A translations: option other than review: is
translation.option_unknown, and a review: that isn't a
TranslationReview is translation.review_invalid.
application { translations: { review: TranslationReview.required }}locales { default: Locale.en_gb supported: [Locale.en_gb, Locale.de_de]}
Jadpo's and packages' wording
The root folder's wording of Jadpo's and packages' text is checked too, each problem with its own error:
- Jadpo's messages. A supported locale that isn't in progress, in
which Jadpo ships no wording and the root file words none of the messages
of a feature the app has on, is one error for the locale, listing what is
missing (
translation.jadpo_missing) and pointing atjadpo translations builtin. A message of a feature that is off istranslation.feature_off, and a group of the root file that names no owner istranslation.group_unknown. Everything else about a group's wording is checked as a folder's is:translation.member_unknown(with the nearest of Jadpo's messages),member_duplicate,wording_shape,wording_invalid,placeholder_unknown,variant_missingandvariant_unknown. - The root folder's record. The root folder has its own
sources.jadpo_record, kept by the same commands, with the owner in the member's name (translation fr_fr.jadpo.invalid_input from ... wording ...), as a package's ispostcodes.<message>. - A library package's text. Its own language files are checked by
themselves, as a domain's are. Its group in the root file is checked
against its public messages, enums and failures
(
translation.member_unknown, with the nearest of them). Each supported locale not in progress must word all of it in the root file or the package's own file (translation.wording_missingwith a root file for the locale,translation.file_missingwithout). A call through the package of a message it doesn't have istranslation.message_unknown, and of one it doesn't makepublic,package.not_public. A root record line is made from the app's default wording or, when the app gives none, the package's, and is stale when that changes (translation.stale).
Markdown for agents: /docs/what-the-compiler-checks-of-translations.md.Built from Jadpo main at a707efb.