Skip to content

reedvoid/blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

reedvoid.github.io

Personal blog. Static HTML generated from Markdown, served via GitHub Pages.

Directory structure

content/
  about.md               # section: about
  assets/
    tal-episodes.json    # generated by scripts/scrape_tal_episodes.py
  blog/
    YYYYMMDD-title.md    # section: blog   (special — see below)
generator/
  generate.py
  input.css
  requirements.txt
  templates/
    base.html
    blog_index.html
    post.html
    section.html
    tal_player.html      # TAL shuffle player (no .md source — see TAL Player)
scripts/
  scrape_tal_episodes.py # scrapes thisamericanlife.org, writes tal-episodes.json
docs/                    # generated output — GitHub Pages source

Usage

pip install -r generator/requirements.txt
python generator/generate.py

Sections

Each .md file in content/ must have a section: field in its YAML front matter. The value determines where the output is written:

  • Regular sections (section: about, section: projects, etc.) — generate docs/{section}/index.html, reachable at /{section}/. Add a new section by dropping a new .md file in content/ with the desired section: value. The nav bar is auto-generated: blog always appears first, then sections in filename-alphabetical order, then tal-player last.
  • section: blog — special case. Must live in content/blog/. Does not generate a section directory; see Blog below.

Files in content/ missing a section: field are silently skipped.

Blog

Blog posts require title: and date: (ISO format: YYYY-MM-DD) in addition to section: blog.

URL slug is derived deterministically as {date}-{slugified-title}, e.g. a post titled Hello World dated 2026-04-25 becomes /blog/2026-04-25-hello-world/.

Collision detection — if two posts would produce the same slug, the generator exits with an error listing both source files before writing anything.

Blog index is auto-generated, sorted newest-first, and served at both / and /blog/. There is no content/ source file for it.

Posts missing title: or date: are skipped with a warning.

TAL Player

A shuffle player for This American Life archival episodes, served at /tal-player/.

Episode data is stored in content/assets/tal-episodes.json and loaded client-side at runtime. The page itself is generated directly from generator/templates/tal_player.html with no .md source file.

Queue persistence — the playback queue (up to 100 episodes) and current position are saved to localStorage['tal-queue'] after every navigation. On page load the queue is restored and the current episode is shown paused at the beginning. This survives mobile browser tab discards (e.g. iOS backgrounding the tab for long enough that the OS kills the process).

To update the episode list (normal case):

.venv/bin/python scripts/update_tal_episodes.py
.venv/bin/python generator/generate.py

update_tal_episodes.py does an incremental refresh: it HEAD-validates all existing audio URLs in parallel (10 workers), then discovers new episodes by fetching the /archive newest-first landing and the / homepage. Only episodes with a number higher than the current max are fetched. Typical wall time ~30s. It will surface broken existing URLs in its summary but does not auto-repair them.

Full rescrape (rebuild from scratch):

.venv/bin/python scripts/scrape_tal_episodes.py
.venv/bin/python generator/generate.py

This walks /archive?year=YYYY for every year from 1995 onward and re-fetches every episode page. Takes ~30 minutes due to per-page rate-limit delays. Use it if the JSON gets out of sync, an episode's URL changes, or you want to refresh metadata. The /archive?year=YYYY endpoint can lag for the most recent few episodes, so a full rescrape immediately after a release may still need a follow-up update_tal_episodes.py run to pick them up.

The .scrape-cache/ directory is a within-run deduplication cache used by scrape_tal_episodes.py only; it is wiped at the start of every full scrape and is not committed.

GitHub Pages setup

Point GitHub Pages to the docs/ folder on the main branch. Nav links use root-relative paths so they work correctly at the root domain.

About

No description, website, or topics provided.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors