Or: ‘How I Learned to Stop Worrying and Love the Code’
There are whole buch of ‘How To’ blogs on the Interwebs about moving from WordPress to a Static Site Generator (SSG).
This is not another one of those, it’s more my Notes and Thoughts.
First, Why NOT?
I’m not really interested in the recent WordPress shenanigans.
As a self-hoster, one petty millionaire being cross at another millionaire doesn’t affect me in the slightest.
This is not the reason that I made the move.
So, Why?
There are a number of reasons why.
This site only really existed as a vehicle for me the learn about WorldPress, and I feel as if I’ve come to the end of that journey.
I’d also noticed something else, my writing had become SEO oriented; I was becoming transfixed on getting all the Yeost SEO green dots for each post.
I was losing my writing style to please the Google Gods and I didn’t like that.
I wanted to learn something new.
I’m very much of the midset “everything is working now; time to change it”.
There is a longer term plan to offload my static sites onto my old SheevaPlug which currently resides in the ‘Cupboard of Forgotten Tech’ , so this is the first step on that journey.
Static sites are blazingly fast.
Exporting WordPress Content
I tried both:
The first requires downloading, unzipping and adding to the /wp-content/plugins/
folder.
The second can either be installed as a plugin; or downloaded, unzipped and placed in the /wp-content/plugins/
folder.
More tools can be found here .
For my usage the Jekyll exporter worked better.
Creating Markdown Content
By far the biggest time sink was cleaning up the export.
Yes, both of the above produced usable Markdown.
Yet:
- WordPress
html
artifacts remained - Images were in a weird folder
- Images had lost their
alt
text - Generally it was all a bit of a mess
All of the above and a bunch of other things I can’t remember needed addressing before I was happy with the Markdown.
It was essentially a long find and replace
few hours.
The process did however afforded me the opportunity to do a bit of light editing (read: get rid of some of the SEO chasing I’d done in the past).
Stuff I Don’t Like
There is one thing that I don’t really like about static sites, and that’s where the content ends up in relation to the final URL.
In the development enviroment all of the content goes under /content/posts/
.
This, I like; it’s tidy and uncluttered.
However, when deploying to the web server this hierarchy is replicated, meaning that my content ends up in https://tld/posts/my-post.html
.
This, I don’t like.
I completely understand why this happens.
I completely understand how having a database prevents this happening.
I also understand that I can take out the /posts/
portion of the URL by editing the [permalinks]
in the hugo.yaml
config file.
Unfortunately that leads to everything being in the server’s root folder; which is untidy and cluttered.
I should probably look at creating an nginx rewrite
rule or something.
An Inelegant nginx Rewrite Rule
So, I cobbled together the below, while I look for a one line regex rewrite
rule:
# 0001
location /googleaiy-raspberrypi-scroll-phat/ {
rewrite ^/googleaiy-raspberrypi-scroll-phat/ /posts/2018/04/googleaiy-raspberrypi-scroll-phat/ break;
}
# 0002
location /refurbishing-a-picade/ {
rewrite ^/refurbishing-a-picade/ /posts/2018/10/refurbishing-a-picade/ break;
}
My Current Workflow
The Internet told me that a good chunk of time would be sunk into developing the new way of working.
Yep, this turned out to be true.
Not least of all:
- Getting content to the web server with the correct permissions
- Backing up the current content
So, naturally I wrote a bash script that does the following:
- Stop the Hugo dev-server
- chown the remote web server directory (take ownership)
- Remove any existing content on the remote web server
- Remove any existing local Hugo ‘/public’ content
- Build the new local Hugo website
- Copy the Hugo ‘/public’ content to the remote web server
- chown the remote web server directory (give ownership to www-data)
- Backup (rsync) the working directory
- Clear out the Hugo generated ‘/public’ folder before syncing (no need to store this in Forgejo)
- Push ‘/path/to/git/hugo/’ to Forgejo
- Start the Hugo dev-server
The Deployment Script
deploy.sh
This is linked to an alias
in my .bashrc
file so that I can simply type ‘Deploy_CT_Current’ in a Termininal, and it goes off and does its thing.
In a Terminal:
nano .bashrc
Add:
# Add deploy alias(s) for Hugo
alias deploy="bash /path/to/script/deploy.sh"
Then reload .bashrc
.
source ~/.bashrc
Feel free to chop this up and season to taste:
#!/bin/bash
# Functions
nuke_hugo () {
clear;
echo "";
# Nuke the existing Hugo installation
echo -e "\e[1;36mNuke the existing Hugo installation...\e[0m";
# Sleep so the screen can be read before moving on
sleep 2;
# Stop the Hugo dev-server
echo "";
echo -e "\e[1;33mStop the Hugo dev-server...\e[0m";
killall hugo;
echo -e "\e[32mDone\e[0m";
echo "";
# chown the remote web server directory (take ownership)
echo -e "\e[1;33mchown the remote web server directory (take ownership)...\e[0m";
ssh -t foo@server 'sudo chown $USER:$USER -R /var/www/example.org';
echo -e "\e[32mDone\e[0m";
echo "";
# Remove any existing content on the remote web server
echo -e "\e[1;33mRemove any existing content on the remote web server...\e[0m";
ssh -t foo@server 'rm -R /var/www/example.org/*';
echo -e "\e[32mDone\e[0m";
echo "";
# Remove any existing local Hugo '/public' content
echo -e "\e[1;33mRemove any existing local Hugo '/public' content...\e[0m";
rm -R /path/to/local/hugo/public/*;
echo -e "\e[32mDone\e[0m";
echo "";
# Build the new local Hugo website
echo -e "\e[1;33mBuild the new local Hugo website...\e[0m";
(cd /path/to/local/hugo/ && hugo);
echo -e "\e[32mDone\e[0m";
echo "";
# Copy the Hugo '/public' content to the remote web server
echo -e "\e[1;33mCopy the Hugo '/public' content to the remote web server...\e[0m";
scp -r /path/to/local/hugo/public/* foo@server:/var/www/example.org/;
echo -e "\e[32mDone\e[0m";
echo "";
# chown the remote web server directory (give ownership to www-data)
echo -e "\e[1;33mchown the remote web server directory (give ownership to www-data)...\e[0m";
ssh -t foo@server 'sudo chown www-data:www-data -R /var/www/example.org';
echo -e "\e[32mDone\e[0m";
echo "";
# Backup (rsync) the working directory
echo "";
echo -e "\e[1;33mBackup (rsync) the working directory...\e[0m";
rsync -a -P --delete -v --exclude '.git' /path/to/local/hugo /path/to/git/hugo;
echo -e "\e[32mDone\e[0m";
echo "";
# Clear out the Hugo generated '/public' folder before syncing (no need to store this in Forgejo)
echo -e "\e[1;33mClear out the Hugo generated '/public' folder before syncing (no need to store this in Forgejo)...\e[0m";
rm -R /path/to/git/hugo/public/*;
echo -e "\e[32mDone\e[0m";
echo "";
# Push '/path/to/git/hugo/' to Forgejo
echo -e "\e[1;33mPush '/path/to/git/hugo/' to Forgejo...\e[0m";
cd /path/to/git/hugo/;
git add .;
git commit -m 'Modified' .;
git push -u origin main;
echo -e "\e[32mDone\e[0m";
echo "";
# Start the Hugo dev-server
echo -e "\e[1;33mStart the hugo dev-server...\e[0m";
hugo server -s /path/to/local/hugo;
echo -e "\e[32mDone\e[0m";
echo "";
}
# Start by clearing the Terminal window
clear
echo "";
echo -e "\e[1;34mUse \e[1;36mCtrl-c\e[1;34m to \e[1;31mExit\e[1;34m and close the window...\e[0m";
echo "";
echo -e "\e[1;31mNuke\e[1;34m will:";
echo -e " Stop the Hugo dev-server";
echo -e " chown the remote web server directory (take ownership)";
echo -e " Remove any existing content on the remote web server";
echo -e " Remove any existing local Hugo '/public' content";
echo -e " Build the new local Hugo website";
echo -e " Copy the Hugo '/public' content to the remote web server";
echo -e " chown the remote web server directory (give ownership to www-data)";
echo -e " Backup (rsync) the working directory";
echo -e " Clear out the Hugo generated '/public' folder before syncing (no need to store this in Forgejo)";
echo -e " Push '/path/to/git/hugo/' to Forgejo";
echo -e " Start the Hugo dev-server";
echo "";
# Loop
while true; do
options=("Nuke")
echo -e "\e[1;36mChoose an option:\e[0m"
select opt in "${options[@]}"; do
case $REPLY in
1) nuke_hugo; break ;;
*) echo "Whoops, choose again, option '$REPLY' is invalid..." >&2
esac
done
done
Hope that helps someone.