Hello, Astro
The Gobbler blog is powered by Astro. This website used to be powered by Ghost. But I like consistency, so this website is now powered by Astro as well.
With the help of Claude, all posts have been moved over while maintaining their original guids for RSS readers, all images downloaded from Ghost, all historical WordPress and Ghost HTML stripped, and all code blocks have been correctly indented 1.
This move means membership and newsletters have been retired. Everything that was previously gated by membership barriers is now available to all. For anyone concerned, Ghost will delete all data around the start of April. So sad.
Tangentially related to all this website work, I have discovered something new 2 (at least new to me): Universally Unique Lexicographically Sortable Identifiers (or ULIDs). They are kind of like UUIDs but sortable and decodable. In previous static sites where posts have had front matter, I’ve always used the post slug or a random UUID as a post identifer for feeds, but ULIDs seem to serve this purpose better. This post, for example, has a unique ID of 01KKC42KAQ8SWA4FTXVGWKJCKE and you can decode that at ulid.page. 3
For those that are interested, I create a new post by running npm run new "Blog Title", which runs this node scripts/new-post.mjs, which leads to this:
#!/usr/bin/env node
/**
* Creates a new post with a ULID postId.
*/
import { writeFile } from 'fs/promises';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { ulid } from 'ulid';
const __dirname = dirname(fileURLToPath(import.meta.url));
const POSTS_DIR = join(__dirname, '../src/content/posts');
const title = process.argv[2];
if (!title) {
console.error('Usage: node scripts/new-post.mjs "Post Title"');
process.exit(1);
}
const slug = title
.toLowerCase()
.replace(/[^\w\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-')
.trim();
const id = ulid();
const now = new Date();
const date = now.toISOString();
const datePrefix = now.toISOString().slice(0, 10);
const filePath = join(POSTS_DIR, `${datePrefix}-${slug}.md`);
const content = `---
title: "${title}"
postId: "${id}"
date: ${date}
tags: []
excerpt: ""
---
`;
await writeFile(filePath, content);
console.log(`Created: src/content/posts/${datePrefix}-${slug}.md`);
console.log(`postId: ${id}`);
Much easier than manually crafting front matter.
Footnotes
-
This took about an hour. ↩
-
via Jon Sterling’s blog. ↩
-
Nice! And, if you can’t tell, I’m excited to have footnotes working again. ↩