agentsclimarketplace

Writing i18n

Skill chrisrackstallion/pitchd-rails-cursor-plugin/skills/writing-i18n

Organize Rails I18n — YAML structure, lazy lookup in views, absolute keys in helpers and controllers, interpolation and pluralization, datetime/number formats, and Active Record error messages. DHH/37signals style: boring keys, framework-first, no string concatenation in templates. Use when adding or changing locales, extracting user-facing copy from ERB, flash messages, or validation messages; not for translation vendor tooling or SPA i18n-js. Triggers: locales, config/locales YAML, t(), I18n.t, missing translations, flash copy, human_attribute_name.From its SKILL.md

Install
npx -y skills add chrisrackstallion/pitchd-rails-cursor-plugin --skill writing-i18n

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.6 KB, as published. Nobody here has run it

Writing I18n

<objective> Treat locale files as part of the application: namespaced keys, static copy in YAML, dynamic values via interpolation. Locale files always mirror the application's structure so key resolution (lazy lookup, `default_i18n_subject`, `human_attribute_name`) works by convention. Views use lazy lookup where it reads naturally; helpers and shared partials use explicit keys. All user-facing error messages live in I18n and read as human language — rename schema-shaped attributes (join-table foreign keys) to their real-world names. All user-visible dates and times are formatted via I18n (`l()` with declared formats). Rails handles pluralization and time formats — do not hand-roll them in templates. Keep I18n boring and omakase — no parallel translation architecture. </objective>

Process

1. Determine What You're Building

TaskAction
New feature copyRead references/patterns.md § Key structure; add keys under a feature namespace
Strings in a viewPrefer t(".key") lazy lookup; read § Lazy vs absolute
Strings in a helper / shared partialAbsolute key — t("feature.button.save")
Flash / controller messagesAbsolute keys; keep messages out of fat controllers where possible
Validation / attribute labelsactiverecord tree — § Active Record
Mailer subject / body phrasesmailers.* + § Mailers in patterns; mailer skill § subjects
Pluralization / dates / numbers§ Pluralization and datetime; use l(), number_to_*

2. Add or Update YAML

Place files under config/locales/ — e.g. en.yml, articles.en.yml. Keep default locale complete for keys you introduce; add secondary locales when the app actually ships them.

3. Replace String Soup

Swap "Save", "Cancel", concatenated greetings, etc., for t() calls and keys. Use %{name} — never string math for grammar.

4. Verify

In development, config.i18n.raise_on_missing_translations = true (if enabled) catches missing keys. Run the screen or mailer preview that uses the new copy.

Verification

  • User-facing static strings in views/helpers/controllers use t() / I18n.t, not raw literals (domain data excepted)
  • Lazy keys match the template path; shared partials use absolute keys
  • Interpolation uses YAML placeholders, not Ruby concatenation
  • Pluralization uses count: and proper one / other (and locale-specific keys when required)
  • No unbounded dynamic key paths from user input
  • activerecord attributes/errors follow Rails structure for forms
  • Locale file nesting mirrors the app structure (view paths, mailer paths) so keys resolve by convention
  • All user-facing error messages come from I18n and read as human language — join-table / FK attributes renamed to real-world names via activerecord.attributes
  • All user-visible dates and times go through l() with formats declared in locale YAML — no strftime in views or helpers

References

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.