Repository navigation
The photographs and the videos, and the privacy policy that declares the player - #218
Merged
Merged
Conversation
…os as rows partials/photo_gallery.html renders the gallery of an event page, under one Gallery heading, in two subsections. Photos (N): one figure per photograph, in a card of its own, with the caption under it in italic (it is the text of the post that published the photo, so it is marked as a quotation), the talk and its speakers credited under a photograph of a talk, the source credited as "Via @account" with the mark of the host in front of the link, and a link to the anchor of each figure. A photograph is capped at 675px high. Talks & Videos (N), on an edition page: one row per recording of the day, in programme order, the row the Talks block of a meetup page prints, with the title as the link to the page of the talk and the Watch line to YouTube. A subsection with nothing in it is not printed, and a page with neither has no gallery. partials/gallery_content.html resolves the block once per page, with the page as the cache key: the file of each item as an image resource, its talk by id, and its position. It skips an item whose file it cannot resolve and an item with no caption, on purpose: a missing asset would stop the build, and an image with no accessible name is worse on the page than one photo fewer. bin/check-content is what says those out loud, in the commit that follows. partials/event_videos.html gives it the videos of an edition: the agenda walked slot by slot, then the talks the agenda does not place, so PyData Barcelona 2017, which has talks and no grid, gets its videos from the second walk. David Arcos decided on 2026-10-15 that a recording is material added after the day, like a photograph, so it belongs in the Gallery at the end of the page and not under the schedule, where PyDay BCN 2020 alone had a Videos block for one day. partials/caption_links.html escapes a caption and then makes its mentions, hashtags, and URLs into links: the one field of the site that reaches a template through safeHTML, and the reason the canary page gets a caption. partials/photo_anchor.html gives the figure of a photo one id. The pages that draw it: layouts/_default/event.html prints the gallery last, after the sponsors and the people of the day, and lists it in the section index; layouts/_default/single.html prints it too, for the archived pages of 2016 to 2019 that are raw HTML on that layout; layouts/_default/meetup.html prints the photographs under the talks. The row of /events/ counts the photos of the day and the row of /talks/ the photos of the talk (partials/listing_counts.html); the page of a talk shows every photo that names it, each linked to its figure, under a Photos heading with the count (partials/talk_record.html returns the list, layouts/talks/single.html prints it), and talks.scss gets the rules of that card. photo_gallery.scss holds the rest, and the cap on the height.
PyBCN posted photographs live from each PyDay on X, and those posts are the only record of the day the association still owns. bin/import-x-photos staged them, one photo per post so no two share a caption, and a human curated each set: what the gallery does not want was dropped, and each photo that shows a talk points at that talk by id. The photos block of each page carries the thread, the items, and the comment that says where they came from. Eleven pages, 235 photographs, 101 of them naming a talk: PyDay BCN 2016 (4), PyData Barcelona 2017 (19), PyDay BCN 2018 (16), PyDay BCN 2019 (20), PyDay BCN 2021 (31), Hands-on Django with PyLadies BCN 2022 (11), PyDay BCN 2022 (32), PyDataBCN 2023 (25), PyDay BCN 2023 (33), PyDay BCN 2024 (23), and PyDay BCN 2025 (21). Four of them are the group photograph the association posted once the day was over, on PyDay BCN 2019, 2021, 2024, and 2025, last in its gallery. PyDay BCN 2020 was held on YouTube and has no photograph. The files sit under themes/pybcn_theme/assets/images/photos/<event>/, capped at 1000px wide by bin/fit-sources (IMPORTED_PHOTO_CAP), and the header image of the Django page is the one of the set. A photograph the association only shared, rather than took, is not here: its copyright belongs to whoever took it (LICENSING.md says so in the commit that follows).
…he canary bin/check-content gains check_gallery: every item of a photos block must reach the page it declares. It rejects a block that is not a block, an item with no file, a file in none of the asset directories or with a ".." segment, an item with no caption (the caption is the alt text, so the gallery leaves such a photo out rather than publish an image nobody can read), a photo that points at a talk of another file, and a source that is not an https URL (the credit reads the account out of its path). A photo wider than the gallery asks for is a warning that points at bin/fit-sources. The gallery of one event points only at the talks of its own file, so talk_ids_of is shared with check_agenda and reports each mistake once. bin/check-rendered gains a third canary. The caption of a gallery photo is the one field that reaches a template through safeHTML, so content/canary.md gets a photos block whose caption carries markup and a protocol relative address, //canary.invalid/caption, which the partial leaves alone and a template that printed the caption as markup would turn into a link to the canary host. The check fails if the caption did not reach the page as text. README.md describes the three canaries. LICENSING.md says where the event photographs come from, that the account credited is not the photographer, that a photograph the association only shared is never imported, and how to ask for one to come down.
partials/video_frame.html embeds one video in a frame from www.youtube-nocookie.com, the player that sets no cookie until the reader presses play. The id is read from the URL and checked against the shape of a YouTube id before it is written into the src: the URL is content, and no content field reaches the page through safeHTML. loading=lazy defers the request, referrerpolicy keeps the path of the page out of it, and the wrapper holds a 16:9 box (talks.scss) so the page does not move when the player arrives. The caller prints the plain link to YouTube under the frame in every case, so the page reads fine with the frame blocked. Where a player goes: on a page about one video. The page of the talk (layouts/talks/single.html, its Video section); the Recordings block of the page of a meetup or an edition (partials/session_videos.html), one player per recording of a whole session, because a recording that belongs to no talk has no page of its own and the page of its day is the page about it; and the Videos block of the page of a person (layouts/people/single.html), one player per talk of theirs that has one, with the link and the day under each. A listing or a programme grid prints a link and no frame, because PyDay BCN 2020 has a video on almost every row and would make one request to Google per row before a reader asked for any of them. Every heading over a list of recordings carries the count. bin/check-rendered allows the frame under talks/, events/meetups/, and people/ with that one src prefix and nowhere else. It is not nothing: the frame still asks Google for the player when the page loads, and Google sees the IP address and the browser of the reader at that moment, before play. The privacy policy says what the frame does and does not do, names the YouTube player among the Google services the site uses, and carries the registered address of the association; the legal notice names the player among the frames Google serves. David Arcos decided for the frame on 2026-10-14, after a first decision for a click-to-load facade, and for the players of the Recordings block on 2026-10-15.
The PyBCN YouTube channel holds 89 videos. bin/import-videos wrote each one as a link of type video on the talk record of the event that held it: 65 links on the talks of 34 meetup pages, and 29 on the talks of PyData Barcelona 2017, the form the 20 links of PyDay BCN 2020 already had. The row of a talk prints the link with the YouTube mark in front, the page of the talk plays it under its Video heading, and the gallery of PyData Barcelona 2017 lists its 29 recordings together. A recording of a whole session, a block of lightning talks or the introduction of an evening, belongs to no talk, so three meetup pages carry it as an entry of session_videos, title and url, which partials/session_videos.html plays under a Recordings heading after the talks, on the meetup page and on an edition page alike. Not "videos": Hugo reads that key as the og:video URLs of the page. data/channel_videos.yaml is the inventory of the channel, the list this site maintains: one entry per video with the id, the title, and the decision, placed or not and why, plus the 29 videos of other channels the pages link. 88 are placed and 1 is unplaced with a reason. bin/check-content reads it against the pages and never the network: a placed entry no page carries, a YouTube link no entry lists, an unplaced entry with no reason, a session video with no title or no url or listed twice on its page, and the reserved videos key are errors. Its summary line reports 117 YouTube links to 117 videos. AGENTS.md says how a new video gets noticed, through bin/list-channel, and what to write where. bin/check-content on this tree: 373 people, 74 sponsors, 607 talks on 224 pages, 87 venues, 0 errors, 81 warnings.
David Arcos walked the built site and reported a list. These are the fixes, kept together because each is small and none changes what the archive holds. The listings: the Day column shows the first day only, Venue, Gallery, Month, and Event are narrower, the venue hover appears only when the full name says more than the short one, and a speaker name on /talks/ reads and behaves like the link it is. The marks: one grey mark per link destination, on every external link including the ones in the body of a page and the edit link of the About block, with Flickr added to the table. "Watch on YouTube" is "Watch", because the mark already says where it goes. The person page: the bio and the social links sit beside the portrait, the roles moved onto the Events heading, the portrait zooms inside its frame the way the organizers cards do, and the generic avatar shows here too. Collaborator prints in the singular, and the board of 2018 to 2025 is the Former Management Board. The rest: the jump bar pins under the navigation as the page scrolls, PyData Barcelona 2017 lists its talks once with both counts, the feed sorts by the day the event happened rather than the day it was committed, Hacktoberfest 2018 takes the day and the organizers its own frozen archive records, and four PyDay editions get the group photograph of their closing post.
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 5 of 5 of the Archive, #213, and the one that closes it. Stacked on #217: its base is
archive/4-listings. Retarget it toeditionwhen the one before it merges.The photographs and the videos: what the days actually looked like.
What it adds
data/channel_videos.yaml, the inventory, and a check that fails when a video of the channel reaches no page. A missing video used to be something a person noticed by eye.youtube-nocookieframe, on 113 pages. A listing and an event page carry a link and no frame.The part to read carefully
The frame changes what a reader's browser does, so
content/pybcn_association/privacy-policy.mdandlegal-notice.mdchange with it. In short: Google serves the player, so it sees a reader's IP address and that they opened that page, before they press play; until they press play Google states the player stores nothing; and under every player there is the plain link to the same video on youtube.com, so the page reads fine with the frame blocked.The last commit, "Minor fixes from the second validation round", is the result of walking the built site: column widths, the mark on every external link, the sticky jump bar, and the group photograph of four PyDay editions.