From WINGS Authoring
Adds translatable text, plurals/gender inflection, locale-aware formatting (number, currency, date), and runtime language switching to WINGS apps via the wi18n package and gen_i18n build step.
How this skill is triggered — by the user, by Claude, or both
Slash command
/wings-authoring:wings-i18nThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The model: **author natural text** in templates. A build step (`gen_i18n`)
The model: author natural text in templates. A build step (gen_i18n)
rewrites templates, replacing each translatable string with a stable numeric
index and emitting a per-language JSON catalog. At runtime the wi18n package
loads the catalog and swaps each index back to the translated string. You never
write index numbers by hand.
_ "github.com/luisfurquim/wings/wi18n" in main.go.
It auto-detects the browser language, loads i18n/<lang>.json, and makes
wings.Main() wait for the catalog before rendering.go run github.com/luisfurquim/wings/cmd/build@latest dev with i18n options,
or the repo's gen_i18n); it produces *.i18n.html + i18n/<deflang>.json.i18n/<lang>.json (one per language) in your web root.<h2>Dashboard</h2> → extracted.title, placeholder, alt, aria-label,
data-i18n (wings.TranslatableAttrs). Other attribute text is left alone.{{expression}} output passes through untranslated — so
translate the template literals, not the data. If you need a data value
localized, format it (see formatting below) or translate it in your data.Opt a subtree out with the standard HTML translate="no" (inherited by
children) — useful for code samples, proper nouns, or literal index demos.
For CSS-generated text use data-i18n="..." + content: attr(data-i18n) so it
flows through the same pipeline (don't hardcode user-visible text in CSS).
A single translated string can't express a target language's plural/gender
agreement. Use inline flex sigils inside a {{...}} block (see the syntax
table in wings-component):
@var — gender axis (the value selects a gender row).%var — count axis (emitted at its position; drives the CLDR plural category).~word — a stem the translator will inflect.#N — a rule index auto-assigned by gen_i18n; never write it yourself.<p>{{@gender %qt ~aluno ~aprovado}}</p>
gen_i18n rewrites this to a #N rule and emits an i18n/<lang>.inflections.json
(gender × CLDR-category cells) for translators. For programmable inflection
engines see README "Programmable Flex (CustomFlex)".
A lone {{%var}} (no ~/@) formats a value for the locale — type-directed:
ints/floats, time.Time, wi18n.Currency, or any type implementing
wi18n.Numerical. Named formats: {{%var:formatName}} keyed by <lang>.fmt.json.
<span>{{%price}}</span> <!-- formatted "R$ 1.234,50" / "$1,234.50" by locale -->
wi18n.Currency is money as an integer in the currency's minor unit (avoids
float rounding), not a float:
type Currency struct {
Amount int64 // minor units: centavos/cents (123450 == 1234.50)
Code string // ISO 4217, e.g. "BRL", "USD", "JPY"
}
// e.g. "price": wi18n.Currency{Amount: 123450, Code: "BRL"}
Physical units (length, temperature, speed, …) have their own measure packages; see README "Physical Measure Packages".
Switch language live with wi18n.SetLang:
wi18n.SetLang("es-AR", func(err error) {
if err != nil { /* handle: revert UI, show dialog */ }
})
go wi18n.SetLang(...)) — calling it
synchronously from an event handler that the runtime is also driving can
deadlock.wi18n.SetCatalogPublicKey, ed25519), a tampered/unsigned catalog yields a
typed *wi18n.CatalogSignatureError (errors.As) — the bundle is refused
(fail-closed). A language-switcher component should branch on it: revert the
<select> to the current locale and surface the error (e.g. open a w-dialog).wi18n.Lang() returns the active tag.content in a catalog renders the raw index — a deliberate
missing-translation signal.helpers/wlate GUI.npx claudepluginhub luisfurquim/wings --plugin wings-authoringGuides writing translatable source strings: avoid concatenation traps, use ICU MessageFormat for plurals, externalize all UI text.
Guides iOS localization with Xcode String Catalogs for translations, pluralization, RTL layouts, and SwiftUI LocalizedStringKey patterns.