Merge pull request 'Stop overriding page title and #site-title with siteName (AI)' (#4) from claude into main

Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
biosias committed 2026-10-27 15:43:31 +01:00
commit 2f1bb8acfe
6 files changed
+14 -23

No files matched your search

+5 -11
View File
@@ -271,12 +271,11 @@ The resolved locale also drives date formatting (`Intl.DateTimeFormat`), search
tag-label sorting (`localeCompare`), via `getLocale()` in the same module — so a translation tag-label sorting (`localeCompare`), via `getLocale()` in the same module — so a translation
file doesn't just relabel text, it affects how dates and sorting behave too. file doesn't just relabel text, it affects how dates and sorting behave too.
The page `<title>` and an optional `#site-title` header link (see "Embedding in an existing cmkiss never names the page: the `<title>`, the site header, and any other branding (the header
page" below) are both set from the `siteName` string at startup, so they stay in sync with the search placeholder, the sidebar section headings) belong to the embedding page and are plain
resolved locale automatically — translate `siteName` in `strings/xx.json` rather than editing static HTML — translate them by editing the page directly (`demo/index.html` for this repo's own
the page. Other site-specific branding in the embedding page itself (the header search demo). The only change cmkiss makes to the tab title is in the article view, where it shows
placeholder, the sidebar section headings) is plain static HTML, not JS-templated — translate `<article title> | <page's own title>`; list views restore the page's original `<title>` exactly.
that by editing the page directly (`demo/index.html` for this repo's own demo).
## Embedding in an existing page ## Embedding in an existing page
@@ -353,11 +352,6 @@ demo does.
```html ```html
<nav id="tag-filters" aria-label="Filter by tag"></nav> <nav id="tag-filters" aria-label="Filter by tag"></nav>
``` ```
- **Site title link — `#site-title`.** Optional; its text is set to the `siteName` string once at
startup, so it stays in sync with the resolved locale without editing the page per language.
```html
<a href="#" id="site-title">My Site</a>
```
`#tag-filters` is optional — omit it and nothing breaks, the article list and search still work `#tag-filters` is optional — omit it and nothing breaks, the article list and search still work
standalone. standalone.
-7
View File
@@ -78,13 +78,6 @@ function init() {
if (!document.getElementById('list-view') || !document.getElementById('article-view')) { if (!document.getElementById('list-view') || !document.getElementById('article-view')) {
throw new Error('Missing required #list-view and/or #article-view element — see the "Embedding in an existing page" section of the README.'); throw new Error('Missing required #list-view and/or #article-view element — see the "Embedding in an existing page" section of the README.');
} }
// Optional embedding-page markup (see "Embedding in an existing
// page" in the README) — set once here rather than in
// showListView()/loadArticle() so a page that loads straight into
// an article route (a direct link) still gets it, not just one that
// starts on the list view.
const siteTitle = document.getElementById('site-title');
if (siteTitle) siteTitle.textContent = t('siteName');
}); });
// Show a top-level error if dependencies fail to load (or a mount point // Show a top-level error if dependencies fail to load (or a mount point
+9 -2
View File
@@ -18,6 +18,12 @@ let currentGeneration = 0;
// everything. // everything.
let lastListHash = '#'; let lastListHash = '#';
// The embedding page's own <title>, captured once when this module first
// runs (module scripts are deferred, so <title> is already parsed). cmkiss
// never names the page itself — list views restore this exactly, and the
// article view only prefixes it with the article's title.
const pageTitle = document.title;
function formatDate(value) { function formatDate(value) {
if (!value) return ''; if (!value) return '';
const date = new Date(`${String(value).slice(0, 10)}T12:00:00`); const date = new Date(`${String(value).slice(0, 10)}T12:00:00`);
@@ -27,7 +33,7 @@ function formatDate(value) {
export function showListView() { export function showListView() {
document.getElementById('list-view').hidden = false; document.getElementById('list-view').hidden = false;
document.getElementById('article-view').hidden = true; document.getElementById('article-view').hidden = true;
document.title = t('siteName'); document.title = pageTitle;
} }
export function showArticleView() { export function showArticleView() {
@@ -552,7 +558,8 @@ export async function loadArticle(hash) {
// cards, the description field here stays frontmatter-only (no // cards, the description field here stays frontmatter-only (no
// auto-excerpt) — the full content is right below it either way. // auto-excerpt) — the full content is right below it either way.
const { readingTime, coverUrl } = deriveContentFields(meta, content, article.path); const { readingTime, coverUrl } = deriveContentFields(meta, content, article.path);
document.title = `${meta.title || article.slug} | ${t('siteName')}`; // Skip the separator when the embedding page has no <title> of its own.
document.title = `${meta.title || article.slug}${pageTitle ? ` | ${pageTitle}` : ''}`;
const element = document.importNode(templates.article, true); const element = document.importNode(templates.article, true);
const field = name => element.querySelector(`[data-field="${name}"]`); const field = name => element.querySelector(`[data-field="${name}"]`);
field('title').textContent = meta.title || article.slug; field('title').textContent = meta.title || article.slug;
-1
View File
@@ -1,5 +1,4 @@
{ {
"siteName": "Ukázkový blog",
"appStartError": "Blog se nepodařilo spustit: {message}", "appStartError": "Blog se nepodařilo spustit: {message}",
"articleNotFound": "Článek nebyl nalezen", "articleNotFound": "Článek nebyl nalezen",
-1
View File
@@ -1,5 +1,4 @@
{ {
"siteName": "Example Blog",
"appStartError": "Failed to start the blog: {message}", "appStartError": "Failed to start the blog: {message}",
"articleNotFound": "Article not found", "articleNotFound": "Article not found",
-1
View File
@@ -1,5 +1,4 @@
{ {
"siteName": "Ukážkový blog",
"appStartError": "Blog sa nepodarilo spustiť: {message}", "appStartError": "Blog sa nepodarilo spustiť: {message}",
"articleNotFound": "Článok nebol nájdený", "articleNotFound": "Článok nebol nájdený",