dialectYamlTemplate top-level constant
String
const dialectYamlTemplate
Implementation
const String dialectYamlTemplate = r'''# ============================================================
# Dialect — Localization Convention
# ============================================================
# This file configures Dialect AND teaches AI assistants how
# to work with this project's translations.
#
# If you are an AI assistant: read this entire file before
# extracting or translating any strings. It is the spec.
#
# === The project ===
# See the `project:` block at the bottom of this file.
# Read it first — it tells you what the app does, which
# disambiguates glossary terms (e.g. "Trip" = a booked
# travel stay, not a corporate business trip).
#
# === Where strings live ===
# - Canonical source strings live in dialect/source/en.arb
# (and any other `dialect/source/<source_locale>.arb` if you
# change `source_locale` below).
# - Translated strings live in dialect/translations/<locale>.arb,
# one file per target locale.
# - The CLI syncs filtered output to each platform's directory
# (e.g. Flutter's `lib/l10n/`) on `dialect sync`.
#
# === Key naming ===
# - Keys are flat camelCase identifiers that are valid Dart
# method names:
# checkoutBookNow, commonCancel, settingsDarkMode
# No dots, no dashes, no leading digit, no underscores in
# normal use. This shape is required by Flutter's
# `flutter gen-l10n` and matches Dart method-name rules,
# so every key in en.arb becomes
# `AppLocalizations.of(context)!.<key>` after sync.
# - Logical grouping lives in metadata, NOT in the key:
# "checkoutBookNow": "Book Now",
# "@checkoutBookNow": {
# "namespace": "checkout",
# "description": "..."
# }
# The `namespace` controls which keys sync to which platform
# (see `platforms.<p>.namespaces` below). Cross-platform
# adapters use it to group output (e.g. one .strings file
# per namespace on iOS).
# - Two screens that currently render the same English string
# get separate keys (e.g. `homeHostedBy` and
# `checkoutHostedBy`). Identical-today is a coincidence,
# not a guarantee. Only use the `common` namespace when a
# key is *logically* shared (cancel / save / loading / delete).
#
# === After editing, normalize with the CLI ===
# You do not need to remember sort order, formatting, or
# indentation rules. Add or edit entries in any reasonable
# shape, then run:
# dialect check --fix # normalizes + flags issues
# dialect sync # generates platform outputs
# dialect check # confirms clean pass
# `dialect check --fix` deterministically sorts keys, moves
# `@@locale` to the top, places each `@key` block after its
# own key, strips any `@key` blocks accidentally added to
# translation files, and validates placeholder/plural shape.
# Spend your effort on the SEMANTIC parts (good descriptions,
# good translations, glossary application). The CLI handles
# the rest.
#
# === @key metadata (semantic part — your responsibility) ===
# - Every key in the SOURCE ARB MUST have a "namespace" and a
# "description" field in its matching `@key` entry.
# "namespace": which group it belongs to (see platforms below).
# "description": what the string means *in context*, not
# just what it literally says.
# Bad: "description": "Book now button"
# Good: "description": "CTA on the checkout screen.
# 'Book' is a verb meaning 'make a reservation',
# NOT a physical book."
# - Add "context": "<screen_or_feature>" when the same word
# might mean different things in different places.
# - For strings with variables, add "placeholders" describing
# each variable's type and meaning.
# - Metadata lives only in the SOURCE ARB. Don't repeat it
# in translation files; the CLI will strip it if you do.
#
# === Placeholders ===
# - Use ICU MessageFormat for interpolation: "Hello {userName}"
# - Declare each placeholder in @key.placeholders with at
# least a `type` (`String`, `int`, `double`, `DateTime`).
# - Use the SAME placeholder name in every translation. Do
# not translate the name itself. (`dialect check` will
# catch mismatches.)
#
# === Plurals ===
# - Use ICU plural select:
# "{count, plural, =1{1 item} other{{count} items}}"
# - Cover the CLDR plural categories required by the target
# locale IN ADDITION TO any `=N` exact-match cases. The
# two are independent: ICU evaluates `=N` first and falls
# back to the matching CLDR category. You need BOTH —
# not one or the other.
# Common CLDR sets:
# English: one / other
# German: one / other
# Spanish: one / other
# Arabic: zero / one / two / few / many / other
# Japanese: other (single-form)
# Vietnamese: other (single-form)
# - Mirror any `=N` exact-match cases the source provides.
# Don't synthesize extra `=N` cases the source doesn't have.
# - Worked example. Source (English):
# "{count, plural, =0{No items} =1{1 item} other{{count} items}}"
# Correct Arabic translation:
# "{count, plural,
# =0{لا توجد عناصر} =1{عنصر واحد}
# zero{لا توجد عناصر} one{عنصر واحد} two{عنصران}
# few{{count} عناصر} many{{count} عنصرًا} other{{count} عنصر}}"
# Notice: the `=0`/`=1` mirrors stay, AND all six CLDR
# categories are present. Dropping the categories and
# keeping only `=0`/`=1`/`other` is WRONG — counts of
# 2, 3, 4, 11, 100 etc. will fall to `other` instead of
# the correct grammatical form.
# - The CLI (`dialect check`) flags missing CLDR categories
# as an error in `--strict`. Trust it; it will tell you
# which category you missed.
#
# === Currency, units, dates, numbers ===
# - Do not translate currency symbols, units, or numeric
# values themselves.
# - Match the position of the currency symbol used in the
# source string. Per-locale repositioning of `$` is a
# runtime number-formatting concern (use `intl`), not a
# translation concern.
#
# === Glossary ===
# - Before translating, read dialect/glossary.yaml.
# - The `term` in the glossary is the canonical lemma (e.g.
# "Book" as a verb). Use the appropriate inflection or
# derivation in the target language — "Booking confirmed"
# becomes Spanish `Reserva confirmada` (noun form), not
# `Reservar confirmado` (mechanical verb substitution).
# The `meaning` field tells you which sense applies.
# - If a glossary term appears in a non-literal sense in a
# specific key (e.g. "Book club" meaning a physical book),
# mark the SOURCE key with `"glossary_exempt": true` in
# its `@key` block and leave a brief note in the
# description.
#
# === What NOT to extract ===
# The following are NOT user-facing copy and should remain
# hardcoded in source. Do not add them to ARB files.
# - Personal names (e.g. "Linh Nguyen" sample profile data)
# - Email addresses, phone numbers, URLs
# - Currency amounts ("82", "$246") — these are data,
# passed in as placeholders
# - Dates and times — formatted at runtime with `intl`
# - Language self-names in a language picker
# (the Spanish UI still says "Español" in its picker, so
# these names live in a per-locale data table, not in
# translation files)
# - Brand/product names you would not translate verbally
# - Demo or placeholder content that exists only to make
# the app look populated (sample listings, lorem ipsum)
# If in doubt: ask whether the string would change for a
# different user. If yes, it's data, not copy.
#
# === Workflow you should follow ===
# 1. Read dialect/dialect.yaml (this file) and dialect/glossary.yaml.
# 2. Read dialect/source/en.arb to see what keys already exist
# and the style/length of existing descriptions.
# 3. For extraction tasks: find user-facing strings in the
# source code that are not in the "What NOT to extract"
# list. For each, propose a flat camelCase key, assign a
# `namespace`, and add the key + `@key` block to
# dialect/source/en.arb. Replace the hardcoded string in
# source code with `AppLocalizations.of(context)!.<key>`
# (Flutter) or the platform's equivalent. Do NOT overwrite
# keys that already exist — they are the product of
# earlier decisions.
# 4. For translation tasks: for every key in dialect/source/en.arb,
# ensure a corresponding entry exists in each
# dialect/translations/<locale>.arb. Keep the same key name;
# translate only the value. Preserve placeholders and ICU
# plural structure exactly. Respect the glossary.
# 5. Run `dialect check --fix && dialect sync && dialect check`
# to normalize, generate platform output, and validate.
#
# === Things you must NOT do ===
# - Do not rename existing keys without being asked.
# - Do not change source code to reference keys that don't exist.
# - Do not invent new @key fields outside this convention.
# - Do not translate the source locale itself.
# - Do not delete keys you don't recognize.
# - Do not mirror @key metadata into translation ARB files.
# - Do not use dotted keys (`checkout.bookNow`). They break
# `flutter gen-l10n`. Use `@key.namespace` metadata instead.
#
# ============================================================
project:
name: "Your project"
description: >
One-line description of what your app does. Translators
and AI assistants read this to disambiguate glossary terms.
source_locale: en
target_locales: [] # add the locales you ship in, e.g. [es, fr, ja]
platforms:
flutter:
output: lib/l10n/
format: arb
namespaces: [common] # add more as your project grows
# Per-locale overrides for the length-ratio check.
# Each value is the [min, max] multiplier of source character length.
# Default for locales not listed: [0.3, 2.5].
length_ratio: {}
''';