Skip to content

The loose ends: heading levels, the event page tags, a check, and the /events/ listing - #211

Merged
ifosch merged 4 commits into
editionfrom
fix/heading-order
Oct 10, 2026
Merged

ifosch merged 4 commits into
editionfrom
fix/heading-order

Conversation

@DZPM

@DZPM DZPM commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

The loose ends the earlier pull requests of this phase left behind. Four of them, each a commit, each independent of the others.

1. 14 pages skip a heading level

The HTML validator reports it as an error, and it makes a screen reader read the wrong outline: a reader moving by heading gets no way back up from a subsection that was never under a section.

Six sources, not one:

Source Was Is Pages
bordered-col, the shortcode behind the cards h4 under the h1 h2 class="h4" 3
contact.html two h4 under the h1 h2 class="h4" 1
options.html h4 under an h2 h3 class="h4" 7
home.html h4 under an h2 h3 class="h4" 1
Six event pages 18 #### under a ## ### 6
promote-your-event, the 2017 PyData page, the 2018 PyDay page ### and raw <h3> under the h1 h2 3

Every one keeps the size it had, through the h4 and h3 Bootstrap classes, which is the pattern event.html already uses with h2 class="h1". Nothing moves on the page: only the level changes, and the level is what carries the outline.

2. 41 of the 48 validator errors on PyDay BCN 2025 are a typo in a template

Not in the page, in event_detail.html: it wrote <b>Requirements:</b></b> and <b>Repository:</b></b>, with the closing tag doubled, which is 30 stray end tags across the 15 workshops of that page. It also wrapped markdownify in a p, and markdownify emits a p of its own, so every description nested one inside another: 6 more.

</br> is not a tag. A br is void and has no closing form, so a browser reads </br> as an opening one and the page gets a line break nobody asked for. 36 of them across the 2022, 2023, 2024, and 2025 pages.

And one that is not a markup problem but a broken link a reader can press: the Registration section of PyDay BCN 2025 says "General registration will open ... through Eventbrite" with href=''. An empty href reloads the page. It now carries the URL the Important dates section of the same page already has, which answers 200.

The 7 errors this does not fix are the <style> the agenda writes into the body. That one is not a typo: the agenda builds its grid from the number of tracks and the times of each page, so the rule cannot be static. Moving it needs custom properties on the container and the rest of the grid in agenda.scss, which is a rework of the schedule and not a tidy-up.

3. A check, so the fifteenth page cannot happen

Nothing stopped the heading skips coming back. bin/check-rendered now fails a build that has one.

It goes there and not in check-content because a heading comes from three places at once: the markdown of a page, a shortcode, and the template around both. Only the built page knows the order they ended up in, which is why the 14 were six different sources.

It reads the main element with the person modals taken out, because a modal holds a heading tree of its own inside a dialog that is closed until a reader opens it. The frozen copies under static/archives/ are skipped, the same exemption the http check already makes.

Checked both ways: nothing is reported on the build as it is, and putting one heading back to an h4 in contact.html makes it report contact/index.html h1 -> h4 and fail.

4. /events/ had no listing

It answered 200 with the word "Events" and nothing under it, which is the open half of an item of #190. #202 took /people/ away because nothing linked to it and it held nothing; /events/ is a real section with real children and the fix is the opposite.

One line. layouts/_default/list.html already lists a section's pages, and content/events/_index.md asked for layout: "single" so the fallback never ran. The page now lists Monthly Events, Other events, PyDataBCN, and PyDay BCN, each linked and with its description.


This closes the last two open items of #190, and the first three commits are each measured against the build rather than asserted.

@DZPM
DZPM requested a review from a team as a code owner October 8, 2026 16:38
@DZPM DZPM self-assigned this Oct 8, 2026
@DZPM
DZPM requested review from ber2, mesejo and mrswats October 8, 2026 16:39
14 pages jumped a heading level, which the HTML validator reports as an
error and which makes a screen reader read the wrong outline: a reader
moving by heading gets no way back up from a subsection that was never
under a section.

Six sources, not one:

- bordered-col, the shortcode behind the cards on /contact/, the PyLadies
  home and the PyLadies contact page, emitted an h4 under the h1. An h2.
- contact.html emitted two more under the h1. Two h2.
- options.html emitted one under an h2, on seven event pages. An h3.
- home.html emitted one under an h2. An h3.
- Six event pages wrote #### directly under a ##, 18 headings between
  them. They are ### now.
- promote-your-event and the 2017 PyData page wrote ### under the h1, and
  the 2018 PyDay page five raw h3 in its pre-Hugo block. All h2.

Every one keeps the size it had, through the h4 and h3 Bootstrap classes,
which is the pattern event.html already uses with h2 class="h1". Nothing
moves on the page: only the level changes, and the level is what carries
the outline.

Measured over the whole build, leaving the frozen copies under /archives/
out: 14 pages had a skip and none has one now. Nothing but heading lines
is touched, which the diff shows.
@DZPM
DZPM force-pushed the fix/heading-order branch from ba96892 to e2aec13 Compare October 8, 2026 16:42
DZPM added 3 commits October 8, 2026 20:14
The PyDay BCN 2025 page carries 48 validator errors. 41 of them are three
mistakes, and none is in the page: they are in a template and in a sed-able
typo repeated across four event pages.

event_detail.html wrote `<b>Requirements:</b></b>` and
`<b>Repository:</b></b>`, with the closing tag doubled, which is 30 stray
end tags across the 15 workshops of that page. It also wrapped
`markdownify` in a `p`, and markdownify emits a `p` of its own, so every
description nested one inside another: 6 more. The labels are their own
paragraph now and markdownify is left to wrap its own text.

`</br>` is not a tag. A `br` is void and has no closing form, so a browser
reads `</br>` as an opening one and the page gets a line break it was not
asked for. 36 of them across the 2022, 2023, 2024, and 2025 pages, 4 of
them on 2025.

And one that is not a markup problem but a broken link a reader can press:
the Registration section of PyDay BCN 2025 says "General registration will
open ... through Eventbrite" with `href=''`. An empty href reloads the
page. The URL is the one the Important dates section of the same page
already carries, which answers 200.

Measured on the built page: 30 stray `</b>` and 6 stray `</p>` are 0, the
4 `</br>` are 0, and there is no empty href left anywhere in content.

The 7 errors this does not fix are the `<style>` the agenda writes into the
body. That one is not a typo: the agenda builds its grid from the number of
tracks and the times of each page, so the rule cannot be static. Moving it
needs custom properties on the container and the rest of the grid in
agenda.scss, which is a rework of the schedule and not a tidy-up.
The commit two below this one fixed 14 pages that jumped a heading level.
Nothing stopped the fifteenth. This is what does.

It goes in the rendered check and not in check-content because a heading
comes from three places at once: the markdown of a page, a shortcode, and
the template around both. Only the built page knows the order they ended up
in, which is why the 14 were six different sources.

What it reads is the main element, with the person modals taken out: a
modal holds its own h3 and h4, a heading tree of its own inside a dialog
that is closed until a reader opens it, and it is not part of the outline
of the page around it. The frozen copies under static/archives/ are served
as they are and are not ours to restructure, so they are skipped, the same
exemption the http check already makes.

The message says to change the level and not the size, because that is the
whole fix: a Bootstrap class keeps the look while the element carries the
right level.

Checked both ways. On the build as it is now, no page is reported. With one
heading put back to an h4 in contact.html, it reports
"contact/index.html  h1 -> h4" and fails.
/events/ answered 200 with the word "Events" and nothing under it. It is
the open half of an item of #190: #202 took /people/ away because nothing
linked to it and it held nothing, but /events/ is a real section with real
children and the fix there is the opposite, a listing.

One line does it. The section already had a layout that lists its pages,
layouts/_default/list.html, added so that a section with no layout of its
own does not fall through to the raw index.xml. content/events/_index.md
asked for layout: "single", which renders the title and a body that is
empty, so the fallback never ran. Without that line it does, and the page
lists Monthly Events, Other events, PyDataBCN, and PyDay BCN, each linked
and with its description.

The build is the same 109 pages with the change and without it: this adds
content to a page that already existed.
@DZPM DZPM changed the title Stop skipping heading levels The loose ends: heading levels, the event page tags, a check, and the /events/ listing Oct 8, 2026

@ifosch ifosch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Great addition to review header skip levels... Looking forward to see how the events listing looks like. Thanks!

@ifosch
ifosch merged commit ea6289b into edition Oct 10, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants