From 1bd5f109d8ca94a9bfdcb19bce671882500a2b38 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 26 Sep 2026 18:48:41 +0000 Subject: [PATCH] C4 wave 3c, my-upg-100-list: two humanizeKey guards become one call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- internal/check-optional-t-equivalence.mjs | 5 +++++ plugin-designs/my-upg-100-list/poster-wall.vue | 11 ++++++++--- plugin-designs/my-upg-100-list/upg-100-mfe.vue | 11 ++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/internal/check-optional-t-equivalence.mjs b/internal/check-optional-t-equivalence.mjs index bcb133775..2e59007b0 100644 --- a/internal/check-optional-t-equivalence.mjs +++ b/internal/check-optional-t-equivalence.mjs @@ -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 diff --git a/plugin-designs/my-upg-100-list/poster-wall.vue b/plugin-designs/my-upg-100-list/poster-wall.vue index ee164d4d7..dd3a90885 100644 --- a/plugin-designs/my-upg-100-list/poster-wall.vue +++ b/plugin-designs/my-upg-100-list/poster-wall.vue @@ -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')) diff --git a/plugin-designs/my-upg-100-list/upg-100-mfe.vue b/plugin-designs/my-upg-100-list/upg-100-mfe.vue index f9501aa2f..8a4cd97da 100644 --- a/plugin-designs/my-upg-100-list/upg-100-mfe.vue +++ b/plugin-designs/my-upg-100-list/upg-100-mfe.vue @@ -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(''))