Skip to content

Fix apostrophe in PyCon Côte d'Ivoire entry - #512

Merged
JesperDramsch merged 1 commit into
mainfrom
JesperDramsch-patch-1
Oct 19, 2026
Merged

JesperDramsch merged 1 commit into
mainfrom
JesperDramsch-patch-1

Conversation

@JesperDramsch

Copy link
Copy Markdown
Owner

No description provided.

@JesperDramsch
JesperDramsch merged commit aa1e44c into main Oct 19, 2026
9 of 10 checks passed
@JesperDramsch
JesperDramsch deleted the JesperDramsch-patch-1 branch October 19, 2026 12:36

Copy link
Copy Markdown
Owner Author

Routine review

Request. Title only, no body and no linked issue: "Fix apostrophe in PyCon Côte d'Ivoire entry". That covers one instance, the PyCon Côte d'Ivoire 2027 entry in _data/conferences.yml. The diff changes only its conference value, from a straight ' to a curly ’ (U+2019).

Checked against. Today is Mon Oct 19 12:37:16 UTC 2026 (date). I fetched no external URLs. Every claim below comes from the repository.

Needs your decision.

  1. This PR was already merged at 2026-10-19T12:36:52Z (as aa1e44c) before this review ran, so any fix has to go in a follow-up PR. Where should the fix go? You can change the template, so that _layouts/conference.html:350,351,353,420 render {{ page.x | jsonify }} instead of '{{ page.x }}'. That covers every entry, now and later. Or you can change the data, adding U+2019 to place (and to the location title for consistency). That fixes only this entry. My recommendation is the template fix. It also makes the curly name optional. AGENTS.md says to spell conference the way the data already spells it, so whether to keep the curly name is your call.

Findings.

Important

  • _data/conferences.yml:90 with _layouts/conference.html:353: the conference page for this entry still fails to run its script. The entry's place keeps the straight apostrophe (place: Abidjan, Côte d'Ivoire). Line 353 interpolates it unescaped as const confPlace = '{{ page.place }}';. That line sits in the same <script> element (lines 233–436) as the confName/seriesName lines (350, 420) that the curly name was meant to make parse. _config.yml's page_gen entry (data conferences, template conference) renders this record into that layout. The rendered snippet fails to parse:
    const confPlace = 'Abidjan, Côte d'Ivoire';
                                       ^^^^^^
    SyntaxError: Unexpected identifier 'Ivoire'
    
    The same snippet without that line, but with the curly confName, parses (node --check exit 0). So on /conference/…-2027/ the calendar-option handler and the follow/save button init still never run. Smallest fix: add | jsonify and drop the surrounding quotes at lines 350, 351, 353 and 420 (see decision 1).

Nits

  • _data/conferences.yml:95: the location title: PyCon Côte d'Ivoire 2027 still uses the straight apostrophe. It no longer matches conference + year.
  • Series follows are keyed on the raw conference string (static/js/action-bar.js:82-86, conference-manager.js:46). Anyone who already followed the straight-apostrophe spelling will no longer match. Page slugs are unaffected, because both apostrophes collapse to -.

Tests. No test covers the request's invariant: a conference page must render valid JS for names or places that contain an apostrophe. There is no fix test to run against the base.

  • Data (REVIEW.md): uv run --python 3.11 … python utils/sort_yaml.py --skip_links exited 0: ✅ 1243 conferences passed validation, 🎉 Conference data sorting and cleaning completed successfully. git diff --stat -- _data printed nothing, so there is no post-merge rewrite.
  • npm ci exited 0. npm test: Test Suites: 15 passed, 15 total / Tests: 423 passed, 423 total.
  • No Python changed, so I did not run ruff or pytest.

Bounds. I got the change from the API diff and checked out refs/pull/512/head. rev-parse matched 843c3e9. I read in full: the diff, the entry, REVIEW.md, AGENTS.md, _layouts/conference.html script lines 345–425, and the _config.yml page_gen block. I skimmed: _includes/head.html (uses jsonify, fine) and the slug uses in _includes/_layouts. I could not run a Jekyll build in the sandbox. A subagent confirmed the Important finding with node --check on the substituted lines, not on a rendered page. Pre-existing: _layouts/conference.html:350-353,420 interpolate data into single-quoted JS strings without escaping, so any future entry with a ' in conference or place breaks its page the same way.


Generated by Claude Code

JesperDramsch added a commit that referenced this pull request Oct 19, 2026
* Escape conference text in inline JavaScript with jsonify

Liquid pastes values verbatim, so `place: '{{conf.place}}'` rendered as
`place: 'Abidjan, Côte d'Ivoire'` and the front page's per-conference
script failed to parse. The curly apostrophe in #512 fixed the name but
not the place, so the front page and the PyCon Côte d'Ivoire page still
threw a SyntaxError.

Every conference name, place and link that reaches JavaScript now goes
through jsonify, the way head.html and the JSON-LD block already do.
tests/test_template_escaping.py fails when a free-text conference field
lands in a script without jsonify or slugify, or when a jsonify'd value
is wrapped in quotes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSanwpb5BXzbhLxMFyz9yS

* Match script end tags with whitespace or attributes in the template test

CodeQL (py/bad-tag-filter) flagged that `</script>` misses `</script >`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSanwpb5BXzbhLxMFyz9yS

* Escape conference text in HTML attributes and reset the extended label

Free text in a double-quoted attribute ended the value at the first ",
so data-conf-name, data-location, aria-label, meta content and the share
and map links now go through escape, or url_encode where the value is
part of a URL. The share links replace url_encode's + with %20, which
mailto: needs and the other targets accept. URL fields stay as they are:
the schema validates them and pydantic percent-encodes quotes in them.

The front page's action bar got the name and place through include
parameters, and the extra places through a for loop, so the template test
now follows include parameters and variables set with assign or for.

calendar.js never reset `extended`, so every conference after the first
extended CfP was labelled "(extended)" too: 66 labels for 16 extended
CfPs. It now resets the way calendar-deadlines.ics already does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSanwpb5BXzbhLxMFyz9yS

---------

Co-authored-by: Claude <noreply@anthropic.com>
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.

1 participant