A static site generator in ~42 lines of Bash
Needed something basic to generate a few pages for this website. I could use an entire framework, but that would be overkill. Decided to write a static site generator in Bash.
Here is that bash script:
#!/bin/bash # create the public/posts directory if it doesn't exist mkdir -p public/posts list="" # --- COMPILE /posts DIRECTORY --- for file in posts/*.html do # get the filename without the extension filename=$(basename "$file" .html) # get the file contents content=$(cat "$file") # extract h1 from content title=$(sed -n 's/.*<h1>\(.*\)<\/h1>.*/\1/p' <<< "$content") # extract the date from the content date=$(sed -n 's/.*<time id="post-date" datetime="YYYY-MM-DD">\(.*\)<\/time>.*/\1/p' <<< "$content") # append the filename to the list of posts in 'list' list+="<li>$date - <a href=\"posts/$filename.html\">$title</a></li>\n" # get template contents before the insert comment, but not including before=$(sed -n '1,//p' template.html | head -n -1) # replace <title> tag with the title of the post in $before before=$(sed "s/<title>.*<\/title>/<title>$title | Kieren Funk<\/title>/" <<< "$before") echo "$before" > "public/posts/$filename.html" echo "$content" >> "public/posts/$filename.html" sed -n '//,$p' template.html | tail -n +2 >> "public/posts/$filename.html" done # --- COMPILE INDEX.HTML --- # sort the list of posts by date which is <li><a href=".*">(YYYY-MM-DD).*</a></li> list=$(echo -e "$list" | sort -r -t '>' -k2) awk -v var="$list" '{gsub(/{{blogPosts}}/,var)}1' index.html > "public/index.html"
The script is pretty simple. It loops through all the files in the posts directory and extracts the title and date from the file. It then appends the filename to a list of posts. It then extracts the content from the file and inserts it into the template. It then writes the template to the public directory.
After all the posts are compiled, it sorts the list of posts by date and inserts it on to the home page.
It's not perfect and there are definitely some limitations. For example, However, for the most part it just works and if I need to add more functionality I can just add it to the script.