Skip to content

Commit eeae0cf

Browse files
committed
add posts
1 parent e5cb02d commit eeae0cf

File tree

6 files changed

+137
-0
lines changed

6 files changed

+137
-0
lines changed

build.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ def build_all_pages():
4646
if page == "manual":
4747
build_lab_manual()
4848
continue
49+
elif page == "posts":
50+
build_posts()
51+
continue
4952

5053
content_file = content_dir / f"{page}.yaml"
5154
content = yaml.safe_load(content_file.open().read())[page]
@@ -81,6 +84,86 @@ def build_all_pages():
8184
shutil.copytree("assets", build_dir / "assets")
8285

8386

87+
def build_posts():
88+
"""Build blog-post-like pages from markdown files in content/posts/."""
89+
posts_dir = content_dir / "posts"
90+
if not posts_dir.exists():
91+
return
92+
93+
environment = Environment(loader=FileSystemLoader(template_dir))
94+
template = environment.from_string((template_dir / "post.html").open().read())
95+
md = Markdown(
96+
extras=[
97+
"fenced-code-blocks",
98+
"highlightjs-lang",
99+
"metadata",
100+
"tables",
101+
"footnotes",
102+
]
103+
)
104+
105+
posts_metadata = [] # Collect metadata for index
106+
107+
for post_file in posts_dir.glob("*.md"):
108+
slug = post_file.stem
109+
raw_content = post_file.read_text()
110+
111+
html_content = md.convert(raw_content)
112+
metadata = getattr(md, "metadata", {}) or {}
113+
114+
page_dir = build_dir / "p" / slug
115+
page_dir.mkdir(exist_ok=True, parents=True)
116+
page_file = page_dir / "index.html"
117+
118+
page_url = f"/p/{slug}/"
119+
120+
# Collect for index
121+
posts_metadata.append(
122+
{
123+
"slug": slug,
124+
"url": page_url,
125+
"title": metadata.get("title", slug.replace("-", " ").title()),
126+
"subtitle": metadata.get("subtitle"),
127+
"date": metadata.get("date"),
128+
}
129+
)
130+
131+
html = template.render(
132+
page_url=config["deploy_url"] + page_url.lstrip("/"),
133+
title=metadata.get("title", slug.replace("-", " ").title()),
134+
subtitle=metadata.get("subtitle"),
135+
date=metadata.get("date"),
136+
content=html_content,
137+
**config,
138+
)
139+
140+
with page_file.open("w") as f:
141+
f.write(html)
142+
143+
# Build index after all posts (even if none)
144+
build_posts_index(posts_metadata, environment)
145+
146+
147+
def build_posts_index(posts_metadata: list[dict], environment: Environment):
148+
"""Build an index page listing all posts."""
149+
template = environment.from_string(
150+
(template_dir / "posts_index.html").open().read()
151+
)
152+
153+
page_dir = build_dir / "p"
154+
page_dir.mkdir(exist_ok=True, parents=True)
155+
156+
html = template.render(
157+
page_url=config["deploy_url"] + "p/",
158+
title="Posts",
159+
posts=sorted(posts_metadata, key=lambda x: x.get("date") or "", reverse=True),
160+
**config,
161+
)
162+
163+
with (page_dir / "index.html").open("w") as f:
164+
f.write(html)
165+
166+
84167
def build_lab_manual():
85168
name = config["pages"]["manual"]["url"][1:-1]
86169
environment = Environment(loader=FileSystemLoader(template_dir))

config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ pages:
4444
url: /lab-manual/
4545
template: manual.html
4646
file: lab-manual/index.html
47+
posts:
48+
name: Posts
49+
url: /p/
50+
template: posts_index.html
51+
file: p/index.html
4752
contact:
4853
name: Contact
4954
url: /contact/

content/posts/.gitkeep

Whitespace-only changes.

templates/manual.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ <h1 class="page-title">Lab manual</h1>
3838
<!-- Code block highlighting -->
3939
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
4040
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-python.min.js"></script>
41+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-bash.min.js"></script>
4142
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
4243
{% endblock js %}

templates/post.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{% extends "_template.html" %}
2+
3+
{% block head %}
4+
{{ super() }}
5+
<!-- Code block highlighting -->
6+
<link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" />
7+
{% endblock head %}
8+
9+
{% block title %}Post - {{ title }}{% endblock title %}
10+
11+
{% block content %}
12+
<div class="container py-5">
13+
<article>
14+
<header class="mb-4">
15+
<h1>{{ title }}</h1>
16+
{% if date %}<p class="text-muted"><small>{{ date }}</small></p>{% endif %}
17+
{% if subtitle %}<p class="lead">{{ subtitle }}</p>{% endif %}
18+
</header>
19+
<div class="post-content">
20+
{{ content }}
21+
</div>
22+
</article>
23+
</div>
24+
{% endblock %}
25+
26+
{% block js %}
27+
{{ super() }}
28+
<!-- Code block highlighting -->
29+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
30+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-python.min.js"></script>
31+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-bash.min.js"></script>
32+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
33+
{% endblock js %}

templates/posts_index.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{% extends "_template.html" %}
2+
{% block content %}
3+
<div class="container py-5">
4+
<h1>{{ title }}</h1>
5+
<ul class="list-unstyled">
6+
{% for post in posts %}
7+
<li class="mb-3">
8+
<a href="{{ post.url }}">{{ post.title }}</a>
9+
{% if post.date %}<small class="text-muted ms-2">{{ post.date }}</small>{% endif %}
10+
{% if post.subtitle %}<p class="text-muted mb-0"><small>{{ post.subtitle }}</small></p>{% endif %}
11+
</li>
12+
{% endfor %}
13+
</ul>
14+
</div>
15+
{% endblock %}

0 commit comments

Comments
 (0)