YAML

YAML locale files, from Rails on

YAML has carried Rails translations since version 2.2: config/locales/en.yml, a locale root key, and a readable tree underneath. Symfony and static site generators read it too. It is the most human friendly of the translation formats and the most sensitive to whitespace, and that tension shapes most of its rules.

This page covers the syntax, the quoting rules that keep ICU plurals parseable, and the conventions each framework expects.

config/locales/fr.yml
fr:
  menu:
    home: Accueil
    projects: Projets
  checkout:
    title: Récapitulatif de commande
    items: "{count, plural, one {# article} other {# articles}}"
A Rails style locale tree: language root, nested keys, and an ICU plural in a quoted value.
Download a sample: sample_de.yml

Cheatsheet

YAML locale syntax in five rows

You writeWhat it means
fr: as the root key The Rails locale root convention. The tree under it becomes your keys.
"{count, plural, …}" ICU messages need quotes, since a bare { starts a YAML map. Quoted, the whole plural imports intact.
&defaults, *alias, <<: Anchors, aliases and merge keys resolve on import; every alias becomes an independent copy, so editing one does not edit the other.
Values with : or a leading % Need quoting to parse. When in doubt, quote; a conservative exporter quotes anything not obviously safe.
# comments Legal YAML, but no translation model carries them. Keep translator context in notes on the key; formats built for comments can hold them.

Nested or flat, side by side

The tree Rails expects, or flat dotted keys under the locale root.

nested
de:
  menu:
    home: Startseite
    projects: Projekte
flat
de:
  menu.home: Startseite
  menu.projects: Projekte

Untranslated keys, three spellings

A file can represent a key German has not translated yet three ways: exported empty, left out entirely, or filled with the source language value.

exported empty
checkout:
  title: Bestellübersicht
  confirm: ""
left out
checkout:
  title: Bestellübersicht
source fallback
checkout:
  title: Bestellübersicht
  confirm: Confirm purchase

Conventions

Where YAML translation files live

FrameworkConventional path
Ruby on Rails config/locales/fr.yml, root key = locale
Symfony translations/messages.fr.yaml
Hugo i18n/fr.yaml

Typical flow: GitHub or GitLab watches the repo, new keys import on push, and finished translations return as a merge request that only touches changed strings.

How the frameworks write plurals in YAML

Rails puts CLDR categories in subkeys; Symfony reads ICU messages in intl-icu domain files.

Rails subkeys
de:
  cart:
    items:
      one: "%{count} Artikel"
      other: "%{count} Artikel"
Symfony ICU
cart.items: "{count, plural,
  one {# item}
  other {# items}}"

Rails resolves the category at runtime from the subkeys. On import, category subkeys like these are recognized as one plural with separate forms, not as unrelated keys.

Plurals

Plurals in YAML

Like JSON, the format has no plural syntax, so files encode plurals in the tree they already have. Pick an encoding and see how the same plural grows from English to Polish. Every encoding has a dedicated guide.

en · two forms
items: "{count, plural, one {# item} other {# items}}"
pl · four forms
items: "{count, plural,
  one {# artykuł} few {# artykuły}
  many {# artykułów} other {# artykułu}}"
ar · six forms
items: "{count, plural,
  zero {لا عناصر} one {عنصر واحد}
  two {عنصران} few {# عناصر}
  many {# عنصرًا} other {# عنصر}}"

One quoted string carries every branch.

en
items:
  one: "# item"
  other: "# items"
pl
items:
  one: "# artykuł"
  few: "# artykuły"
  many: "# artykułów"
  other: "# artykułu"
ar
items:
  zero: "لا عناصر"
  one: "عنصر واحد"
  two: "عنصران"
  few: "# عناصر"
  many: "# عنصرًا"
  other: "# عنصر"

CLDR categories as subkeys. This is the Rails idiom, and category subkeys are recognized as one plural on import.

en
items:
  - "# item"
  - "# items"
pl
items:
  - "# artykuł"
  - "# artykuły"
  - "# artykułów"
  - "# artykułu"

A sequence in CLDR order; only position says which form is which.

en · the only shape it has
item: "{{count}} item"
item_plural: "{{count}} items"

Legacy i18next: base key plus _plural, one and other only. Polish and Arabic cannot be expressed in it.

en · two keys
item_one: "{{count}} item"
item_other: "{{count}} items"
pl · four keys
item_one: "{{count}} artykuł"
item_few: "{{count}} artykuły"
item_many: "{{count}} artykułów"
item_other: "{{count}} artykułu"

Modern i18next: one suffixed key per CLDR category.

en
items: "# item|# items"
pl
items: "# artykuł|# artykuły|# artykułów|# artykułu"

Every form in one pipe separated string, the Symfony translation convention.

The categories per language come from CLDR: Polish needs four forms, Arabic six, Japanese only one.

See the same plural in every format.

In locamorph

How locamorph handles YAML

structure

Trees in, trees out

Nested locale trees import as dotted keys and export back as trees. Flat files stay flat. The shape of your file is a setting, not an accident.

plurals

Plurals as ICU messages

All CLDR forms travel inside one ICU message, so a plural never collapses to a single form between import and export.

safety

Indentation you can trust

Exports follow the project’s indentation settings every time. No mixed tabs, no drifting levels, no Monday morning YAML parse error.

Convert

Convert YAML to and from other formats

Conversion is import plus export; the key model is shared, so a Rails tree can leave as anything locamorph writes.

YAML to JSON

A Rails backend growing a JavaScript front end.

  1. Import config/locales/en.yml; the locale root is understood.
  2. The tree structure carries over unchanged.
  3. Export as JSON, nested or flat, for your JS i18n library.

JSON to YAML

The reverse trip, re-rooted for Rails.

  1. Import the JSON file.
  2. Nothing to adjust; keys and plurals map one to one.
  3. Export as YAML with stable indentation and conservative quoting.

YAML to XLIFF

Handing a Rails app to a translation agency.

  1. Import the YAML locales.
  2. Source and target languages pair up per key.
  3. Export XLIFF 1.2 for any CAT tool.

Bring your config/locales

Import a YAML locale file on the free plan and get it back with the same structure, the same indentation and only the translations changed.