First and foremost, this blog is also available over Gemini,
What is Gemini ?
Gemini is a protocol which strives to replace parts of the Web (HTTP, that you're currently using). Essentially, it's a stripped-down version of the modern web, without interactive or colorful pages. But also without tracking and (lots of) security holes.
Gemini is limited to text-only content, and isn't interoperable with HTTP. Well, you can't have everything.
I'm not here to decide whether or not Gemini is actually a good idea, but I want to provide content to both Gemini and the HTTP web.
The first version fetched the content directly from the SQLite database of a Ghost installation. The issue is that the first database access would lock up Ghost...
So instead I used the Content API, which has the benefit of decoupling the gemini server from the ghost server, and is more resilient against any database schema changes, and also works with MySQL installations.
How it works
On startup, the server fetches all the posts from Ghost, and converts the HTML into Gemtext. The output is cached in RAM for better performances. Every hour, the server fetches all the posts again, in order to reflect any update.
Additionally, there is a webhook endpoint that you can connect to the Site Rebuild Ghost Webhook (which will trigger on any change), or you can also connect it to multiple webhooks (post created, updated ...) for more granularity.
The homepage provides a feed of all the posts, with the excerpt and date. You can customize this page with a Go template (
index.tpl). It fetches the blog title, description and navigation and integrates it into the homepage.
The search feature is availably over Gemini and HTTP. It uses the awesome Bleve search library, which provides full-text search.
There is a HTTP API, with CORS headers matching the Ghost content API domain, so you can call it from the Ghost frontend.