sr's census found item-noun="country", item-noun-plural="countries" and unit="UPG" passed as literals. All three reach the DOM: PosterWall renders the noun pair at its section count (n === 1 ? itemNoun : plural) and the unit beside each row's count, so in Arabic the chrome translated and these stayed English. The noun pair now goes through t(). Country and Countries were already in the catalogue in all eleven locales -- Land/Länder, الدولة/الدول, Страна/Страны -- so this adds no strings, and PosterWall keeps making its own singular/plural choice with the caller supplying both forms, which is what its props are for. unit stays "UPG" on purpose. It is DX-life's term of art, and their own Arabic common.json carries the literal "UPG" rather than translating it; matching them is the point of the port. It is the one entry the census still reports here. A fourth literal the census did not flag went with them: the prayer-list "Coming soon" sentence, which reaches exportState.message and so renders too. That one had no key, so it lands as an English-source key -- the convention useRegionsI18n exists to serve -- translated in all eleven locales, 77 keys each, parity green. MEASURED, this plugin's entries in check:hardcoded-english: 3 before, 1 after. |
||
|---|---|---|
| .. | ||
| api | ||
| charts/whiteboard | ||
| colors | ||
| components | ||
| composables | ||
| constants | ||
| dashboards | ||
| data | ||
| elements | ||
| i18n | ||
| layouts | ||
| lists | ||
| maps | ||
| packet | ||
| packets | ||
| scripts | ||
| stores | ||
| styles | ||
| utils | ||
| vendor/cldr | ||
| index.js | ||
| ProfileLoader.vue | ||
| README.md | ||
library/ (@map) — the shared map template
The other half of the architecture (see ../plugin-designs/README.md):
every map in plugin-designs/<your-map>/ composes the reusable, parameterized pieces that live here.
Fix something here and every map benefits on the next build; break something here and every map
breaks — read components/WARNING.md before touching shared pieces.
| Folder | What lives there |
|---|---|
ProfileLoader.vue |
The root of every bundle: parses profile-config, loads the profile, provides the stores + config |
components/ |
Shared UI — map, legends, controls, popup (PeopleGroupDetail), tables, charts, hints (README) |
composables/ |
Shared logic — map engine (useMapInstance), provider switch, shadow-DOM styles, theming |
stores/ |
Per-instance Pinia stores (ui / map / data) — provided by ProfileLoader, injected by children |
api/ |
Data-source registry (sources.json) + fetch layer — the JAMstack runtime wiring |
colors/ |
Color sets maps opt into via profile-config.colorSet |
i18n/ |
The shared string catalogs (all maps speak the same languages) |
data/ |
Small shared datasets baked at build time (big served data lives in ../data/) |
constants/ |
Shared constants |
scripts/ |
Maintainer pipelines (posters, research) — not part of any bundle |
The rule of thumb (same as WARNING.md): custom code in your app-profile, reusable code here — and things only move from the first to the second once they've earned it.