Skip to content

Commit eef461b

Browse files
committed
feat: tola v0.7.0
1 parent e8525f6 commit eef461b

38 files changed

+944
-189
lines changed

.github/workflows/tola-build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
2828
- name: Tola build (data files)
2929
run: |
30-
wget 'https://github.com/tola-rs/tola-ssg/releases/download/v0.6.5/tola-x86_64-linux-static.tar.gz'
30+
wget 'https://github.com/tola-rs/tola-ssg/releases/download/v0.7.0/tola-x86_64-linux-static.tar.gz'
3131
tar xzvf tola-*
3232
chmod +x ./tola
3333
ls -lah

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ npm-debug.*
33
*.log
44
.DS_Store
55
public/
6-
.direnv/
6+
.direnv/
7+
.tola/
8+
content/tags/*.typ

assets/styles/tailwind.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
22
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap');
3+
34
@import 'tailwindcss';
45

56
/* Tailwind CSS v4 configuration */

components/layout.typ

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Layout components
2+
// Import: #import "/components/layout.typ" as layout
3+
4+
#import "/utils/tola.typ": cls
5+
6+
/// Horizontal rule with default styling
7+
#let hr = html.hr(class: "border-surface my-8")
8+
9+
10+
/// Flex row container with configurable gap
11+
/// safelist: gap-1 gap-2 gap-3 gap-4 gap-5 gap-6 gap-7 gap-8
12+
#let flex-row(gap: 4, ..items) = html.div(
13+
class: cls("flex flex-wrap items-center", "gap-" + str(gap)),
14+
)[#for item in items.pos() { item }]
15+
16+
17+
/// Flex column container with configurable gap
18+
/// safelist: gap-1 gap-2 gap-3 gap-4 gap-5 gap-6 gap-7 gap-8
19+
#let flex-col(gap: 4, ..items) = html.div(
20+
class: cls("flex flex-col", "gap-" + str(gap)),
21+
)[#for item in items.pos() { item }]
22+
23+
24+
/// Grid container
25+
/// safelist: grid-cols-1 grid-cols-2 grid-cols-3 grid-cols-4
26+
#let grid(cols: 2, gap: 4, ..items) = html.div(
27+
class: cls("grid", "grid-cols-" + str(cols), "gap-" + str(gap)),
28+
)[#for item in items.pos() { item }]

components/ui.typ

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// UI components
2+
// Import: #import "/components/ui.typ" as ui
3+
4+
#import "/utils/tola.typ": cls
5+
#import "/components/layout.typ" as layout
6+
7+
/// Navigation link
8+
#let nav-link(href, label) = html.a(
9+
class: "text-muted hover:text-accent transition-colors",
10+
href: href,
11+
)[#label]
12+
13+
/// Tag badge
14+
#let tag(name) = html.span(
15+
class: "px-2 py-1 text-xs bg-surface rounded text-accent",
16+
)[#name]
17+
18+
/// Card container
19+
#let card(title: none, body) = html.div(class: "p-4 bg-surface rounded-lg")[
20+
#if title != none { html.h3(class: "font-semibold text-accent mb-2")[#title] }
21+
#body
22+
]
23+
24+
/// Post card for blog listings
25+
#let post-card(post) = {
26+
let date = post.at("date", default: "")
27+
html.a(
28+
class: "block mb-6 p-4 border border-white/10 rounded-lg bg-surface/50 hover:bg-surface transition-colors no-underline group",
29+
href: post.permalink,
30+
)[
31+
#html.h3(class: "text-xl font-semibold mb-2 group-hover:text-accent transition-colors")[
32+
#post.title
33+
]
34+
35+
#layout.flex-row(
36+
gap: 4,
37+
html.span(class: "text-sm text-muted")[#date],
38+
..post.at("tags", default: ()).map(t => tag(t)),
39+
)
40+
41+
#if post.at("summary", default: none) != none {
42+
html.p(class: "mt-2 text-muted")[#post.at("summary")]
43+
}
44+
]
45+
}
46+
47+
/// Side-by-side showcase card: source code + rendered output.
48+
#let showcase-demo(
49+
title: none,
50+
description: none,
51+
code: none,
52+
preview: none,
53+
code-label: "Typst Code",
54+
preview-label: "Rendered Output",
55+
) = {
56+
assert(title != none, message: "showcase-demo: `title` is required")
57+
assert(code != none, message: "showcase-demo: `code` is required")
58+
assert(preview != none, message: "showcase-demo: `preview` is required")
59+
60+
html.section(
61+
class: "my-8 rounded-lg border border-white/10 bg-gradient-to-br from-slate-900/80 via-slate-900/50 to-cyan-950/20 p-4 sm:p-6",
62+
)[
63+
#html.div(class: "mb-4")[
64+
#html.h3(class: "text-lg sm:text-xl font-semibold text-cyan-300")[
65+
#title
66+
]
67+
#if description != none {
68+
html.p(class: "mt-1 text-sm text-slate-300")[
69+
#description
70+
]
71+
}
72+
]
73+
74+
#html.div(class: "grid gap-4")[
75+
#html.div(class: "rounded-lg border border-white/10 bg-slate-950/70 overflow-hidden")[
76+
#html.div(class: "border-b border-white/10 px-3 py-2 text-xs uppercase tracking-wide text-slate-400")[
77+
#code-label
78+
]
79+
#html.div(class: "p-3 text-sm")[
80+
#code
81+
]
82+
]
83+
84+
#html.div(class: "rounded-lg border border-cyan-500/30 bg-surface/40 overflow-hidden")[
85+
#html.div(class: "border-b border-cyan-500/20 px-3 py-2 text-xs uppercase tracking-wide text-cyan-300")[
86+
#preview-label
87+
]
88+
#html.div(class: "p-3 text-sm")[
89+
#preview
90+
]
91+
]
92+
]
93+
]
94+
}

content/index.typ

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#import "/templates/page.typ": page
22
#import "/utils/helpers.typ" as utils
3+
#import "@tola/pages:0.0.0": pages
34

45
#show: page.with(title: "home")
56

@@ -49,12 +50,11 @@ In the near future I intend on exploring embedded hardware & RF with some home-a
4950
#utils.hr
5051

5152
= recent posts
52-
#let pages = json("/_data/pages.json")
5353
#let posts = (
54-
pages
54+
pages()
5555
// filter 'all posts' out
5656
.filter(p => p.title != "posts")
57-
.filter(p => "/posts/" in p.url)
57+
.filter(p => "/posts/" in p.permalink)
5858
.filter(p => p.at("draft", default: false) == false)
5959
.sorted(key: p => p.date)
6060
.rev()

content/posts.typ

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#import "/templates/page.typ": page
22
#import "/utils/helpers.typ" as utils
3+
#import "@tola/pages:0.0.0": pages
34

45
#show: page.with(title: "posts")
56

67
= all posts
7-
#let pages = json("/_data/pages.json")
88
#let posts = (
9-
pages
9+
pages()
1010
// filter this page out
1111
.filter(p => p.title != "posts")
12-
.filter(p => "/posts/" in p.url)
12+
.filter(p => "/posts/" in p.permalink)
1313
.filter(p => p.at("draft", default: false) == false)
1414
.sorted(key: p => p.date)
1515
.rev()

content/posts/cloudflare-warp.typ

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#import "/templates/post.typ": post
2-
#import "/utils/helpers.typ" as utils
2+
#import "/utils/helpers.typ": parse-date
33

44
#let args = (
55
title: "warp madness",
6-
date: "2025-09-04",
6+
date: parse-date("2025-09-04"),
77
author: "amy erskine",
88
summary: [trials and tribulations of cloudflare warp],
99
tags: ("networking", "cloudflare"),

content/posts/entra-user-move.typ

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#import "/templates/post.typ": post
2-
#import "/utils/helpers.typ" as utils
2+
#import "/utils/helpers.typ": parse-date
33

44
#let args = (
55
title: "moving on-prem users to Entra",
6-
date: "2025-09-05",
6+
date: parse-date("2025-09-05"),
77
author: "amy erskine",
88
summary: [how to migrate your Active Directory users],
99
tags: ("tidbits", "microsoft"),
@@ -52,7 +52,7 @@ $body = @{
5252
Invoke-MgGraphRequest -Method PATCH -Uri "https://graph.microsoft.com/v1.0/users/$userId" -Body $body
5353
```
5454

55-
This will **break** the on-premise link. Be sure you're operating on the right accounts.
55+
This will *break* the on-premise link. Be sure you're operating on the right accounts.
5656

5757
Wait for the Exchange mailboxes to get assigned, then verify they are all set to SharedMailbox mode:
5858
```powershell

content/posts/fortinet-sslvpn-stuck.typ

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#import "/templates/post.typ": post
2-
#import "/utils/helpers.typ" as utils
2+
#import "/utils/helpers.typ": parse-date
33

44
#let args = (
55
title: "SSLVPN stuck at 98%",
6-
date: "2025-08-11",
6+
date: parse-date("2025-08-11"),
77
author: "amy erskine",
88
summary: [troubleshooting Fortinet's SSLVPN],
99
tags: ("tidbits", "networking", "fortinet"),

0 commit comments

Comments
 (0)