Skip to content

Commit ca2f8b0

Browse files
committed
feat: per-tag page
1 parent a07180d commit ca2f8b0

7 files changed

Lines changed: 74 additions & 19 deletions

File tree

.github/workflows/tola-build.yaml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,37 @@ jobs:
1010
- name: Checkout
1111
uses: actions/checkout@v6
1212

13-
- name: Set Node.js 24.x
13+
- name: Setup Node.js 24.x
1414
uses: actions/setup-node@v6
1515
with:
1616
node-version: 24
17+
18+
- name: Setup Deno
19+
uses: denoland/setup-deno@v2
20+
with:
21+
deno-version: lts
1722

1823
- name: Install tailwindcss
1924
run: |
2025
npm init -y
2126
npm i tailwindcss @tailwindcss/cli
2227
23-
- name: Tola build
28+
- name: Tola build (data files)
2429
run: |
2530
wget 'https://github.com/tola-rs/tola-ssg/releases/download/v0.6.5/tola-x86_64-linux-static.tar.gz'
2631
tar xzvf tola-*
2732
chmod +x ./tola
2833
ls -lah
2934
PATH="./node_modules/.bin:$PATH" ./tola build
35+
36+
- name: Tag generation
37+
run: |
38+
cd scripts
39+
deno run -A gen-tags.ts
40+
41+
- name: Tola build (final)
42+
run: |
43+
PATH="./node_modules/.bin:$PATH" ./tola build
3044
3145
- name: Upload Artifacts
3246
uses: actions/upload-pages-artifact@v3

content/tags.typ

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#import "/templates/page.typ": page
2+
#import "/utils/helpers.typ" as utils
3+
4+
#show: page.with(title: "home")
5+
6+
#html.h1(class: "text-4xl font-bold text-center mb-8")[all tags]
7+
8+
#let tags = json("/_data/tags.json")
9+
#html.div(class: "flex flex-col gap-2")[
10+
#for tag in tags.keys() {
11+
html.a(href: "/tags/" + tag)[#text("#" + tag)]
12+
}
13+
]

content/tags/tag.typ.tmpl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#import "/templates/tag.typ": tag-listing
2+
3+
#let args = (
4+
tag: "{TAG}"
5+
)
6+
7+
#show: tag-listing.with(..args)

flake.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
inputs.tola.packages.${pkgs.system}.default
2828
tailwindcss_4
2929
typstyle
30+
deno
3031
];
3132
};
3233
};

scripts/gen-tags.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const tagJsonPath = "../public/_data/tags.json"
2+
const templatePath = "../content/tags/tag.typ.tmpl"
3+
const outputRoot = "../content/tags/"
4+
5+
const tags = JSON.parse(Deno.readTextFileSync(tagJsonPath))
6+
const tagNames = Object.keys(tags)
7+
console.log("generating files for", tagNames.length, "tags")
8+
9+
let template = Deno.readTextFileSync(templatePath)
10+
11+
for (const tag of tagNames) {
12+
const newFile = template.replace("{TAG}", tag)
13+
const outputPath = outputRoot + tag + ".typ"
14+
15+
Deno.writeTextFileSync(outputPath, newFile);
16+
console.log("wrote to", outputPath, "for tag", tag)
17+
}

templates/tag.typ

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#import "/templates/base.typ": base, colors
2+
#import "/utils/helpers.typ" as utils
3+
4+
#let tag-listing(tag: none, body) = {
5+
show: base
6+
7+
html.h1(class: "text-4xl font-bold text-center mb-8")[posts tagged '#tag']
8+
9+
let pages = json("/_data/pages.json")
10+
let tags = json("/_data/tags.json")
11+
let postsWithTag = tags.at(tag, default: ())
12+
html.div(class: "flex flex-col items-center")[
13+
#for taggedPost in postsWithTag {
14+
let post = pages.filter(p => p.url == taggedPost.url).at(0)
15+
utils.post-card(post)
16+
}
17+
]
18+
}

utils/helpers.typ

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
// Shared utilities
2-
// Import: #import "/utils/helpers.typ": *
3-
4-
51
#let hr = html.hr(class: "border-text/50 my-4")
6-
72
#let nav-link(href, label) = html.a(
83
class: "text-muted hover:text-accent transition-colors",
94
href: href,
@@ -17,32 +12,22 @@
1712
}
1813
#body
1914
]
20-
// Helper for flex rows.
21-
// We use a safelist comment to ensure Tailwind generates these classes.
15+
2216
// safelist: gap-1 gap-2 gap-3 gap-4 gap-5 gap-6 gap-8
2317
#let flex-row(gap: "4", ..items) = html.div(
2418
class: "flex flex-wrap gap-" + gap + " items-center",
2519
)[#for item in items.pos() { item }]
2620

2721
#let to-string(value) = repr(value)
2822

29-
// ----------------------------------------------------------------------------
30-
// Post Helpers
31-
// ----------------------------------------------------------------------------
32-
33-
// Helper to fetching posts from the virtual JSON file
34-
// - Filters for pages with "/posts/" anywhere in URL (supports path_prefix)
35-
// - Excludes drafts
36-
// - Sorts by date (newest first)
37-
3823
// Helper to render a consistent post card
3924
// - post: The post object from get-posts()
4025
#let post-card(post) = {
4126
let date = post.at("date", default: "")
4227
// Cleaner approach: Wrap the whole card in a block-level anchor tag.
4328
// HTML5 allows block elements (div, h3, p) inside anchor tags.
4429
html.a(
45-
class: "block mb-6 p-4 border border-white/10 rounded-lg bg-surface/50 hover:bg-surface transition-colors no-underline group",
30+
class: "block mb-6 p-4 border border-white/10 rounded-lg bg-surface/50 hover:bg-surface transition-colors no-underline group w-full",
4631
href: post.url,
4732
)[
4833
#html.h3(

0 commit comments

Comments
 (0)