mirror of
https://github.com/sbrow/thor.git
synced 2026-08-26 11:23:32 -04:00
Compare commits
4 Commits
565115c30c
...
0dc6cc117f
| Author | SHA1 | Date | |
|---|---|---|---|
| 0dc6cc117f | |||
| d10b832f3f | |||
| c3efbf80f0 | |||
| 177117e471 |
@@ -3,8 +3,6 @@
|
|||||||
- Look at the source for 3 template languages that support mustache syntax,
|
- Look at the source for 3 template languages that support mustache syntax,
|
||||||
and see how they implement the tempaltes, then pick the best one. One of them
|
and see how they implement the tempaltes, then pick the best one. One of them
|
||||||
should be Hugo / go.
|
should be Hugo / go.
|
||||||
- [ ] Deal with the favicon
|
|
||||||
- [ ] Icon support.
|
|
||||||
- [ ] robots.txt?
|
- [ ] robots.txt?
|
||||||
- [ ] Evaluate Tufte CSS — borrow sidenote CSS or replace TailwindCSS entirely
|
- [ ] Evaluate Tufte CSS — borrow sidenote CSS or replace TailwindCSS entirely
|
||||||
- Option B: Steal Tufte's sidenote/margin-note CSS (adapt for dark theme), keep TailwindCSS
|
- Option B: Steal Tufte's sidenote/margin-note CSS (adapt for dark theme), keep TailwindCSS
|
||||||
@@ -17,4 +15,3 @@
|
|||||||
- [ ] Nix build integration — main flake runs thor + tailwindcss instead of Hugo
|
- [ ] Nix build integration — main flake runs thor + tailwindcss instead of Hugo
|
||||||
- [ ] Copy-to-clipboard button on code blocks (was in Hugo's custom-head.html)
|
- [ ] Copy-to-clipboard button on code blocks (was in Hugo's custom-head.html)
|
||||||
- [ ] OpenGraph meta tags
|
- [ ] OpenGraph meta tags
|
||||||
- [ ] utteranc.es comments on posts
|
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
ICON_HOME :: `<svg aria-hidden="true" class="hi-svg-inline h-6 w-6" fill="none" height="1em" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" width="1em"><path d="m3 9 9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>`
|
||||||
|
|
||||||
|
ICON_GITHUB :: `<svg aria-hidden="true" class="hi-svg-inline h-7 w-7" fill="none" height="1em" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" width="1em"><path d="M15 22v-4a4.8 4.8.0 00-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35.0-3.5.0.0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35.0 3.5A5.403 5.403.0 004 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18c-4.51 2-5-2-7-2"/></svg>`
|
||||||
|
|
||||||
|
ICON_RSS :: `<svg aria-hidden="true" class="hi-svg-inline h-7 w-7" fill="none" height="1em" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" width="1em"><path d="M4 11a9 9 0 019 9"/><path d="M4 4a16 16 0 0116 16"/><circle cx="5" cy="19" r="1"/></svg>`
|
||||||
|
|
||||||
|
ICON_CHEVRON_UP :: `<svg aria-hidden="true" class="hi-svg-inline h-10 w-10" fill="none" height="1em" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" width="1em"><path d="m18 15-6-6-6 6"/></svg>`
|
||||||
|
|
||||||
|
ICON_STAR :: `<svg aria-hidden="true" class="hi-svg-inline h-3.5 w-3.5 text-yellow-500 align-baseline mr-2" fill="currentColor" height="1em" viewBox="0 0 16 16" width="1em"><path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/></svg>`
|
||||||
+31
-9
@@ -26,9 +26,6 @@ render_site :: proc(pages: []Page, content_path: string, output_dir: string, bas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy static assets (avatar, favicon, etc.)
|
|
||||||
copy_static_assets(content_path, output_dir)
|
|
||||||
|
|
||||||
// Render individual content pages (skip home)
|
// Render individual content pages (skip home)
|
||||||
for page in pages {
|
for page in pages {
|
||||||
if page.type == .Home {
|
if page.type == .Home {
|
||||||
@@ -58,6 +55,13 @@ render_site :: proc(pages: []Page, content_path: string, output_dir: string, bas
|
|||||||
sitemap := generate_sitemap(pages, base_url)
|
sitemap := generate_sitemap(pages, base_url)
|
||||||
write_file(fmt.tprintf("%s/sitemap.xml", output_dir), sitemap)
|
write_file(fmt.tprintf("%s/sitemap.xml", output_dir), sitemap)
|
||||||
|
|
||||||
|
// Copy static assets (avatar, favicon, etc.)
|
||||||
|
copy_static_assets(content_path, output_dir)
|
||||||
|
|
||||||
|
// Generate robots.txt
|
||||||
|
robots := fmt.aprintf("User-agent: *\nAllow: /\nSitemap: %s/sitemap.xml\n", base_url)
|
||||||
|
write_file(fmt.tprintf("%s/robots.txt", output_dir), robots)
|
||||||
|
|
||||||
total := len(pages) + 1
|
total := len(pages) + 1
|
||||||
if !has_home {
|
if !has_home {
|
||||||
total += 1
|
total += 1
|
||||||
@@ -66,17 +70,30 @@ render_site :: proc(pages: []Page, content_path: string, output_dir: string, bas
|
|||||||
}
|
}
|
||||||
|
|
||||||
render_page_html :: proc(page: Page, site_title: string) -> string {
|
render_page_html :: proc(page: Page, site_title: string) -> string {
|
||||||
|
comments := ""
|
||||||
|
if page.type == .Post {
|
||||||
|
comments = `
|
||||||
|
<script src="https://utteranc.es/client.js"
|
||||||
|
repo="sbrow/sbrow.github.io"
|
||||||
|
issue-term="pathname"
|
||||||
|
label="Comment"
|
||||||
|
theme="github-dark"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
async></script>`
|
||||||
|
}
|
||||||
|
|
||||||
body := fmt.aprintf(
|
body := fmt.aprintf(
|
||||||
`<main>
|
`<main>
|
||||||
<article class="prose">
|
<article class="prose">
|
||||||
<h1>%s</h1>
|
<h1>%s</h1>
|
||||||
%s %s
|
%s %s
|
||||||
</article>
|
</article>%s
|
||||||
</main>
|
</main>
|
||||||
`,
|
`,
|
||||||
page.title,
|
page.title,
|
||||||
render_date(page),
|
render_date(page),
|
||||||
page.body_html,
|
page.body_html,
|
||||||
|
comments,
|
||||||
)
|
)
|
||||||
title := fmt.tprintf("%s | %s", page.title, site_title)
|
title := fmt.tprintf("%s | %s", page.title, site_title)
|
||||||
return render_chrome(title, body)
|
return render_chrome(title, body)
|
||||||
@@ -150,6 +167,7 @@ render_posts_html :: proc(pages: []Page, site_title: string) -> string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render_chrome :: proc(page_title: string, body: string) -> string {
|
render_chrome :: proc(page_title: string, body: string) -> string {
|
||||||
|
header := fmt.aprintf(HEADER, ICON_HOME)
|
||||||
return fmt.aprintf(
|
return fmt.aprintf(
|
||||||
`<!DOCTYPE html>
|
`<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@@ -163,8 +181,9 @@ render_chrome :: proc(page_title: string, body: string) -> string {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
%s%s<footer>
|
%s%s<footer>
|
||||||
<a href="https://github.com/sbrow" target="_blank" rel="noopener noreferrer me" title="Github">GitHub</a>
|
<a class="goto-top opacity-0" href="#">%s</a>
|
||||||
<a href="/index.xml" target="_blank" rel="noopener noreferrer me" title="Rss">RSS</a>
|
<a href="https://github.com/sbrow" target="_blank" rel="noopener noreferrer me" title="Github">%s</a>
|
||||||
|
<a href="/index.xml" target="_blank" rel="noopener noreferrer me" title="Rss">%s</a>
|
||||||
<p class="pt-5 prose">Proudly built with <a href="https://odin-lang.org/">Odin</a> and <a href="https://tailwindcss.com/">Tailwindcss</a></p>
|
<p class="pt-5 prose">Proudly built with <a href="https://odin-lang.org/">Odin</a> and <a href="https://tailwindcss.com/">Tailwindcss</a></p>
|
||||||
<p><small>©</small> 2026</p>
|
<p><small>©</small> 2026</p>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -174,8 +193,11 @@ render_chrome :: proc(page_title: string, body: string) -> string {
|
|||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
page_title,
|
page_title,
|
||||||
HEADER,
|
header,
|
||||||
body,
|
body,
|
||||||
|
ICON_CHEVRON_UP,
|
||||||
|
ICON_GITHUB,
|
||||||
|
ICON_RSS,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +205,7 @@ HEADER :: `
|
|||||||
<header>
|
<header>
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="mr-auto"><a href="/">Home</a></li>
|
<li class="mr-auto"><a href="/">%s</a></li>
|
||||||
<li><a href="/ideas/">Ideas</a></li>
|
<li><a href="/ideas/">Ideas</a></li>
|
||||||
<li><a href="/posts/">Posts</a></li>
|
<li><a href="/posts/">Posts</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -202,7 +224,7 @@ render_post_item :: proc(page: Page) -> string {
|
|||||||
}
|
}
|
||||||
star := ""
|
star := ""
|
||||||
if page.is_starred {
|
if page.is_starred {
|
||||||
star = `<span class="text-yellow-500 mr-2">★</span>`
|
star = ICON_STAR
|
||||||
}
|
}
|
||||||
return fmt.aprintf(
|
return fmt.aprintf(
|
||||||
` <li class="flex justify-between"><a href="%s">%s</a><span>%s%s</span></li>`,
|
` <li class="flex justify-between"><a href="%s">%s</a><span>%s%s</span></li>`,
|
||||||
|
|||||||
Reference in New Issue
Block a user