Skip to content

Commit d088982

Browse files
committed
create index pages for examples
1 parent 85e2524 commit d088982

2 files changed

Lines changed: 106 additions & 0 deletions

File tree

build.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,76 @@
1515
)
1616
CANVAS_COURSE_PATTERN = re.compile(r"canvas\.uchicago\.edu/courses/\d+")
1717

18+
EXAMPLES_EXCLUDE_DIRS = {"__pycache__", "images"}
19+
EXAMPLES_EXCLUDE_SUFFIXES = {".pyc"}
20+
21+
22+
def build_examples_indexes(examples_root: Path, env, base_url: str):
23+
"""Generate index.html pages for the examples tree.
24+
25+
Walks examples/ recursively. For any directory without an existing
26+
index.html, renders one that lists its subdirectories and files.
27+
The top-level page lists each week; deeper pages list their contents.
28+
"""
29+
template = env.get_template("examples_index.html")
30+
31+
def is_hidden(p: Path) -> bool:
32+
return any(part.startswith(".") for part in p.relative_to(examples_root).parts)
33+
34+
def is_excluded(p: Path) -> bool:
35+
return any(part in EXAMPLES_EXCLUDE_DIRS for part in p.relative_to(examples_root).parts)
36+
37+
all_dirs = [examples_root, *sorted(p for p in examples_root.rglob("*") if p.is_dir())]
38+
for dirpath in all_dirs:
39+
if is_hidden(dirpath) or is_excluded(dirpath):
40+
continue
41+
if (dirpath / "index.html").exists():
42+
continue
43+
44+
rel = dirpath.relative_to(examples_root)
45+
url_prefix = f"{base_url}/examples"
46+
if rel != Path("."):
47+
url_prefix += "/" + "/".join(rel.parts)
48+
49+
entries = sorted(dirpath.iterdir(), key=lambda p: (not p.is_dir(), p.name.lower()))
50+
dirs = [
51+
{"name": p.name, "url": f"{url_prefix}/{p.name}/"}
52+
for p in entries
53+
if p.is_dir()
54+
and p.name not in EXAMPLES_EXCLUDE_DIRS
55+
and not p.name.startswith(".")
56+
]
57+
files = [
58+
{"name": p.name, "url": f"{url_prefix}/{p.name}"}
59+
for p in entries
60+
if p.is_file()
61+
and p.name != "index.html"
62+
and p.suffix not in EXAMPLES_EXCLUDE_SUFFIXES
63+
and not p.name.startswith(".")
64+
]
65+
66+
if rel == Path("."):
67+
title = "Examples"
68+
crumbs = []
69+
parent_url = ""
70+
else:
71+
title = "Examples — " + " / ".join(part.replace("_", " ") for part in rel.parts)
72+
crumbs = [{"name": "Examples", "url": f"{base_url}/examples/"}]
73+
accum = f"{base_url}/examples"
74+
for part in rel.parts[:-1]:
75+
accum += f"/{part}"
76+
crumbs.append({"name": part, "url": f"{accum}/"})
77+
crumbs.append({"name": rel.parts[-1], "url": ""})
78+
parent_parts = rel.parts[:-1]
79+
parent_url = f"{base_url}/examples/" + (
80+
"/".join(parent_parts) + "/" if parent_parts else ""
81+
)
82+
83+
html = template.render(
84+
title=title, crumbs=crumbs, parent_url=parent_url, dirs=dirs, files=files
85+
)
86+
(dirpath / "index.html").write_text(html)
87+
1888

1989
def apply_config(text: str) -> str:
2090
"""Replace quarter and Canvas course ID references with current config values."""
@@ -140,6 +210,9 @@ def build_site(output_dir: str = "_site", base_url: str = ""):
140210
homepage_html = env.get_template("index.html").render()
141211
(out / "index.html").write_text(homepage_html)
142212

213+
# Examples index pages (top-level + per-week + per-subdir)
214+
build_examples_indexes(out / "examples", env, base_url)
215+
143216

144217
if __name__ == "__main__":
145218
parser = argparse.ArgumentParser(description="Build the static site.")

templates/examples_index.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{% extends "base.html" %}
2+
3+
{% block title %}{{ title }} | Web Development{% endblock %}
4+
5+
{% block content %}
6+
<div class="lecture-index">
7+
<h1>{{ title }}</h1>
8+
{% if crumbs %}
9+
<p class="breadcrumbs">
10+
{% for crumb in crumbs %}{% if not loop.last %}<a href="{{ crumb.url }}">{{ crumb.name }}</a> / {% else %}{{ crumb.name }}{% endif %}{% endfor %}
11+
</p>
12+
{% endif %}
13+
{% if parent_url %}
14+
<p><a href="{{ parent_url }}">← Up</a></p>
15+
{% endif %}
16+
{% if dirs %}
17+
<h2>Directories</h2>
18+
<ul>
19+
{% for d in dirs %}
20+
<li><a href="{{ d.url }}">{{ d.name }}/</a></li>
21+
{% endfor %}
22+
</ul>
23+
{% endif %}
24+
{% if files %}
25+
<h2>Files</h2>
26+
<ul>
27+
{% for f in files %}
28+
<li><a href="{{ f.url }}">{{ f.name }}</a></li>
29+
{% endfor %}
30+
</ul>
31+
{% endif %}
32+
</div>
33+
{% endblock %}

0 commit comments

Comments
 (0)