I received an email asking me about how I manage my site. This post walks through the high-level steps of building my site.
There are four major tasks that go into making Take on Rules:
The process is roughly as follows:
- I create an Org-Roam node; in my setup each node is one file.
- Via Ox-Hugo, I export the node to a Hugo content directory.
- In the Hugo directory, I run a series of Rake tasks that:
- extracts and/or relates data
- builds the
- uploads them to my remote host.
- Adds the public
httpurl as a ref on the Org-Roam node.
The following diagram illustrates the data mapping process:
The data files are a mix of hand-written “databases” and derived “databases.”
Examples of the hand-written variety include:
- My Glossary
- Used as the “dictionary” of terms; when writing I reference these entries.
- My Epigraphs
- Used to create well-formed epigraphs with quotation and proper citation. On Sharpening Your Tools has an example of an epigraph.
Examples of the derived variety include the data files that show which pages reference which glossary item and the page that show’s the epigraphs I’ve collected and what posts reference them. I run build tasks to generate these derived files.
For further information about the data files, see Hugo’s documentation on Data Templates.
A Tangent Into The Technical History of My Site
Take on Rules started as a Wordpress site. Then I moved to a Jekyll site hosted on Github. And then to Hugo on Github. And now Hugo hosted on NearlyFreeSpeech.net.
In moving from Wordpress to Jekyll, my site went from a dynamic site to a static build site. All of the pages are uploaded to my hosting server, which serves the pages directly to you.
Out of the box, Hugo and Jekyll provide tools that generate some pages. Hugo’s Taxonomies powers Take on Rules’s Tags, Series, and Licenses pages; as well as the specific sub-pages.
Other pages, such as my Tables page rely on data files. For building those data files, I use Rake. Why? Because my primary language is Ruby. But those Rake files are an amalgam of code; a mix of shell scripts (e.g. Ripgrep), shell invocations of Emacs (e.g.
emacs --eval="(lisp function calls)"), and Ruby class/method calls.
Shifting from Writing in Hugo to Writing in Org-Mode
In years past, I wrote my blog using Markdown. I would store the posts in a repository generated by Hugo. As I further delved into Org-Mode, I shifted to write each post as an Org-Roam node.
The reason for this shift was that I was taking notes in two places:
- posts for my blog.
- notes for myself (via my personal knowledge management system powered by Org-Roam).
I had notes that I intended to publish that referenced notes I didn’t intend to publish.
An example of these two types of notes is in my Session Reports. My session reports are write ups of what happened; they reference characters and places. The notes about characters might include the plots they are setting in motion. Hence I wouldn’t publish them. However I did want to continue to reference them.
My desired state
was is to build and see those relationships between public and “private” notes. I also don’t want to export links to my private notes.
Exporting from Org-Mode to Hugo
The Ox-Hugo package provides amazing tooling for export. I wrote some small refinements for export.
Now when exporting a node from Org-Roam to Hugo, I check each link in the exported document.
For each link that points to an internal Org-Roam node, I check if there’s a reference property.
If there’s a reference, I export an A-tag with an
href to that reference. If there isn’t a reference, I export a SPAN-tag with a
The result, references to public resources show up as links to those resources. And references to internal nodes are named and styled but I don’t link nor export those nodes.
You can read about that functionality in Extending the Ox.
From Hugo to the World
Once things are in the Hugo directory, I have a myriad of scripts that extract metadata from the pages and are then assembled into data files. From those data files aggregate pages are made. One example of those aggregate pages is my List of All Tables.
After all things are assembled, I push the files up to the remote server. And the update the Org-Roam node with the URL for the published page.
This last step now means that whenever I reference the URL for the post in my Org-Roam notes, it will be treated as a link to that Org-Roam note. See Org-roam User Manual’s section on Refs for more details.
My process for blogging continues to evolve. I strive to create semantic content on my public page while also providing optimal utility to myself.
I write and aggregate this information to help facilitate discovery; both recollecting what I wrote but also helping others stumble through my site and learn things.
I keep a list of things that I’d like to adjust in my process.
One of those is to move my glossary and epigraphs fully to Org-Roam. At present my canonical glossary is a
YAML file in a Hugo
data directory (e.g.
In the near term, my plan is to move the glossary entries into my Org-Roam ecosystem and build the
./data/glossary.yml from that. In doing that, I would gain the benefit of:
- Org-Roam references and backlinks
- Private nodes referencing the same object as public posts
- Exposing a more rich “here are my notes for this concept”
To do that requires data migration as well as extending some of Org-Mode’s features.