diff --git a/library/components/poster/PosterWall.vue b/library/components/poster/PosterWall.vue index 35b909827..7161fabc4 100644 --- a/library/components/poster/PosterWall.vue +++ b/library/components/poster/PosterWall.vue @@ -47,7 +47,7 @@ import { tStatic } from '../../i18n/index.js' const T = (key, en) => tStatic(key) || en import { useShadowStyles } from '@map/composables/useShadowStyles.js' import { usePosterPrints } from '@map/composables/usePosterPrints.js' -import { useOptionalI18n } from '@map/composables/useOptionalT.js' +import { useOptionalI18n, useOptionalT } from '@map/composables/useOptionalT.js' // Export-modal geometry. A fixed;inset:0 scrim covers only the CONTENT PANE in the cap-5 shell // (contain:layout on .vtl-content). Measured 1024x793 @ (256,107) at 1280x900 — rail clickable // behind the "modal". See library/utils/viewportScrim.js for the measurements and rejected fixes. @@ -70,8 +70,12 @@ const props = defineProps({ itemNoun: { type: String, default: 'list' }, // English plurals are not "+s". A naive pluralizer shipped "28 countrys" to the // section headers, so the plural is a PARAMETER — the caller knows its own noun. - // Defaults to itemNoun + 's', which is right for "list"/"poster". + // ⚠ No "+s" default any more: a noun pair is English-only by construction. itemNounPlural: { type: String, default: '' }, + // ★ THE LOCALIZED WAY TO COUNT ITEMS: a catalogue PLURAL key ("{n} country | {n} countries" in en, + // four forms in ru, six in ar, one in zh), rendered with the count so each locale picks its own CLDR + // form. Wins over itemNoun/itemNounPlural, which remain for callers that have not moved yet. + itemCountKey: { type: String, default: '' }, collapsible: { type: Boolean, default: false }, collapsedBy: { type: Function, default: () => false }, // A card may declare itself unsupported (India: 855 groups do not fit a sheet). @@ -246,7 +250,13 @@ const gridStyle = computed(() => { return { gridTemplateColumns: `repeat(${Math.min(perRow.value, fits)}, minmax(0, 1fr))` } }) -const plural = computed(() => props.itemNounPlural || `${props.itemNoun}s`) +const plural = computed(() => props.itemNounPlural || props.itemNoun) +// Counts are PLURAL catalogue keys, rendered with the number so each locale takes its own CLDR form. +// `t` here is useOptionalI18n's, whose bare-host fallback is humanizeKey — right for button labels, +// wrong for a count — so counts use a catalogue translator of their own (tStatic when no i18n). +const tCount = useOptionalT('') +const countOf = (key, n) => tCount(key, { n: Number(n || 0).toLocaleString() }, Number(n || 0)) +const itemCount = (n) => (props.itemCountKey ? countOf(props.itemCountKey, n) : `${n} ${n === 1 ? props.itemNoun : plural.value}`) const base = computed(() => String(props.assetsBase || './assets').replace(/\/+$/, '')) // ★ A SECOND PLACE TO LOOK, because "poster not generated yet" was being shown for posters that @@ -1087,8 +1097,7 @@ useShadowStyles( ▶

{{ sec.name }}

- {{ sec.total.toLocaleString() }} {{ T('gospel.list.peopleGroups', 'people groups') }} · - {{ sec.items.length }} {{ sec.items.length === 1 ? itemNoun : plural }} + {{ countOf('wall.peopleGroupCount', sec.total) }} · {{ itemCount(sec.items.length) }} @@ -1132,7 +1141,7 @@ useShadowStyles(
{{ item.label }}
-
{{ item.count.toLocaleString() }} people groups
+
{{ countOf('wall.peopleGroupCount', item.count) }}
{{ unsupported(item) }}