Use Liquid templating for static HTML inclusion
You might not know this but this blog is built using Jekyll, a static site generator. Jekyll is a great tool for creating simple websites and blogs. It is powered by the Liquid templating syntax. It allows you to include dynamic content in your static HTML files. This is a very powerful feature and I was wondering if I could use it outside of Jekyll.
Templating with Liquid
So the answer is yes! You can absolutely use Liquid templating in your static HTML files. All you need is LiquidJS:
-
Install LiquidJS:
npm install -g liquidjs
-
Create a file that you would want to include in multiple pages. For example a
head.liquid
that contains the head of all your HTML pages:<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Lots of head stuff --> <title>{{ title }}</title> <link rel="stylesheet" href="styles.css"> </head>
-
Then create an
index.liquid
template file:<!DOCTYPE html> <html lang="en"> {% include 'head.liquid', title: 'Page Title' %} <body> Page content here </body> </html>
Notice how the
title
variable is passed to thehead.liquid
template. This allows you to set a different title for each of your pages. -
Finally, run the LiquidJS CLI to render the HTML:
npx liquidjs -t @index.liquid -o index.html
Which will generate the following
index.html
file:<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Lots of head stuff --> <title>Page Title</title> <link rel="stylesheet" href="styles.css"> </head> <body> Page content here </body> </html>
And that’s it! When creating your next page you can reuse the head.liquid
template file and pass in the title of the page. This is a very simple example
but you can obviously do much more with Liquid templating.
Using LiquidJS in your project
To include this tool in my web application I actually created a Makefile to automate the process. The structure of this project is as follows:
_includes/
: Reusable liquid templates (header, footer, etc…)._layouts/
: Structural layouts for the pages._pages/
: Every page of the application and their contents._static/
: Static files (images, styles, scripts, etc…).www/
: The output directory for the compiled HTML files.
In the example above the head.liquid
and index.liquid
files would go into
the _includes
and _pages
directories respectively. There are no
layouts
in this example but you can add some in the _layouts
directory. They simplify
your pages even further allowing you to only have content in your page files.
# Define directories
SRC_DIR := .
INCLUDES_DIR := $(SRC_DIR)/_includes
LAYOUTS_DIR := $(SRC_DIR)/_layouts
STATIC_DIR := $(SRC_DIR)/_static
PAGES_DIR := $(SRC_DIR)/_pages
OUT_DIR := www
# Compiler command
CC := npx liquidjs --partials $(INCLUDES_DIR) --layouts $(LAYOUTS_DIR)
# Find all files in STATIC_DIR and create corresponding file names in OUT_DIR
STATIC_FILES := $(shell find $(STATIC_DIR) -type f -not -name '.*')
OUTPUT_STATIC := $(STATIC_FILES:$(STATIC_DIR)/%=$(OUT_DIR)/%)
# Find all .liquid files in PAGES_DIR and create corresponding .html file names
PAGE_TEMPLATES := $(shell find $(PAGES_DIR) -name '*.liquid')
OUTPUT_PAGES := $(PAGE_TEMPLATES:$(PAGES_DIR)/%.liquid=$(OUT_DIR)/%.html)
# Default target: compile all .liquid files
all: $(OUT_DIR) $(OUTPUT_STATIC) $(OUTPUT_PAGES)
# Rule to create the output directory
$(OUT_DIR):
mkdir -p $(OUT_DIR)
# Rule to copy static files
$(OUT_DIR)/%: $(STATIC_DIR)/%
@mkdir -p $(dir $@)
cp -r $< $@
# Rule to compile .liquid to .html
$(OUT_DIR)/%.html: $(PAGES_DIR)/%.liquid $(INCLUDES_DIR)/* $(LAYOUTS_DIR)/*
@mkdir -p $(dir $@) # Create the output directory if it doesn't exist
$(CC) -t @$< -o $@
# Clean target to remove compiled files
clean:
rm -rf $(OUT_DIR)
re: clean all
.PHONY: all clean
Just run the make
command and this Makefile will compile all .liquid
files
in _pages
and output the resulting .html
files in the www
directory. You
can then serve www
with your favorite web server.
Conclusion
This technique makes it easy to reuse HTML snippets across your website without resorting to copy-pasting, JavaScript or some form of server side rendering (like php or SSI).