Skip to content

Commit b6fa408

Browse files
hrq-chiuchiHenrique Chiuchi
andauthored
fix(templates): stop leaking the template's title into published pages (CoreBunch#217)
composeTemplateChain always returned the innermost TEMPLATE's title as the merged page's title, never the actual page or entry being rendered. Every published page's <title> and <head> metadata came from whichever template wrapped it: ordinary pages all showed the "everywhere" template's title, and post-type entries showed the postType template's title instead of the entry's own title. For a page terminal, terminal.page is already available inside composeTemplateChain, so use its title directly. For an entry terminal there is no Page object at that layer, so the two callers (renderPublishedDataRowTemplate and the row preview handler) set merged.title from the published/draft row's own title cell right after composing, before the page is rendered. Co-authored-by: Henrique Chiuchi <henriquechiuchi@outlook.com>
1 parent 76f15fa commit b6fa408

3 files changed

Lines changed: 11 additions & 1 deletion

File tree

server/handlers/cms/data/preview.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ export async function handleRowPreview(
9494
return jsonResponse({ error: 'No entry template found for this collection' }, { status: 404 })
9595
}
9696
const merged = composeTemplateChain(chain, { kind: 'entry' })
97+
// The template chain has no Page for the entry, so composeTemplateChain
98+
// can't know its title — the entry's own (draft) title is the real document title.
99+
if (typeof draftCells.title === 'string') merged.title = draftCells.title
97100

98101
// Build a synthetic PublishedDataRow with the draft cells merged in.
99102
// Bindings inside the template (`{currentEntry.body}`, featured-media

server/publish/publicRenderer.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ export async function renderPublishedDataRowTemplate(
176176
const chain = resolveTemplateChain(snapshot.site, { kind: 'entry', tableSlug: row.tableSlug })
177177
if (chain.length === 0) return null // no entry template → 404 (unchanged behaviour)
178178
const merged = composeTemplateChain(chain, { kind: 'entry' })
179+
// The template chain has no Page for the entry, so composeTemplateChain
180+
// can't know its title — the entry's own title is the real document title.
181+
if (typeof row.cells.title === 'string') merged.title = row.cells.title
179182

180183
// Seed the entry stack with the published row + route frame from the request
181184
// URL. Loop interceptors push/pop iteration items on top of this stack;

src/core/templates/templateCompose.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,11 @@ export function composeTemplateChain(chain: Page[], terminal: TerminalContent):
140140
return {
141141
id: innermost.id, // identifies "what was rendered" for the publish.html filter
142142
slug: innermost.slug,
143-
title: innermost.title,
143+
// The terminal page's own title is the document's real title — the
144+
// wrapping template's title is chrome, never `<title>` content. Entry
145+
// terminals have no Page here; their caller overrides `title` from the
146+
// published row after composing.
147+
title: terminal.kind === 'page' ? terminal.page.title : innermost.title,
144148
rootNodeId: acc.rootId,
145149
nodes: acc.nodes,
146150
}

0 commit comments

Comments
 (0)