diff --git a/app/index.html b/app/index.html index f9c18f3..af6b645 100644 --- a/app/index.html +++ b/app/index.html @@ -952,7 +952,7 @@ body { // Category state (phase 3) let categoriesUse = false; - let categoriesList = []; // [{code, name, direction, message, notfoundmessage, pagenotfoundmessage, font, ...}] + let categoriesList = []; // [{code, name, direction, message, notfoundmessage, pagenotfoundmessage, visibilityifnocontent, font, ...}] let categoriesByCode = {}; // code → category object let defaultCategoryCode = null; let activeCategory = null; // current code @@ -1210,6 +1210,7 @@ body { // - Home page: always show (per config.homepage or default 'pages/home.md') // - Variant exists for active category: show // - Active category has notfoundmessage: show (renderer falls back to default language) + // - Active category has visibilityifnocontent: visible: show (renderer shows pagenotfoundmessage) // - Otherwise: hide if (!categoriesUse) return true; if (page.file === defaultPage()) return true; @@ -1217,7 +1218,7 @@ body { const variants = page.variants || []; if (variants.includes(activeCategory)) return true; const cat = categoriesByCode[activeCategory]; - return !!(cat && cat.notfoundmessage); + return !!(cat && (cat.notfoundmessage || cat.visibilityifnocontent === 'visible')); } // ─── Theme ──────────────────────────────────────────────── @@ -2252,7 +2253,8 @@ function fmtDatetime(dtStr) { function visibleCategoryCodesForCurrentPage() { // Which categories should appear in the dropdown: // - the variant exists for this page, OR - // - the category has a notfoundmessage + // - the category has a notfoundmessage (fallback to default content), OR + // - the category has visibilityifnocontent: visible (shows pagenotfoundmessage instead) // - always include the active category so user can see what they're on const out = new Set(); const page = currentPage @@ -2260,8 +2262,8 @@ function fmtDatetime(dtStr) { : null; categoriesList.forEach(cat => { const hasVariant = !page || page.uncategorized || !(page.variants && page.variants.length) || page.variants.includes(cat.code); - const hasMsg = !!cat.notfoundmessage; - if (hasVariant || hasMsg || cat.code === activeCategory) out.add(cat.code); + const alwaysVisible = !!cat.notfoundmessage || cat.visibilityifnocontent === 'visible'; + if (hasVariant || alwaysVisible || cat.code === activeCategory) out.add(cat.code); }); return out; } diff --git a/docs/reference-config.md b/docs/reference-config.md index 6c91062..0c0d829 100644 --- a/docs/reference-config.md +++ b/docs/reference-config.md @@ -151,16 +151,46 @@ categories-use: yes # Enable the category system. Default: no. default-category: # The category used when no ?cat= parameter is in the URL. code: en # Short code. Used in filenames (page.en.md) and URL params. - name: English # Display name shown in the category selector. + name: English # Display name shown in the category dropdown list. + message: English # Label shown on the selector bar (trigger button). Falls back to name. + name-latin: English # Secondary label shown in the dropdown alongside name. Use when name + # is in a non-Latin script (e.g. Arabic, Devanagari) to aid recognition. + # Omit if name is already Latin or identical to name. direction: ltr # Text direction. ltr or rtl. Default: ltr. + # rtl flips the nav position and content text direction. + notfoundmessage: "Not available in this language" + # Short note shown in the dropdown when no variant exists for the + # current page. Also enables fallback: the renderer will fall back to + # the default-category content instead of hiding the page. + # Omit to hide the category from the dropdown when no variant exists. + visibilityifnocontent: hidden # hidden (default) or visible. + # hidden: category disappears from the selector when no variant exists + # for the current page (unless notfoundmessage is also set). + # visible: category stays in the selector regardless. When the user + # navigates to a page with no variant, pagenotfoundmessage is shown + # in the content area. No fallback to default-category content. + pagenotfoundmessage: "This page is not yet available in English." + # Message shown in the content area when a page cannot be fetched for + # this category. Overrides the top-level pagenotfoundmessage. + font: NotoNastaliqUrdu-Regular.ttf + # Font filename inside assets/fonts/. Loaded on demand when this + # category is activated. Useful for scripts that need a specific font. + line-height: 2.8 # Line height override for this category. Useful for scripts like + # Nastaliq that need extra vertical space. Restores to theme default + # when switching away. -categories: # Additional categories. +categories: # Additional categories. Each entry supports the same keys as + # default-category above. - code: nb name: Norsk direction: ltr - code: ar name: عربي - direction: rtl # RTL flips nav position and content text direction. + name-latin: Arabic + direction: rtl + notfoundmessage: "غير متاح" + font: NotoNastaliqUrdu-Regular.ttf + line-height: 2.8 categories-sectionnames: same # How section names are shown per category. # same: all categories share one section name (defaultname in nav.yml). @@ -170,6 +200,21 @@ categories-selecticon: globe # Icon shown in the category selector bar. SVG na categories-selecttext: "Language" # Label shown next to the icon in the category selector bar. ``` +### Per-category keys summary + +| Key | Required | Description | +|---|---|---| +| `code` | Yes | Short identifier used in filenames (`page.nb.md`) and the `?cat=` URL param. | +| `name` | Yes | Display name shown in the dropdown list. | +| `message` | No | Label shown on the selector trigger button. Falls back to `name`. | +| `name-latin` | No | Secondary label in the dropdown, shown alongside `name` when `name` uses a non-Latin script. | +| `direction` | No | `ltr` or `rtl`. Default: `ltr`. RTL flips nav and content direction. | +| `notfoundmessage` | No | Short note shown in the dropdown when no variant exists for the current page. Also enables fallback to default-category content. | +| `visibilityifnocontent` | No | `hidden` (default) or `visible`. `visible` keeps the category in the selector when no variant exists; navigating to it shows `pagenotfoundmessage` with no fallback to default content. | +| `pagenotfoundmessage` | No | Message shown in the content area when a page cannot be fetched for this category. Overrides the top-level `pagenotfoundmessage`. | +| `font` | No | Font filename from `assets/fonts/`. Loaded on demand when this category is activated. | +| `line-height` | No | Body line height override for this category. Restores to theme default when switching away. | + --- ## Reusable callout messages @@ -228,6 +273,30 @@ offline-message: nb: "Du er frakoblet. Koble til og last inn på nytt." language: en +pagenotfoundmessage: "Please select a page to continue." + +categories-use: yes +default-category: + code: en + name: English + direction: ltr +categories: + - code: nb + name: Norsk + direction: ltr + visibilityifnocontent: visible + pagenotfoundmessage: "Denne siden er ikke tilgjengelig på norsk ennå." + - code: ar + name: عربي + name-latin: Arabic + direction: rtl + notfoundmessage: "غير متاح" + pagenotfoundmessage: "هذه الصفحة غير متاحة." + font: NotoNastaliqUrdu-Regular.ttf + line-height: 2.8 +categories-sectionnames: same +categories-selecticon: globe +categories-selecttext: "Language" callouts: aitranslation: diff --git a/docs/reference-pages.md b/docs/reference-pages.md index f1e4607..6598ad9 100644 --- a/docs/reference-pages.md +++ b/docs/reference-pages.md @@ -4,7 +4,7 @@ All keys you can use inside a markdown page in `pages/` or `posts/`. A page has two parts: -```markdown +````markdown --- # Frontmatter (YAML, optional except for title) title: My Page @@ -17,7 +17,8 @@ toc ``` Regular markdown, plus mdcms code blocks for callouts, table of contents, post lists. -``` + +```` ---