Description
apply_title_template() in post-render.py appends | {site_name} to titles that already
end in the site name, so every page ships a doubled title. This affects the Great Docs
documentation site itself.
Evidence
I reproduced the same behaviour on my own site (great-docs 0.17.0, Quarto 1.9.38).
Cause
great_docs/assets/post-render.py, apply_title_template(), line 430:
# Skip if already has a pipe (already templated)
if " | " in current_title or " - " in current_title:
if current_title.endswith(site_name):
return html_content
# Build new title from template
new_title = template.replace("{page_title}", current_title).replace("{site_name}", site_name)
The guard has two issues:
- The dash doesn't match on subpages. Quarto joins page and site titles with an en-dash "–" (U+2013), but the guard only tests for hyphen-minus "-" (U+002D).
- There's no separator on home pages. The generated
index.qmd carries title: "", so Quarto falls back to the site title ("Great Docs"). That contains neither "|" nor a dash, so the outer if is skipped and the site name is appended to itself.
Reproducible example
Driving the shipped function directly:
import importlib.util, pathlib
import great_docs
path = pathlib.Path(great_docs.__file__).parent / "assets" / "post-render.py"
spec = importlib.util.spec_from_file_location("post_render", path)
m = importlib.util.module_from_spec(spec)
# needs empty _site/ dir in cwd; runs the full post-render pipeline
pathlib.Path("_site").mkdir(exist_ok=True)
spec.loader.exec_module(m)
def run(title, site="Great Docs"):
m._gd_options = {"seo_enabled": True, "site_name": site,
"title_template": "{page_title} | {site_name}"}
html = m.apply_title_template(f"<title>{title}</title>", "index.html")
return html.removeprefix("<title>").removesuffix("</title>")
for title in ("Great Docs", "Intro – Great Docs", "Intro - Great Docs"):
print(f"{title!r:24} -> {run(title)!r}")
'Great Docs' -> 'Great Docs | Great Docs' # bug 2
'Intro – Great Docs' -> 'Intro – Great Docs | Great Docs' # bug 1
'Intro - Great Docs' -> 'Intro - Great Docs' # working
Suggested fix
Return early whenever the title already ends in the site name preceded by one of the two possible separators: Quarto's own en dash or a pipe from a previous pass of this same template.
current_title = title_match.group(1).strip()
if (
current_title == site_name
or current_title.endswith(f" | {site_name}")
or current_title.endswith(f" – {site_name}")
):
return html_content
new_title = template.replace("{page_title}", current_title).replace("{site_name}", site_name)
A plain current_title.endswith(f" {site_name}") is too loose: it would also
match a page whose own title ends in the site name with no separator
ever inserted (e.g. a page titled "Welcome to Great Docs" with title-prefix disabled).
Workaround
Suppressing the append via config, for anyone hitting this before a fix lands:
seo:
title_template: "{page_title}"
Development environment
- great-docs 0.17.0
- Quarto 1.9.38
- Python 3.13, Linux
Description
apply_title_template()inpost-render.pyappends| {site_name}to titles that alreadyend in the site name, so every page ships a doubled title. This affects the Great Docs
documentation site itself.
Evidence
<title>I reproduced the same behaviour on my own site (great-docs 0.17.0, Quarto 1.9.38).
Cause
great_docs/assets/post-render.py,apply_title_template(), line 430:The guard has two issues:
index.qmdcarriestitle: "", so Quarto falls back to the site title ("Great Docs"). That contains neither "|" nor a dash, so the outerifis skipped and the site name is appended to itself.Reproducible example
Driving the shipped function directly:
Suggested fix
Return early whenever the title already ends in the site name preceded by one of the two possible separators: Quarto's own en dash or a pipe from a previous pass of this same template.
A plain
current_title.endswith(f" {site_name}")is too loose: it would alsomatch a page whose own title ends in the site name with no separator
ever inserted (e.g. a page titled "Welcome to Great Docs" with
title-prefixdisabled).Workaround
Suppressing the append via config, for anyone hitting this before a fix lands:
Development environment