Rails projects store translations under config/locales/{locale}.yml with every entry nested under a single root key matching the locale (en:, de:, etc.). Many tools in the broader localization ecosystem — translation memory engines, gettext-based runtimes, third-party glossaries, and human translators armed with poedit — speak .po natively but not Rails YAML. Bridging the two formats is necessary whenever a Rails app needs to plug into a workflow built around gettext: integrating with a TMS, sharing strings with a Django or Flask service, or running a CLI tool that expects PO input.
i18n-convert reads the YAML document, recognizes the single top-level locale key as the source-language marker, and unwraps everything below it. Nested mappings under that locale root (the common Rails convention for grouping app.title, app.subtitle, and so on) are flattened into dotted keys to fit PO's flat msgid namespace — app: { title: "..." } becomes msgid "app.title". Each leaf becomes a msgid (the key) / msgstr (the value) pair, separated by blank lines per PO grammar. A canonical empty-msgid header is emitted at the top so that every standard gettext tool can parse the result without complaint. The conversion is purely structural — values are passed through verbatim, including Ruby-style %{name} placeholders, which most gettext runtimes can also resolve.
Command
i18n-convert simple.yml --to po -o messages.po
Input
en:
greeting: Hello
farewell: Goodbye
app_name: My Application
welcome_message: Welcome to our app
Output
msgid ""
msgstr ""
msgid "greeting"
msgstr "Hello"
msgid "farewell"
msgstr "Goodbye"
msgid "app_name"
msgstr "My Application"
msgid "welcome_message"
msgstr "Welcome to our app"