C4 wave 3d, all-people-groups: the {t, te, locale} form, English preserved
This site needed more than `t`, so it is the first to take useOptionalI18n: it used
te() to choose between the catalogue and its inline EN map, and i18n.locale to pick
a number format for toLocaleString.
EN stays the fallback, passed in. It is an inline English map rather than the
catalogue, so routing it through tStatic would change what a bare host renders.
gospel-plugin and exp-shepherd each CHOSE the locale-honouring default for their own
bundles; all-people-groups has no owner to ask — studio agreed to treat it as
unowned — so the conservative reading wins and it renders exactly what it rendered.
An unowned file is the wrong place to make a product decision by default.
Two equivalences worth stating rather than assuming:
- the old code asked te() first and only then t(); the helper calls t() and falls
back when it returns the key unchanged. Same outcome either way — present key
gives the translation, absent key gives EN — and it no longer depends on te()
being implemented by the host.
- keys arrive BARE here ('hint', 'pray'), and qualify() prefixes 'allPeopleGroups.'
exactly as the hand-written `const full = 'allPeopleGroups.' + key` did.
locale needs unwrapping: it is a REF when the host installed i18n and a plain string
when it did not. PosterWall.vue records the same variance, which is why the helper
hands it back as-is rather than pretending one shape.
This commit is contained in:
parent
e80c38c045
commit
ef8b86029a
1 changed files with 21 additions and 13 deletions
|
|
@ -30,7 +30,7 @@
|
|||
* answers. A slow or unreachable API costs the black layer, never the map.
|
||||
*/
|
||||
import { inject, ref, computed, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useOptionalI18n } from '@map/composables/useOptionalT.js'
|
||||
import { useMapInstance, engineGlobal } from '@map/composables/useMapInstance.js'
|
||||
import { resolveMapProvider, setProjectionOn } from '@map/composables/useMapProvider.js'
|
||||
import { useMapData } from '@map/composables/useMapData.js'
|
||||
|
|
@ -108,18 +108,26 @@ const EN = { title: 'All People Groups', locations: '{n} group–country locatio
|
|||
frontier: 'Frontier — nothing started', unreached: 'Unreached — work beginning', reached: 'Reached — church is there',
|
||||
hint: 'Click a row to see all of them · click again for everything', loading: 'Loading every people group…',
|
||||
loadError: 'The map could not be loaded.', pray: 'Pray for them →', population: 'pop {n}' }
|
||||
let i18n = null
|
||||
try { i18n = useI18n() } catch (_) { /* no i18n on this host: English below */ }
|
||||
function tr(key, vars) {
|
||||
const full = 'allPeopleGroups.' + key
|
||||
// vue-i18n treats {n} as ITS placeholder: pass the values to t(), or it blanks them out before any
|
||||
// later substitution sees them (the legend read "group–country locations" with no number).
|
||||
if (i18n && i18n.te && i18n.te(full)) return i18n.t(full, vars || {})
|
||||
let v = EN[key]
|
||||
if (vars) for (const k in vars) v = String(v).split('{' + k + '}').join(String(vars[k]))
|
||||
return v
|
||||
}
|
||||
const uiLocale = computed(() => (i18n && i18n.locale && i18n.locale.value) || 'en')
|
||||
// C4 wave 3d: the guard is library/composables/useOptionalI18n now — this site needs more than `t`,
|
||||
// so it takes the {t, te, locale} form rather than useOptionalT.
|
||||
// ★ EN STAYS THE FALLBACK, passed in. It is an inline English map, not the catalogue, so routing this
|
||||
// to tStatic would change what a bare host renders. gospel-plugin and exp-shepherd each CHOSE the
|
||||
// locale-honouring default for their own bundles; all-people-groups has no owner to ask
|
||||
// (studio agreed to treat it as unowned), so the conservative reading wins: preserve what it renders.
|
||||
// The keys arrive BARE here ('hint', 'pray'), and qualify() adds the 'allPeopleGroups.' prefix, which
|
||||
// is exactly what the hand-written `const full = 'allPeopleGroups.' + key` did.
|
||||
// ★ ONE EQUIVALENCE WORTH STATING: the old code asked te() first and only then t(). The helper calls
|
||||
// t() and falls back when it returns the key unchanged. Same outcome both ways — present key: the
|
||||
// translation; absent key: EN — and it no longer depends on te() being implemented.
|
||||
const { t: tr, locale: i18nLocale } = useOptionalI18n('allPeopleGroups', {
|
||||
fallback: (full) => EN[String(full).replace(/^allPeopleGroups\./, '')]
|
||||
})
|
||||
// locale arrives as a REF when the host installed i18n and a plain string when it did not
|
||||
// (PosterWall.vue records the same variance), so unwrap both shapes.
|
||||
const uiLocale = computed(() => {
|
||||
const l = i18nLocale
|
||||
return (l && typeof l === 'object' && 'value' in l ? l.value : l) || 'en'
|
||||
})
|
||||
const fmt = (n) => { try { return Number(n).toLocaleString(uiLocale.value) } catch (_) { return Number(n).toLocaleString() } }
|
||||
|
||||
// ─── The four categories (the Driver's palette) ──────────────────────────────
|
||||
|
|
|
|||
Loading…
Reference in a new issue