diff --git a/AGENTS.md b/AGENTS.md
index 406f6fc..24d2c51 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -250,6 +250,7 @@ render(tmpl, data, partials) → render_nodes (walks flat node array against con
## Design decisions
+You may never, *ever* remove `TODO:` or `FIXME:` comments. Those are for humans, not machines.
See `HUGO.md` for analysis of why thor doesn't need Hugo's shortcode context isolation.
See `mustache/PARTIAL_INDENT.md` for whitespace handling analysis.
See `mustache/SPEC.md` for the original implementation specification.
diff --git a/TODOS.md b/TODOS.md
index 9186c89..8ccc123 100644
--- a/TODOS.md
+++ b/TODOS.md
@@ -1,7 +1,11 @@
+- [ ] Integrity hash
+ - Allows users to verify their output didn't change after upgrading to a new version
- [ ] Content-hash fingerprinting for CSS and JS cache busting
- [ ] Clean up the default layouts
- [ ] Memory
- [ ] Not sure whether to use temp allocator or site_allocator in opengraph.odin.
+ - [ ] Not sure whether to use temp allocator or site_allocator in `site_load_content`.
+ - [ ] Might not need to allocate in `strip_html_tags`
- [ ] Performance
- [ ] See if we can disable bounds checks in `write_indented` and elsewhere.
- [ ] Instead of loading the site fresh each time in watch mode, create a
@@ -9,16 +13,18 @@
- [ ] Only publish referenced assets.
- [ ] Split `load_page` into frontmatter-parse + body-process phases so draft pages can skip the markdown pipeline entirely
- [ ] Use spall to find ways to reduce run time.
-- [ ] mustache data keys for opengraph, etc.
+- [ ] Open Graph
+ - [x] mustache data keys for opengraph, etc.
+ - [ ] OpenGraph meta tags — verify all fields match production site
+ - [ ] set opengraph tags / description automatically if unset. (Like hugo does)
+ - [ ] can't set avatar.jpg directly in `og_init`.
- [ ] Author should be a struct adhering to https://schema.org/author
- [ ] Block attributes on code fences (`{ #ex-1 }`) — hello-world.md
- [ ] include-code shortcode (`{{< include-code ... >}}`) — i-ported-fd-to-odin
- [ ] follow symlinks in `scan_content`?
- [ ] ensure sidenote numbers render in display order and not in declaration order.
-- [ ] OpenGraph meta tags — verify all fields match production site
- [ ] Add Opt-in deflist support.
- [ ] We need to be able to do `Year_Section` in a non-magical, unprivileged way. See [PLAN.md](PLAN.md) for computed properties approach.
-- [ ] set opengraph tags / description automatically if unset. (Like hugo does)
- [ ] Table of contents support.
- [ ] prefixing every log message with `thor: ` is silly
- [ ] Nav items should be active when the current page is selected.
diff --git a/content.odin b/content.odin
index df60038..70a3490 100644
--- a/content.odin
+++ b/content.odin
@@ -13,6 +13,7 @@ Page :: struct {
slug: string,
layout: string,
permalink: string,
+ url: string,
title: string,
description: string,
date: string,
@@ -28,6 +29,10 @@ Page :: struct {
site_load_content :: proc(site: ^Site) {
site.pages = make([dynamic]Page, 0, 8, site_allocator(site))
scan_content(site, site.content_dir, "")
+
+ for &page in site.pages {
+ page.url = fmt.tprintf("%s%s", site.base_url, page.permalink)
+ }
}
// scan_content walks the content directory. At the root level (section=""),
diff --git a/feed.odin b/feed.odin
index d17e483..bc22c95 100644
--- a/feed.odin
+++ b/feed.odin
@@ -40,18 +40,16 @@ generate_rss :: proc(site: ^Site) -> string {
fmt.aprintf(
`%s
-%s%s
+%s
%s
-%s%s
+%s%s
`,
xml_escape(page.title),
- site.base_url,
- page.permalink,
+ page.url,
pub_date,
- site.base_url,
- page.permalink,
+ page.url,
xml_escape(page.body_html),
),
)
@@ -78,7 +76,7 @@ generate_sitemap :: proc(site: ^Site) -> string {
}
strings.write_string(
&sb,
- fmt.aprintf("%s%s%s\n", site.base_url, page.permalink, lastmod),
+ fmt.aprintf("%s%s\n", page.url, lastmod),
)
}
diff --git a/opengraph.odin b/opengraph.odin
index 48b207e..dcf0cde 100644
--- a/opengraph.odin
+++ b/opengraph.odin
@@ -28,7 +28,7 @@ og_init :: proc(site: Site) -> Open_Graph {
og_for_page :: proc(site: Site, page: Page, base: Open_Graph) -> Open_Graph {
og := base
is_article := page.section != ""
- og.url = fmt.tprintf("%s%s", site.base_url, page.permalink)
+ og.url = page.url
og.title = strip_html_tags(page.title, context.temp_allocator)
og.type = "article" if is_article else "website"
og.is_article = is_article