Skip to content

New title canonicalization for h1 is breaking custom rendering (using custom template and no boostrap) #11596

@cderv

Description

@cderv

New title canonicalization from

is a bit to eager for custom rendering lik pkgdown is doing. This has been found while investigating

This example recreates what pkgdown is doing

  • Take this custom template template.html

    <!DOCTYPE html>
    <html lang="$lang$">
    <body>
    
    <div class="meta">
    $if(title)$
      <h1>$title$</h1>
    $endif$
    </div>
    
    <main>
    $body$
    </main>
    
    </body>
    </html>

    It does not use any of quarto partial and fully custom. pkgdown use something like this by taking the $title$ to put it in a specific div it can retrieve from

  • Now use it a simple .qmd document like this

    ---
    title: TESTING
    format: 
      html:
        template: template.html
        minimal: true
        theme: none
    ---
    
    # Heading

The output will be the following after quarto render

<!DOCTYPE html>
<html lang="en"><head></head><body>

<div class="meta">
  
</div>

<main><header id="title-block-header" class="quarto-title-block"><h1 class="title">TESTING</h1></header>
<h1 id="heading">Heading</h1>
</main>



</body></html>

Previous with Quarto 1.5

<!DOCTYPE html>
<html lang="en"><head></head><body>

<div class="meta">
  <h1>TESTING</h1>
</div>

<main>
<h1 id="heading">Heading</h1>
</main>



</body></html>

New addition from #11224 is applying here because all the checks are triggered

// https://github.com/quarto-dev/quarto-cli/issues/10567
// this fix cannot happen in `processDocumentTitle` because
// that's too late in the postprocessing order
const titleBlock = doc.querySelector("header.quarto-title-block");
const main = doc.querySelector("main");
// if no main element exists, this is likely a revealjs presentation
// which will generally have a title slide instead of a title block
// so we don't need to do anything
if (!titleBlock && main) {
const header = doc.createElement("header");
header.id = "title-block-header";
header.classList.add("quarto-title-block");
main.insertBefore(header, main.firstChild);
const h1s = Array.from(doc.querySelectorAll("h1"));
for (const h1n of h1s) {
const h1 = h1n as Element;
if (h1.classList.contains("quarto-secondary-nav-title")) {
continue;
}
// Now we need to check whether this is a plausible title element.
if (h1.parentElement?.tagName === "SECTION") {
// If the parent element is a section, then we need to check if there's
// any content before the section. If there is, then this is not a title
if (
h1.parentElement?.parentElement?.firstElementChild !==
h1.parentElement
) {
continue;
}
} else {
// If the parent element is not a section, then we need to check if there's
// any content before the h1. If there is, then this is not a title
if (h1.parentElement?.firstElementChild !== h1) {
continue;
}
}
const div = doc.createElement("div");
div.classList.add("quarto-title-banner");
h1.classList.add("title");
header.appendChild(h1);
break;
}
}

#11224 was supposed to solve #10567 which seemed to be quite specific to breadcrumbs. So maybe the post processing applies to eagerly here.

  • Should it apply on Project type website rendering only ?
  • Should it apply only when no custom template as been passed ?

I see that this processing checks that .quarto-title-block exists and add it otherwise. I believe class is not always added in HTML document.
It is from this specific partial (and others) added only for bootstrap output

I mean when minimal: true or theme: pandoc or theme: none, I don't think there will be this class however the processing will add it.

There are many variation of title block also and this check

const titleBlock = doc.querySelector("header.quarto-title-block");

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinghtmlIssues with HTML and related web technology (html/css/scss/js)needs-discussionIssues that require a team-wide discussion before proceeding furtherregressionFunctionality that used to work but now is broken.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions