From db48d34fb365256db5089f346855b1e8e41f5c97 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 20 Oct 2026 15:00:30 +0200 Subject: [PATCH 1/4] Only write the default listing metadata link when it has visible text 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. --- .../website/listing/item-default.ejs.md | 25 ++++++- tests/docs/listings-metadata-link/.gitignore | 4 ++ tests/docs/listings-metadata-link/_quarto.yml | 5 ++ .../listings-metadata-link/custom-field.qmd | 10 +++ tests/docs/listings-metadata-link/fields.qmd | 10 +++ tests/docs/listings-metadata-link/index.qmd | 10 +++ .../posts/dated/index.qmd | 8 +++ .../posts/empty-version/index.qmd | 6 ++ .../posts/undated/index.qmd | 5 ++ .../listings-metadata-link/reading-time.qmd | 10 +++ .../site/render-listing-metadata-link.test.ts | 72 +++++++++++++++++++ 11 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 tests/docs/listings-metadata-link/.gitignore create mode 100644 tests/docs/listings-metadata-link/_quarto.yml create mode 100644 tests/docs/listings-metadata-link/custom-field.qmd create mode 100644 tests/docs/listings-metadata-link/fields.qmd create mode 100644 tests/docs/listings-metadata-link/index.qmd create mode 100644 tests/docs/listings-metadata-link/posts/dated/index.qmd create mode 100644 tests/docs/listings-metadata-link/posts/empty-version/index.qmd create mode 100644 tests/docs/listings-metadata-link/posts/undated/index.qmd create mode 100644 tests/docs/listings-metadata-link/reading-time.qmd create mode 100644 tests/smoke/site/render-listing-metadata-link.test.ts diff --git a/src/resources/projects/website/listing/item-default.ejs.md b/src/resources/projects/website/listing/item-default.ejs.md index 823f32c18d3..fbf6e912361 100644 --- a/src/resources/projects/website/listing/item-default.ejs.md +++ b/src/resources/projects/website/listing/item-default.ejs.md @@ -14,9 +14,7 @@ return !["title", "image", "image-alt", "date", "author", "subtitle", "descripti // Capture the item number for utility functions that need it const itemNumber = listing.utilities.itemNumber(); -// Writes a metadata value -const outputMetadata = (item, field) => { - +// Reads a (possibly dotted) metadata field from an item const readField = (item, field) => { let value = item[field]; if (field.includes(".") && !field.endsWith(".") && !field.startsWith(".")) { @@ -29,6 +27,19 @@ value = value[deref]; return value; } +// Whether the metadata block shows any text for the item +const hasMetadata = (item) => { +return Boolean( +(fields.includes('date') && item.date) || +(fields.includes('author') && item.author) || +(fields.includes('reading-time') && item['reading-time']) || +otherFields.some(field => readField(item, field)) +); +} + +// Writes a metadata value +const outputMetadata = (item, field) => { + let value = readField(item, field); if (value !== undefined) { print(`
${listing.utilities.outputLink(item, field, value)}
`); @@ -91,10 +102,14 @@ print(`
${listing.utilities.outputLi ::: {.metadata} +<% if (hasMetadata(item)) { %> + ```{=html} ``` +<% } %> + <% if (fields.includes('date') && item.date) { %>
<%= item.date %>
<% } %> @@ -115,10 +130,14 @@ print(`