C4 wave 3c, my-upg-100-list: two humanizeKey guards become one call

poster-wall.vue and upg-100-mfe.vue both had the same two lines — a humanizeKey
fallback, then `try { t = useI18n().t } catch` — and now call
useOptionalT('', { fallback: (k) => humanizeKey(k) }).

No namespace: callers pass FULL keys here, which is what the bare useI18n().t they
used to get required.

humanizeKey stays as the fallback rather than taking the catalogue default, so a
bare host still reads a title-cased last segment. gospel-plugin chose the
locale-honouring default for their bundle; the same one-word choice is upg100's to
make for theirs.

★ ONE BEHAVIOUR GAIN, stated rather than smuggled: the old i18n path was the raw
useI18n().t, so on a host WITH i18n a missing key rendered the dotted key itself.
It now falls through to humanizeKey — the fallback a bare host already got. Nothing
that resolves today changes; a key that is missing reads better.

Register now covers 14 migrated sites.
This commit is contained in:
Doxa Maps 2026-09-26 18:48:41 +00:00
parent ccc9a44995
commit 1bd5f109d8
3 changed files with 21 additions and 6 deletions

View file

@ -144,6 +144,11 @@ const SITES = [
// file is the wrong place to make a product decision by default.
// First site on the {t, te, locale} form: it needs locale for toLocaleString.
['plugin-designs/all-people-groups/all-people-groups.vue', 'useOptionalI18n', 'fallback: (full) =>'],
// wave 3c — my-upg-100-list (owner: upg100). Both used the humanizeKey fallback and no namespace,
// since callers pass full keys. Each keeps humanizeKey, so a bare host reads the same title-cased
// last segment it always did.
['plugin-designs/my-upg-100-list/poster-wall.vue', 'useOptionalT', 'humanizeKey(k)'],
['plugin-designs/my-upg-100-list/upg-100-mfe.vue', 'useOptionalT', 'humanizeKey(k)'],
]
// ★ ONE FILE KEEPS TWO BARE useI18n CALLS ON PURPOSE, and the count is asserted rather than waived.
// resources-map.vue reads the LOCALE twice (`useI18n().locale.value`) to decide isEnglish and the

View file

@ -39,7 +39,7 @@
* IDEA-POSTER-EXPORT-404-ON-DROPPED-FOLDER-TRADEOFF.
*/
import { computed, inject, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useOptionalT } from '@map/composables/useOptionalT.js'
// The page's people-group LIST (library/lists/): every people-group fetch below keeps only its groups.
import { applyPeopleGroupList } from '@map/lists/peopleGroupList.js'
import PosterWall from '@map/components/poster/PosterWall.vue'
@ -163,8 +163,13 @@ async function fetchListRecords(list) {
// Guarded like every other useI18n() here: it throws on a host without vue-i18n.
const humanizeKey = (k) => String(k).split('.').pop()
.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/^./, (c) => c.toUpperCase())
let t = (k) => humanizeKey(k)
try { t = useI18n().t } catch (_) { /* no i18n on this host */ }
// C4 wave 3c: the guard is library/composables/useOptionalT.js now. humanizeKey STAYS as the fallback,
// passed in, so a bare host still reads a title-cased last segment rather than a dotted key. No
// namespace: callers pass FULL keys here, exactly as the raw useI18n().t they used to get.
// ★ ONE BEHAVIOUR GAIN, stated rather than smuggled: the old i18n path was the bare useI18n().t, so on
// a host WITH i18n a missing key rendered the raw dotted key. It now falls through to humanizeKey, the
// same fallback the bare host already got. Nothing that resolves today changes.
const t = useOptionalT('', { fallback: (k) => humanizeKey(k) })
const intro = computed(() => t('messages.upg100WallIntro'))
const heading = computed(() => t('messages.upg100WallHeading'))
const wallTag = computed(() => t('messages.upg100WallTag'))

View file

@ -34,7 +34,7 @@
* whole MFE (both panes) is what gets shared/embedded.
*/
import { ref, computed, inject, onMounted, onBeforeUnmount } from 'vue'
import { useI18n } from 'vue-i18n'
import { useOptionalT } from '@map/composables/useOptionalT.js'
import { buildPaneColumn, PANE_GRID_STYLES } from '@map/layouts/pane-wrapper/pane-wrapper.js'
import { useShadowStyles } from '@map/composables/useShadowStyles.js'
import ViewSelect from '@map/components/ViewSelect.vue'
@ -50,8 +50,13 @@ import ShareButton from '@map/components/map-controls/ShareButton.vue'
// humanises the key so a bare host shows "Select View", never a blank or a raw dotted key.
const humanizeKey = (k) => String(k).split('.').pop()
.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/^./, (c) => c.toUpperCase())
let t = (k) => humanizeKey(k)
try { t = useI18n().t } catch (_) { /* no i18n on this host */ }
// C4 wave 3c: the guard is library/composables/useOptionalT.js now. humanizeKey STAYS as the fallback,
// passed in, so a bare host still reads a title-cased last segment rather than a dotted key. No
// namespace: callers pass FULL keys here, exactly as the raw useI18n().t they used to get.
// ★ ONE BEHAVIOUR GAIN, stated rather than smuggled: the old i18n path was the bare useI18n().t, so on
// a host WITH i18n a missing key rendered the raw dotted key. It now falls through to humanizeKey, the
// same fallback the bare host already got. Nothing that resolves today changes.
const t = useOptionalT('', { fallback: (k) => humanizeKey(k) })
const cfg = inject('profileConfig', ref(null))
const tk = inject('mapboxToken', ref(''))