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.liquidthat 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.liquidtemplate file:<!DOCTYPE html> <html lang="en"> {% include 'head.liquid', title: 'Page Title' %} <body> Page content here </body> </html>Notice how the
titlevariable is passed to thehead.liquidtemplate. 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.htmlWhich will generate the following
index.htmlfile:<!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).