I started by building a static site as a small side project for my brother—but then I wanted partials... and regression tests. I thought partials which could help me inline the CSS and JS tags while breaking the code up into different files for organizational purposes in development. I like to inline the assets to avoid render-blocking latency on simple landing pages which will likely be served over unreliable network conditions.
At first I really didn't think I needed a generator at all, but one thing led to another and I kind built a basic one myself.
It consists of a build.rb
file that looks like this...
prod_build = ARGV[0] == "for_prod"
# Read files
meta_html = File.open("workspace/meta.partial.html").read
style_css = File.open("workspace/style.partial.css").read
body_html = File.open("workspace/body.partial.html").read
json_data = File.open("workspace/data.json").read
scaffold_js = File.open("workspace/scaffold.partial.js").read
dynamic_js = File.open("workspace/dynamic.partial.js").read
analytics_html = File.open("workspace/analytics.partial.html").read
base_html = File.open("workspace/base.html").read
test_html = ""
unless prod_build
test_html = File.open("workspace/test.dev.html").read
end
# Create built page
build_string = base_html
.gsub("{{ meta }}", meta_html)
.gsub("{{ style }}", style_css)
.gsub("{{ html }}", body_html)
.gsub("{{ data }}", json_data)
.gsub("{{ scaffold_script }}", scaffold_js)
.gsub("{{ dynamic_script }}", dynamic_js)
.gsub("{{ analytics }}", analytics_html)
.gsub("{{ test }}", test_html)
# Write to target page
if prod_build
puts "Production build.... index.html"
File.write("index.html", build_string)
else
puts "Development build.... wip-index.html"
File.write("wip-index.html", build_string)
end
I could DRY up this code, but I prefer it to be dumb and super explicit at this stage.
As you can see, this is just basic string find and replace. {{
could just as easily have been 💩💩
or [cromulent >>
. It's completely arbitrary, but {{}}
looked fancy.
base.html
looks like this...
<html lang="en">
<head>
{{ meta }}
<style>
{{ style }}
</style>
</head>
<body>
{{ html }}
<script>
// Data
var data = {{ data }}
// Code
{{ scaffold_script }}
{{ dynamic_script }}
</script>
{{ analytics }}
{{ test }}
</body>
</html>
...I even wrote my own dependency-free JavaScript test suite. I'll share more once it's further along.
I probably should have reached for an existing static site generator instead of doing this from scratch, so why did I take this approach?
In all seriousness, I generally like to avoid dependencies when doing projects like this so it's easier to hop in for a quick change in the future without having to install a bunch of old dependencies. Building a whole toolchain myself is sort of silly, but fun!
If you don't want to be like me, you may want to check out this great thread...
Happy coding!