Repository navigation
The schedule model: a talk stops being the slot that placed it - #215
Merged
Merged
Conversation
An event page used to carry one list, events, with every fact of a session in each row: the time, the room, the colour, the title, the speaker as free text, the description, and the links. It now carries three: rooms (id and name), talks (the content: title, speakers, description, language, topic, duration_minutes, links) and agenda (the grid: start, track_length, room, and a talk id or its own label and type). They are separate because one talk can take more than one slot, and because a photo or a page can point at a talk by id, which a row of a grid cannot give it. partials/agenda_entry.html is the join, in one place, so the block of the grid and the modal behind it cannot disagree. It also computes what the page used to store: the colour, one per room of the day from the palette agenda.scss defines, and the end of a slot, from its start and the length of what fills it. speakers is a list of person ids and the name printed is the one the record holds; the free-text speaker field is gone. language is a code, en, es or ca, or a list of them written in that order. Also in this change: partials/event_types.html gains keynote and panel, and the singular and plural noun of each type; partials/event_type_icon.html can draw a named icon, with the label as its accessible name, for a row that prints nothing else about the type; partials/video_link.html prints a link to a video with the mark of its host in front, and the modal behind a block of the grid prints the video of a session through it. The block itself prints no link: a link belongs on a row and a player on a page about one talk, and a block of the grid is neither. partials/people_names.html and partials/speaker_names.html resolve person ids to names once per build. The modal lists the repositories of a talk as a list of links, no longer one string with raw HTML in it. partials/link_mark.html is the one mark per link destination the site prints. The host of the URL picks the glyph: YouTube, GitHub, GitLab, Bitbucket, SlideShare, Speaker Deck, Flickr, Google Drive, LinkedIn, Meetup, X, or a generic arrow for any other host. It is grey at rest like every other icon of the site (.link_mark in main.scss) and hidden from a screen reader, because the words beside it name the destination. video_link.html prints its mark through it, and so does the link render hook, layouts/_default/_markup/render-link.html, so an external link in the body of a page carries the same mark as one a template writes.
…th no grid The hero of an edition page prints the title and the description and no date, so until now the page said its day nowhere a reader or a machine could find it. partials/event_date.html formats an event date, and a range when end_date is set, as one time element per day, and the page prints it as the first line of its column: "19 to 21 May 2017" for PyData Barcelona 2017, "29 November 2025" for PyDay BCN 2025. Every edition page carries date and venue now, and the two that ran more than one day carry end_date. partials/talk_rows.html lists the talks of a page as rows, one per talk, with the icon of the type, the title, who gave it, and the video when the talk has one. event.html draws them where the grid would be for a page that has talks and no agenda: PyData Barcelona 2017 holds 32 talks and no record of the room or the hour of any of them, so there is no grid to draw. PyDay BCN 2018 and 2019 carry an agenda with no eventTimes on purpose and publish the frozen programme in their body, so they get no rows either.
A talk credits its speakers by person id, so every speaker of the eleven programmes needs a record under content/people/. 38 records are new, most of them a name and an id, which is what the source gives: the printed agenda of a PyDay names a person and nothing else about them. One of them, Giorgio Polvara, is an organizer and not a speaker: the frozen site of Hacktoberfest 2018 names him with three people who already have a record. Five records are corrected rather than added. Four names get the accent their owner writes (Daniel Mesejo León, Daniel Sánchez Santolaya, Eva Martín del Pico, Julio Martínez) and one loses the leading space it carried (Noé Casas). The import that follows resolves a speaker name to a record by the same name ignoring accents and case, so a record with the wrong spelling would still resolve, and then print it. The portrait of Jordi Bosch is replaced with the one David Arcos sent on 2026-10-14, cut square by bin/square-photos.
The eight pages that carried an events list carry the three lists now: Django Girls with PyLadies BCN 2022 (2 talks over 10 slots, one workshop in four parts), PyDataBCN 2023 (13 talks, 19 slots, 5 rooms), and PyDay BCN 2020 to 2025 (20, 17, 14, 14, 16, and 17 talks). Every speaker is a person id, every language a code, every time a quoted string, and the colour of a block is gone from the content: across the eight editions 24 colour-and-room combinations covered more than one room and only 20 mapped to a single room, so it meant nothing. The rows a slot used to carry that belong to the day and not to the talk stay on the slot: the start, the room, the python level, the topic level, the requirements, and the sponsor. Each page also carries its date and its venue, and the previous_editions list, which no template read, is gone. The 20 video links of PyDay BCN 2020 are kept on the talks they belong to, as links of type video, which is where the grid reads them.
…eir frozen pages Three editions had a page and no programme the templates could read. PyData Barcelona 2017 gets its 32 talks from the archive, with the description each speaker wrote and the slides the page used to list in its body as a numbered list with the speaker names typed in. The talks carry no room and no hour, because no source gives them, so the page lists them as rows and draws no grid. The Media and Slides lists leave the body: the talk records hold the same links. PyDay BCN 2018 gets its 8 sessions off the agenda table the association froze into the page, in 4 rooms, with no length because the printed programme gives none. Its five speakers get a record. PyDay BCN 2019 gets its 15 sessions off the agenda the thread of the day photographed, in 3 rooms. The printed agenda names no speaker, and the thread announced only some of the sessions, so 11 of the 15 talks credit nobody and the four that do (the two keynotes, Héctor Canto, and Anna Fedotova) carry the post they were read from as their source. Both pre-Hugo pages keep their body, the pasted table of 2018 and the calendar embed of 2019, and carry agenda, talks and rooms with no eventTimes, so the page draws no second grid under the frozen one.
…dition PyDay BCN 2016 named its eleven sponsors in prose, five of them with no record and no logo. The five get a record under content/sponsors/ (AtlaSense, Claranet, MongoDB, Punt Multimèdia, Schibsted Spain) and a logo under the theme assets, and the page lists all eleven through sponsor_levels, the grid every other edition uses. The logos of the two whose host no longer answers still link to the site the sponsor paid for: a host that does not answer today is a fact about that host, and the record of what was agreed is not ours to drop (David Arcos, 2026-10-14). The page also carries its three days, 15 to 17 September 2016, and its venue, and takes layouts/_default/event.html so the sponsors render. Hacktoberfest 2018 gets its day, 21 October 2018, its venue, Kernel Analytics, and its four organizers from the frozen copy of the site of the day under static/archives/hacktoberfestbarcelona.com/, which the menu entry of the page already pointed at. An earlier comment on the page said no source gave the day; the source was the page this one links to. No agenda, on purpose: the frozen page lists hours and names no speaker and no talk, so a programme would invent a grid the day did not have.
bin/check-content reads the three lists the pages carry now, because the join between them fails in silence: a slot that names a talk the page does not define renders as an empty block, which looks like a gap in the programme and not like a mistake. What it rejects: a page that still carries events, the model agenda and talks replaced; a room with no id or no name, or an id used twice; a talk with no type or an unknown one, a language that is not en, es or ca, a list of languages in another order, a duration that is not a whole number, a link with no type or no address, and the free-text speaker field; a speaker id with no record behind it; a talk id used twice in one file, which leaves the second talk unreachable; a slot whose start is not a quoted H:MM string (YAML 1.1 reads an unquoted 9:00 as the integer 540), with no track_length, naming a room or a talk the page does not declare, or with no talk and no type or length of its own. It also checks end_date: it is a date, date is there too, and end_date is later than date, because the date partial treats an end_date it cannot use as absent and a two day edition turns back into one day in silence. A talk with no speaker is a warning, not an error, with a count per page: the source of PyDay BCN 2019 names nobody for 11 of its 15 sessions, and a count that grows is the sign that a source was read carelessly. The speakers of a talk count as a listing for the orphan check, so a person credited by a programme and by no people block is no longer reported. The summary line counts the talks and the pages that declare them: 168 talks on 11 pages in this tree. AGENTS.md says what the three lists are and that a time is a quoted string, and CONTRIBUTING.md adds end_date to what the check fails on.
This was referenced Oct 15, 2026
Closed
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.
Part 2 of 5 of the Archive, #213. Stacked on #214: its base is
archive/1-tools, so the diff shows only this part. Retarget it toeditiononce #214 merges, which is also what makes CodeQL run on it.A schedule entry used to be one record that was both the talk and the slot of the grid that placed it. That is why the site could never say what a person had given: the title lived inside a cell of a timetable. This splits the two, across the eight programmes that still mixed them, and teaches the templates the new shape.
What it changes
rooms,talks, andagendareplace the singleeventslist. A talk carries its title, its speakers, its language, and its links; a slot carries its time, its room, and its level.editionit reports 8 errors, because these are the eight pages it is about to fix.The acceptance test
The built schedule of those pages does not change. That was checked page by page while converting: the same rows, the same rooms, the same times, with only what was deliberately removed gone.