Blog
Mon Jan 6 16:37:53 2020 +1100Starting a blog
A number of things have had me thinking about doing web stuff. I've re-done my site and am making myself start blogging again. I've got a few things that I want to talk about, including AI and game playthroughs.
Where better to begin that the website itself.
My website is all pretty static. At first I just needed a video portfolio site so that I could show people my work, so my site started as a digital business card and some links off to YouTube.
I do realise that these days people use Facebook, LinkedIn, or other social media for this stuff…
I've since added in a blog where I can talk about projects I'm working on, a piece of interactive fiction, and am planning on expanding with solo roleplaying playthroughs and errata.
I've put together a system that allows me to write in Org mode, export to HTML, and then check it into a git repo to push it to my website when I want to publish it. The project uses GNU Make to build the site, and a git hook to manage publishing.
The blog's design
The question is: what exactly do I need my blog for? I need to be able to write posts, and people need to be able to read them. Readers also need to be able to browse between posts, and follow the blog if they are interested in more.
I'm not currently trying to build a community, so I don't need users to interact with the site. This means that everything can be done server side, and then served up statically, which fits how my website was already set up.
I also want it to be easy to maintain; I only want to have to worry about what I'm writing, not having to update it manually every time that I want to publish something.
So my requirements are:
- the ability to write posts
- that have a title
- and a date
- readers must be able to read posts
- starting at the most recent post
- one post at a time
- readers must be able to navigate the blog by
- going to the next page
- going to the previous page
- via an index
- readers must be able to follow the blog via rss
- It must be easy to maintain.
Org mode → blog
I quite like writing in Org mode, and it has an HTML export option, so I decided to make use of that, Git, and GNU Make, to build everything and get it to the server with a minimal amount of work. Org mode is a mode for Emacs, that formats text nicely, does tables with formulas, knows about code to the point where you can use it for litterate programming, and task management.
Writing and exporting to HTML in Org mode is incredibly straight forward.
When I'm done with a post, it's as simple as C-c C-e h h, and I've got
an HTML file saved along with my Org file.
Now, those HTML files are full of inline CSS, so it takes a bit
of regex magic with sed to clean it up. I'm also only interested in the
contents so I find where they start, read the file from there using tail,
and drop the end with sed because I'm already using it to clean up the
HTML.
tail --line=+$(grep -ni 'h2 id' "$1"| sed 's/:.\+//; 1q') "$1" | sed -e 'list of substitutions to turn styles into classes' \ -e 'extra substitutions for clean up' \ -e 'match the end and stop reading' \ -e 'extra escapes for classes I want to keep.'
It is possible I'll want to change this date to be the day the file is
merged into master, which I should be able to find with git log, but
I wont have to worry about that until I start wanting to edit posts.
Now, I just have to call that for every HTML file in my blog directory.
I can order them by the modified date, which I can pull out with stat,
and use the filename as the post title. I really don't need to track the
author, as it is my blog, not a public site. If the need ever arises, I
guess I can do that with git, but it isn't something I need to think about
right now.
date=$(date -d \ "`stat \"$1\" |grep Modify | cut -f 2- -d ' '`"\ +'%a, %d %b %Y %H:%M:%S %z')
When going through each of these, however, I do need links to the next article, and previous articles. To get those, I can use the index.
The index
I do think I will want to come back and add the first paragraph, or sentence of each post, and pretty print them, to build a sperate front page, but for now, the index will do.
Processing the index is pretty easy. Using my rules about post time, I can sort all the HTML files in my blog by date, and then add them to a list, and save that to an index page. Stick the date for each post in the list as well, and people can easily browse to where ever they want.
find blog -iname "*.html" -type f -printf '%T@ %p\n' |\ sort -nr |\ cut -f 2- -d " " |\ while read file do link=$(echo "$file" | sed -e 's/.\+\///') title=$(echo $link | sed -e 's/_/ /g' \ -e 's/.html//'\ -e 's/\([A-Z]\)/ \1/g') date=$(date -d \ "`stat \"$file\" |grep Modify | cut -f 2- -d ' '`"\ +'%a, %d %b %Y') echo "<li>$date<a ...>$title</a></li>" >> index.html done
Once the index is done, to get the next and previous links for each
individual page, I can use grep to pull the page I'm processing from
the index, along with the next or previous page; drop the page I'm on;
and then use that to make links.
next=$(tail --line=+$headerlength dist/blog/index.html |\ grep '<li>' |\ grep "$title" -B 1 |\ sed 1q) prev=$(tail --line=+$headerlength dist/blog/index.html |\ grep '<li>' |\ grep "$title" -A 1 |\ tail -n 1) [ -z "`echo $prev | grep \"$title\" `" ] && \ echo '<a ...>Prev</a>' >> $outfile [ -z "`echo $next | grep \"$title\" `" ] && \ echo '<a ...>Next</a>' >> $outfile
RSS
When I get around to it, I can use this same logic to build a rolling blog page, with the first 10 items, so that readers can get more than the one article at a time.
While I was at it, I built another script that got the last 10 pages and stuck them in RSS. It was as simple as getting an existing RSS template (thank you Luke Smith) then writing a shell script that made RSS items.
This is the bit that is likely to have issues as I didn't bother learning about RSS at all, and just built XML that fit Luke's template.
Make and Git
Now, the site has started to get a bit complex. I've also been building
some other things in the same space, so I've got a more and more complex
project directory. I also need to be certain of build order with some
of these steps, so I'm leaning on my old friend make.
Writing a Makefile is pretty simple once you know the syntax, and its
pretty easy to build a number of different rules. You give it rules to
build all the individual components, link them all together, and then
set up rules for deployment.
.PHONY: all dev clean all: $(BLOG_DIR)/index.html $(BLOG_FILES) $(BLOG_DIR)/index.html clean: rm -rf .$(DIST_DIR) dev: cp -rfv .$(DIST_DIR) $(DEV_SRV) $(BLOG_DIR)/index.html: $(BLOG_DIR) $(SRC_DIR)/*.html bin/build.sh ./bin/build.sh $(BLOG_DIR)/rss.xml: $(BLOG_DIR) $(SRC_DIR)/*.html bin/rss.sh ./bin/rss.sh $(BLOG_DIR)/%.html: $(SRC_DIR)/%.html ./bin/blog.sh $<
$ make clean && make && sudo make dev
This is a simple example of how I build the site and deploy it to my dev environment.
I can then hook this into git to handle deploying to prod. By putting a remote on my web server, I can stick a hook in it to build the site and deploy it into production, making deploying as simple as:
$ git push prod
And then here we are.