Internationalization (i18n)¶
CMDx talks to users through messages: coercion errors, validation errors, missing outputs, missing required inputs, and the default fault reason. All of that goes through CMDx::I18nProxy.
If the i18n gem is loaded, CMDx uses I18n.translate, so messages follow whatever I18n.locale is set to—just like the rest of your app.
If i18n isn’t there, CMDx loads YAML for config.default_locale and does simple %{key} interpolation itself.
Out of the box, CMDx ships English only (en). Want dozens more languages? Add cmdx-i18n, or drop in your own YAML (see Custom locale paths).
Usage¶
Flip the locale and built-in messages follow:
class ProcessQuote < CMDx::Task
required :price, coerce: :float
def work
# ...
end
end
I18n.with_locale(:fr) do
result = ProcessQuote.execute(price: "invalid")
result.failed? #=> true
result.errors[:price] #=> ["impossible de contraindre en float"]
result.reason #=> "price impossible de contraindre en float"
end
Note
Failures pile up on task.errors (CMDx::Errors). result.reason is basically the friendly string built from those errors (Errors#full_messages, joined with ". ").
Translation Keys¶
Everything lives under cmdx.*. Override a key in your locale file to change wording app-wide:
| Key | Used by |
|---|---|
cmdx.attributes.required |
Missing required input |
cmdx.coercions.into_a / into_an |
Single-type coercion failure (%{type}) |
cmdx.coercions.into_any |
Multi-type coercion failure (%{types}) |
cmdx.outputs.missing |
Declared output not set on context |
cmdx.reasons.unspecified |
Fallback fault reason |
cmdx.types.<name> |
Human-readable coercion type names (array, big_decimal, boolean, complex, date, date_time, float, hash, integer, rational, string, symbol, time) |
cmdx.validators.absence / presence / format |
Standalone validator messages |
cmdx.validators.inclusion.{of,within} |
Inclusion validator messages |
cmdx.validators.exclusion.{of,within} |
Exclusion validator messages |
cmdx.validators.length.{is,is_not,min,max,gt,lt,within,not_within,nil_value} |
Length validator messages |
cmdx.validators.numeric.{is,is_not,min,max,gt,lt,within,not_within,nil_value} |
Numeric validator messages |
Tip
Tweaking one field? Use :message or :<rule>_message on the input (see Validations). Overriding cmdx.* changes the text everywhere that key is used.
Configuration¶
Rails¶
The CMDx railtie adds its locale files to I18n.load_path on boot—but only for locales you list in config.i18n.available_locales. So you don’t load YAML for languages you never ship.
Default locale (plain Ruby)¶
No i18n gem? (Scripts, CLIs, tiny workers.) Set default_locale and CMDx reads that locale’s YAML directly.
In this mode there’s one active locale—no I18n.with_locale equivalent. If a key is missing, you’ll see "Translation missing: <key>". If the locale itself can’t be resolved to a YAML file on the load path, CMDx raises CMDx::UnknownLocaleError (a CMDx::Error) the first time it tries to translate. More detail: Configuration – default locale.
Custom locale paths¶
Point CMDx at extra folders of <locale>.yml files with I18nProxy.register. Later registrations win on merge, so you can override a few keys without copying entire files.
# lib/locales/en.yml
en:
cmdx:
attributes:
required: "is mandatory"
CMDx::I18nProxy.register(File.expand_path("lib/locales", __dir__))
Note
register only affects the no-i18n-gem path. When i18n is loaded, CMDx delegates to I18n.translate—add your paths to I18n.load_path instead.
cmdx-i18n¶
The cmdx-i18n gem ships 86 locales for built-in coercion, validator, and fault messages. In Rails, its Railtie loads bundled YAML for locales you already list in config.i18n.available_locales — no extra wiring. Outside Rails, require "cmdx/i18n" registers the files with CMDx::I18nProxy so CMDx can translate even when the i18n gem is not loaded.
Flip locale and the same task surfaces localized errors (the French example under Usage works out of the box once the gem is installed):
I18n.with_locale(:ja) do
result = ProcessQuote.execute(price: "not-a-number")
# => Japanese coercion message on result.errors[:price]
end
Need to customize one language? Copy a locale into your app and edit keys under cmdx.*:
Full locale list and setup notes: cmdx-i18n on GitHub.