Skip to content

Fix empty metadata and subtitle links in default listings - #15130

Merged
cderv merged 4 commits into
mainfrom
fix/listing-empty-metadata-link
Oct 20, 2026
Merged

cderv merged 4 commits into
mainfrom
fix/listing-empty-metadata-link

Conversation

@cderv

@cderv cderv commented Oct 20, 2026

Copy link
Copy Markdown
Member

Found while reviewing #15099 (empty thumbnail link, #15066): the default listing template has two more anchors that can end up empty, a Tab stop with no accessible name flagged by axe-core link-name.

Both have been there since the default listing template was introduced, so this is not a regression and there is no backport.

Fix

The template now checks whether a value renders as visible text (hasText()). Falsy values render as   through outputLink(), and empty lists and blank strings stringify to whitespace, so none of them count. The metadata link is written only when one of its fields has text, and the subtitle line only when the subtitle has text.

The .metadata div itself is kept on every post. It is a flex column in the row layout, so dropping it on some posts would widen .body on those posts only and make widths differ within one listing. The subtitle line has no such role and is dropped entirely.

A custom field whose value is HTML rendering nothing (e.g. " ") still gives an unnamed link. Catching it would need HTML parsing in the EJS template for author-provided content, which was deemed out of scope.

The new smoke test covers the default fields, fields without any metadata, reading time only, and a custom field that is present, missing, empty, blank or an empty list. axe-core in Chromium on the same listing pages reports no link-name violation.

Fixes #15129, fixes #14380

Checklist

I have (if applicable):

  • referenced the GitHub issue this PR closes
  • updated the appropriate changelog in the PR
  • ensured the present test suite passes (ran the listing smoke tests in tests/smoke/site/, not the full suite)
  • added new tests
  • created a separate documentation PR in Quarto's website repo and linked it to this PR (not applicable: no documented behaviour changes)
AI-assisted PR
  • AI tool used: Claude Code
  • Codebase grounding: local clone
  • Human review: I have reviewed, tested, and verified the AI-generated content before submitting.

Note: autonomous AI agents submitting PRs without human oversight are not permitted — see the Code of Conduct.

cderv added 4 commits October 20, 2026 15:00
The default listing template always wrapped the metadata block in a link to the post. When the block shows nothing (no date or author, fields that exclude every metadata field, or a listed custom field that is missing or empty on the post), the link is empty: a Tab stop with no accessible name, flagged by axe `link-name`.

The link is now written only when the block has visible text. The guard follows the same field checks as the children it wraps, plus truthiness for extra fields, whose empty values render a bare ` `.

The `.metadata` div stays on every item. In the row layout it is a flex item, so removing it on items without metadata would widen `.body` on those items only and make body widths differ within one listing.
The guard tested truthiness, but a custom field holding an empty list or
a whitespace-only string is truthy and still renders no visible text, so
the metadata link stayed empty for those posts. The same holds for
`author`, which listing items carry as a list.

The guard now asks whether each value renders as visible text: falsy
values fall back to a bare ` `, and empty lists and blank strings
stringify to whitespace. The children are unchanged.
The subtitle line was written whenever `subtitle` is in the listing
fields, which it is by default, so every post without a subtitle got an
empty link in its body: a Tab stop with no accessible name, flagged by
axe `link-name`. It now uses the same visible-text check as the metadata
link. Unlike the metadata column, the subtitle line has no layout role,
so it is dropped entirely.

Fixes #14380
@posit-snyk-bot

posit-snyk-bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cderv
cderv merged commit 34e8108 into main Oct 20, 2026
51 checks passed
@cderv
cderv deleted the fix/listing-empty-metadata-link branch October 20, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants