So, here we are again. Designing a new system for automatic static page creation. Ah well, it had to happen some time.
The old system was a nice little technical feat, with a javascript file parsing the entire page from markdown to HTML in the client’s browser - reliably and without crashing the browser. At the time the thinking was:
In reality, what happened is:
lynx
or in dillio
(my test for really low end internet browsing)The point is, I started off with the best of intentions and ended up making my website less accessible. My page download time (request to render) was 0.7 seconds, which I thought was good… I had a feeling I could do better though.
The new process is in my opinion better. Let’s start with some comparisons from what was previously spoken about:
lynx
and dillio
How this is achieved is the files are now stored as pure markdown, with a custom script being run over the files to produce the HTML files using pandoc
.
Below is the script used (for the purpose of completeness):
0001 #!/bin/bash 0002 0003 # build() 0004 # 0005 # Build in the current directory. 0006 # 0007 # @param $1 The location of the style sheet. 0008 # @param $2 The location of the navigation HTML data. 0009 function build { 0010 for filename in *.md; do 0011 pandoc --section-divs -c $1 -B $2 -o ${filename%.*}.html $filename 0012 echo -n "." 0013 done 0014 } 0015 0016 # clean() 0017 # 0018 # Clean the working directory. 0019 function clean { 0020 rm *.html 0021 } 0022 0023 # help() 0024 # 0025 # Display the help for this script. 0026 function help { 0027 echo "bash run.sh <CMD>" 0028 echo "" 0029 echo " ComManD" 0030 echo "" 0031 echo " build Build the different directories" 0032 echo " clean Clean the directory of build files" 0033 echo " help Display the help" 0034 } 0035 0036 # main() 0037 # 0038 # Handle the main program logic. 0039 # 0040 # @param $@ Arguments from the command line. 0041 function main { 0042 work="$(pwd)/www" 0043 style="http://coffeespace.org.uk/style.css" 0044 header="$work/header.html" 0045 directories[0]="$work" 0046 directories[1]="$work/blogs" 0047 directories[2]="$work/projects" 0048 directories[3]="$work/software" 0049 # Pre-build the header if required 0050 if [[ "$1" == "build" ]]; then 0051 pandoc --section-divs -o "$work/header.html" "$work/header.md_nocompile" 0052 fi 0053 # Iterate over the directories 0054 for dir in "${directories[@]}"; do 0055 cd $dir 0056 case "$1" in 0057 build) 0058 build $style $header 0059 ;; 0060 clean) 0061 clean 0062 ;; 0063 help) 0064 help 0065 exit 1 0066 ;; 0067 *) 0068 echo "Error: Use 'help' for more information" 0069 exit 1 0070 ;; 0071 esac 0072 cd ${directories[0]} 0073 done 0074 echo -e "\n[DONE]" 0075 } 0076 0077 main $@
Notice the comments - I have no expectation of being able to remember how this works next year ;)
Then it’s simply a case of getting the changes pulled from git
and build automatically:
0078 #!/bin/bash 0079 0080 # Infinite loop 0081 while : 0082 do 0083 # Fetch the latest changes 0084 git fetch 0085 # Check whether pull required 0086 if ! git diff --quiet remotes/origin/HEAD; then 0087 # Pull the latest changes 0088 git pull 0089 # Remove the old HTML files 0090 bash run.sh clean 0091 # Rebuild the HTML files 0092 bash run.sh build 0093 else 0094 echo "No changes" 0095 fi 0096 # Sleep for 5 minutes and check again 0097 sleep 300 0098 done
Notice that the site is only rebuilt when there are changes pushed - this means the entire site is down for 5 seconds maximum for every push to the repository.
It’s still very “hacky”, I know - but I like it. This is run on my 3 euro ScaleWay instance and runs perfectly fine. I once purposely tried to DDoS my own server with no effect, so it should stand up reasonably well to attack.
It’s redeeming features are that it’s simple, easy to understand, easy to debug and easier to add hacks too. There may be better ways to do this, but from my perspective it does enough. I’m fairly happy with this system.
I’m interested in knowing your thoughts - please post your comments below!