Repository navigation
The loose ends: heading levels, the event page tags, a check, and the /events/ listing - #211
Merged
Merged
Conversation
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
force-pushed
the
fix/heading-order
branch
from
October 8, 2026 16:42
ba96892 to
e2aec13
Compare
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.
ifosch
approved these changes
Oct 10, 2026
ifosch
left a comment
Member
There was a problem hiding this comment.
LGTM! Great addition to review header skip levels... Looking forward to see how the events listing looks like. Thanks!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
bordered-col, the shortcode behind the cardsh4under theh1h2 class="h4"contact.htmlh4under theh1h2 class="h4"options.htmlh4under anh2h3 class="h4"home.htmlh4under anh2h3 class="h4"####under a#####promote-your-event, the 2017 PyData page, the 2018 PyDay page###and raw<h3>under theh1h2Every one keeps the size it had, through the
h4andh3Bootstrap classes, which is the patternevent.htmlalready uses withh2 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 wrappedmarkdownifyin ap, and markdownify emits apof its own, so every description nested one inside another: 6 more.</br>is not a tag. Abris 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 inagenda.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-renderednow fails a build that has one.It goes there and not in
check-contentbecause 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
mainelement 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 understatic/archives/are skipped, the same exemption thehttpcheck already makes.Checked both ways: nothing is reported on the build as it is, and putting one heading back to an
h4incontact.htmlmakes it reportcontact/index.html h1 -> h4and 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.htmlalready lists a section's pages, andcontent/events/_index.mdasked forlayout: "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.