From ac43ab1e5aa4451fe56bc684d88f4e14f5dbaf22 Mon Sep 17 00:00:00 2001 From: Spencer Brower <6729162+sbrow@users.noreply.github.com> Date: Sun, 19 Jul 2026 12:01:55 -0400 Subject: [PATCH] chore: Url now stored on page. --- AGENTS.md | 1 + TODOS.md | 12 +++++++++--- content.odin | 5 +++++ feed.odin | 12 +++++------- opengraph.odin | 2 +- 5 files changed, 21 insertions(+), 11 deletions(-) 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