Seth Kushniryk

New Blog!

2019/09/09

If you’re here, then you’ve no doubt noticed the new layout. I’ve completely redone my entire website, including the backend for my blog. In this post I’m going to describe what I changed, how, and why.

0. What was wrong with my old site:

My old website was built using PHP scripts I hacked together along with Cutenews, which is a PHP blog application that is reasonably easy to integrate into a site. The problem with cutenews is that it’s got a proprietary license. It’s also overcomplicated by useless features, yet at the same time it places many constraints on the formatting of the posts and the integration with the website. My PHP scripts that held it all together were also a security concern. Sometime soon I’ll write a post about what happened with my contact form, which I unwisely wrote myself.

The other component of my old website was Twitter Bootstrap, which is a framework for building responsive websites. Unfortunately, Bootstrap is also huge and complex, and full of extra javascript and CSS that I would never need. Both Bootstrap and Cutenews were unsuitable for a personal website/blog.

Due to my piecemeal construction of the old site, the code was ugly, and tweaked just enough to work. Multiple years of little undocumented tweaks made it hard for me to remember how things worked and why. I was unhappy with how the site looked, but didn’t have the time to deal with the aftermath of a change, as each small change was sure to break something.

1. Deciding on a replacement:

I had decided long ago that I needed to replace the site, but I spent about a year trying to figure out what to replace it with. My first idea was to rewrite everything in a Python Flask app using the Flask-Blogging extension. This had the benefits of being simpler, flexible, and not PHP. One disadvatage was that it required a lot of extra code to make it work in a usable way, and though I knew Python better than PHP, this wasn’t exactly the low-maintenance solution I wanted.

When I looked for more “out of the box” solutions, I came across Known. This was better than everything I’d seen so far, but still overcomplicated, and written in PHP. It also had an unnecesarrily “startup-y” look to it, which is boring, and not what I was looking for. It was basically a simpler take on Wordpress without good documentation of the internals.

At this point, I had come up with some requirements:

2. What I went with:

In my search for static site generators, I came across Hugo, a simple static site generator written in Go. It can take various formats like markdown and org-mode files and convert them to static pages. Hugo seemed like the perfect start, I just needed a theme. I started off looking at ways to incorporate Bootstrap or Pure.css into a Hugo theme, but I couldn’t find anything that really went nicely together.

Eventually, I found XMin. I was impressed by what could be done with around 130 lines of code. The CSS was simple and readable, and the site was easy to navigate and not flashy. Being written by an RStudio developer, $\rm\LaTeX$ support was advertised on the front page. The site also worked without modifications on my phone. I decided to base my new site on this theme.

3. What I changed:

The theme wasn’t perfect; I wanted to change a fair bit, but the simplicity of the code made it extremely easy to modify. Every change was a minor one, but the end result is a site that looks quite a bit different, personalised just the way I want. The first change was to make the <hr> tags solid. The dotted lines are too stereotypical of a github.io page.

After that, I spent hours trying to figure out waht to do with the links at the top. I didn’t quite like them as they were. I started out by making them darken on mouseover. I’ve always found that to be a nice UI feature. I also changed the text in the links to be always black; I didn’t like the look of some blue, some purple.

Perhaps the biggest change was the font. The fonts in the original theme were ugly. Originally, I intended to go with Chicago, which I know is even uglier, but I had a copy of the font from an old Mac System 7 disk, and it gave the site a personal touch. Unfortunately there was no good way to get a license to use the font, so I decided against it. I ultimately decided to go with Computer Modern, the default $\rm\LaTeX$ font, which has the nice effect of unifying the text with any math I put in. The monospace font is also from the Computer Modern family, though I am still debating whether or not I like it. Syntax highlighting for code blocks is done with PrismJS, which was very easy to add into the theme.

The rest of the changes have just been little configuration tweaks, like putting the category list below each post, changing the main menu buttons, and paginating the posts on the Posts page. One that seems big visually, but was done with just a little bit of CSS was putting frames and shadowboxes around all the pictures. This was important to me because a lot of my blog is pictures and I want them to pop out of the page. There are still a couple more tweaks to do. The biggest one is making the subscribe link work like a regular rss link using type="application/rss+xml"; I’m still figuring out how to do that with Hugo.

4. A new workflow:

Writing posts on my old site was reasonably easy, I just logged in, wrote the post, and hit “Publish”. Uploading images was a pain through the web interface, and it would often time out. For this site, I just drop the images in a content folder, write the post in markdown using an emacs mode called easy-hugo, and then I run a script I wrote to compile the site in Hugo, commit and push to git, and rsync it to the server all in one go. The script is at the end of this post. I would like to open source all of my changes, but I didn’t use git while I did the bulk of my early changes, so I don’t have any patches for XMin. For now, I’ll offer the source upon request.

Since I’ve done everything but show off the $\rm\LaTeX$ capability, here’s the Black-Scholes equation:

$$\frac{\partial V}{\partial t} + \frac{1}{2}\sigma^2S^2\frac{\partial^2V}{\partial S^2}+rS\frac{\partial V}{\partial S}-rV=0$$

#!/bin/bash

#deploy.sh: takes one argument: commit message in quotes
#Example: $ ./deploy.sh "commit message goes here"

hugoroot="/home/hugo/site"
rsynclocation="user@server:/path/to/webroot/"

# Send errors to stderr
function STDERR () {
cat - 1>&2
}

# Check for git commit message:
if [ -z "$1" ]; then
    echo "Error: No commit message given" | STDERR
    exit 1
fi

# Set the working directory to the hugo root:
echo "Info: Finding hugo root"
pushd $hugoroot
if [ $? -ne 0 ]; then
    echo "Error: Hugo root not found!!" | STDERR
    exit 1
fi

# Run hugo to build the site:
echo "Info: Running hugo"
hugo -v

# Commit and ask to push to git if build was successful, otherwise fail
if [ $? -eq 0 ]; then
    git add -A
    git commit -m "$1"

# Ask whether to push:
    valid=false;
    push=false;
    while [ "$valid" = false ]; do
	read -p "Push to git (y/n)? " choice
	case "$choice" in 
	    y|Y )
		valid=true
		echo "Info: Pushing to git."
		push=true
		;;
	    n|N )
		valid=true
		echo "Info: Not Pushing to git."
		;;
	    * )
		echo "Error: invalid input" | STDERR
		;;
	esac
    done
else
    echo "Error: Hugo failed!!"
    exit 1
fi

# Do the push if asked
if [ "$push" = true ]; then
    git push
    if [ $? -ne 0 ]; then
	echo "Error: git push didn't exit successfully" | STDERR
	valid=false
        while [ "$valid" = false ]; do
	read -p "Continue without pushing to git (y/n)? " choice
	case "$choice" in 
	    y|Y )
		valid=true
		echo "Info: Moving on without pushing to git."
		;;
	    n|N )
		valid=true
		echo "Error: Exiting due to git push failure" | STDERR
		exit 1
		;;
	    * )
		echo "Error: invalid input" | STDERR
		;;
	esac
	done
    fi
fi

# Upload to server:
valid=false
serverupload=false
while [ "$valid" = false ]; do
    read -p "Upload to server webroot (y/n)? " choice
    case "$choice" in 
	y|Y )
	    valid=true
	    echo "Info: Uploading to server via rsync."
	    sdfupload=true
	    ;;
	n|N )
	    valid=true
	    echo "Info: Skipping upload to server"
	    exit 1
	    ;;
	* )
	    echo "Error: invalid input" | STDERR
	    ;;
    esac
done

if [ "$serverupload" = true ]; then

    success=false
    while [ "$success" = false ]; do
	rsync --recursive --progress --delete public/* $rsynclocation
	if [ $? -ne 0 ]; then
	    echo "Error: Upload to server failed!" | STDERR
	    valid=false
	    while [ "$valid" = false ]; do
		read -p "Try again (y/n)? " choice
		case "$choice" in
		    y|Y )
			valid=true
			echo "Info: Trying again."
			;;
		    n|N )
			valid=true
			echo "Info: Skipping upload to server"
			success=true
			;;
		    * )
			echo "Error: invalid input" | STDERR
			;;
		esac
	    done
	else
	    success=true
	fi
    done
fi

popd

Categories: Computer Linux