What are Static Site Generators? What are they for? Why should I use them? Do they have limitations? How can I use them with GitLab Pages?
If these questions ring a bell, this series of posts is for you! We are preparing three articles around the same theme "Static Site Generators (SSGs)".
This is Part 2: Modern Static Site Generators, where we provide you with an overview on the subject.
The previous post was Part 1: Dynamic x Static Websites, where we briefly explained the differences between them, and their pros and cons.
Stay tuned for the next post: Part 3: Build any SSG site with GitLab Pages!
Note: For this series, we assume you are familiar with web development, curious about Static Site Generators, and excited to see your site getting deployed with GitLab Pages.
What's in this overview?
- TOC
Benefits of Modern Static Site Generators
Static Site Generators (SSGs) are software created to automate web development to output static sites from dynamic writing. So, we code dynamically and publish statically. No pain, all gain.
The most fascinating thing of any SSG is the ability to code fast, save money (on web hosting), and incredibly decrease the page loading time (compared to server-side dynamic webpages). Also, if we have a lot of visitors at the same time, our static sites have less chance to crash due to server overload than dynamic ones.
Note: if you want to know more about it, read the introductory article for this series: "SSGs Part 1: Static x Dynamic Websites".
Structure of SSGs
The structure of SSGs is a combination of features to make static sites development faster and less repetitive. Let's take a quick look at the list below, then describe them one by one.
- Environment
- Template engine
- Markup language
- Preprocessors
- Directory structure
Environment
The environment, also called platform, consists essentially on the programming language the SSG was written in. It will make difference on the configuration, customization, and performance of the SSG. Examples: Ruby, Python, Node JS.
Template engine
The template engine is very important we understand, since all the dynamic structure of our sites will depend on that. It's essential that we choose an SSG with a templating system that we can use comfortably. Examples: Liquid, Haml and Slim (Ruby), Twig (PHP), [Swig] (JavaScript).
To give you a picture, let's see an example for an HTML file, in which we are using the Liquid Templating Engine:
<!DOCTYPE html>
<html lang="en">
{% include head.html %}
<body>
{% include header.html %}
<main class="content">
{{ content }}
</main>
{% include footer.html %}
</body>
</html>
As you may have guessed, we have three files for the content that repeats sitewide (head, header
and footer), which are included to every page using this template. The only thing that is different
is the {{ content }}
of that page, which is written in a separate file, and also included
dynamically to the template with this tag. Finally, all the files will be compiled to regular
HTML pages before being stored in the web server. This process is called build. GitLab Pages
builds any SSG.
Advantages over flat HTML
- Minimize typography errors ("typos"): all files are considerably reduced, improving readability
- Avoid repetition: every block repeated sitewide would be included to every page, equivalently
- Update faster: if we change something in the file
footer.html
, it will affect the entire site
Markup language
Markup language is a system to write documents making them somehow syntactically distinguishable from text. Lightweight markup languages have a simplified and unobtrusive syntax, designed to be easily written within any text editor. That's what we'll use to write our content.
The majority of SSGs use markdown engines for this purpose. But there are many more lightweight markup languages used likely, such as AsciiDoc, Textile and ReStructuredText.
Among those SSGs which use markdown markup, generally we are allowed to choose which markdown engine we want to use. It is set up on the site configuration. For example, in Ruby there are a handful of Markdown implementations: Kramdown, RDiscount, Redcarpet, RedCloth.
A blog post or a page written in markdown will most likely start with a front matter
section containing information about that page or post, and then comes the content just below it.
This is an example.md
file used in a Jekyll site, and also an example.html.md
file for
a Middleman site:
---
# front matter (between three-dashes block)
title: "Hello World" # post or page title
date: YYYY-MM-DD HH:MM:SS # date and time, e.g. "2016-04-30 11:00:00"
author: "Foo Bar" # a common variable to exemplify
---
# An h1 heading
Some text.
The front matter variables, which are title
, date
and author
for our example above,
can be called with template tags all over the site. With Liquid, if we write:
<h2>Title: {{ page.title }}</h2>
<p>Date: {{ page.date }}</p>
<p>By {{ page.author }}</p>
The output would be:
<h2>Title: Hello World</h2>
<p>Date: 2016-04-30 11:00:00</p>
<p>By Foo Bar</p>
The content for our example would output simply:
<h1>An h1 heading</h1>
<p>Some text.</p>
Preprocessors
The preprocessors are made to speed up our development process too. They simplify the way we code, and then compile their own files into standard ones. Examples: Sass and Stylus for CSS, CoffeeScript for JavaScript.
Again, just to give you a picture, check a CSS code block written in CSS directly, and the other written in Sass:
CSS:
h1 {
color: #333;
padding-top: 30px;
}
p {
color: #333;
}
Sass:
$clr = #333
h1
color: $clr
padding-top: 30px
p
color: $clr
In a large-scale styling, saving all curly brackets { }
and semi-colons ;
makes a lot
of difference for who is typing. Also, with Sass variables (e.g., $clr
above), we can
define some standards and apply them all over our stylesheets. In the end, everything
will be compiled to regular CSS. There are more interesting features and advantages of
preprocessors, but that's not in focus on this post.
By the way, the given Sass example will be compiled exactly to the CSS code above it.
Directory structure
The directory structure is different for each SSG. It's important to study the file tree before we start working with an SSG, otherwise we might face odd build errors that we won't understand solely because we didn't use its structure accordingly. Examples: Hexo structure, Middleman structure, Jekyll structure. So, just make sure you add new files to the correct directories.
SSGs built-in features
In addition to their standard components, there are also a number of built-in features that make building and previewing static sites easier - and faster. For example:
- Most of SSGs have a pre-installed server for previewing the sites locally
- Some of them also contain in their installation package a LiveReload plugin, so we don't need to refresh the page in our browser every time we save it
- Most of them provide us with built-in compilers for their supported preprocessors
Blog-Aware SSGs
One of the most attractive features for the majority of modern SSGs is the ability to manage blog content without the need of storing posts, or post contents, in databases or in server-side-only processed files.
A blog-aware website generator will create blog-style content, such as lists of content in reverse chronological order, archive lists, and other common blog-style features. How would an SSG do that?
With their file tree and their template engine. The file tree defines the specific
directory for posts
and the template engine calls the posts dynamically.
With a for
loop through the posts, they can be displayed in a single page, as
illustrated below (with Liquid):
<ul>
{% for post in site.posts %}
<li>
<span>{{ post.date }}</span>
<h2>
<a class="post-link" href="{{ post.url }}">{{ post.title }}</a>
</h2>
</li>
{% endfor %}
</ul>
This code means that, for each post within the site posts
({% for post in site.posts %}
), all of them would be displayed as items of an
unordered list of posts, within links for their respective paths.
Of course, we can adapt the HTML structure according to our needs. Also, we can use the blog-aware structure to create different kinds of dynamic insertion. For example, we could use them to display multiple things within the same category, as a collection of photos, books, etc. So, each time we add a new item, the SSG uses it's template engine to bring our collections together.
Supported content
Static servers fully support any language or script interpreted by browsers, known as client-side processing. Let's just remember that a static site is essentially composed of three components: the structure (HTML), the layout and styles (CSS), and the behavior (JavaScript).
Supported languages and file extensions
- Common file extensions:
.html
/.css
/.js
/.xml
/.pdf
/.txt
- Common media files: images, audio, video, SVG
Supported interactive services (examples)
- Commenting Systems (e.g., Disqus, Facebook Comments, and many others)
- Live Chat (e.g., JivoChat, Tawk.to)
- PayPal Payments Standard
- Facebook Social Plugins
- Twitter Kit
- Google Apps (e.g., Analytics, Adwords, AdSense, etc)
- Site Search Engine (e.g., Google Search, Swiftype, Tipue)
- Mailing lists and blog subscriptions (e.g., MailChimp)
Supported utilities (examples)
- HTML/CSS/JS frameworks and libraries. E.g, Bootstrap, Foundation, Normalize, Modernizr, Skeleton, jQuery, HTML5 Boilerplate, Animate.css
- Schema.org markup, making search engines to understand our site content better. This is one of the numerous SEO techniques
- Sitemaps, important for SEO too. E.g., Jekyll Sitemap plugin, Middleman Sitemap, Hexo Sitemap plugin
Limitations of SSGs
We've just described what we can do with SSGs. Now let's see what we cannot.
- Register users
- Have admin access
- Send emails via
mail()
function - Use any server-side language or script
These kinds of actions depend necessarily on server-side processing, which are not handled by static-only web servers, as we explained in the first post of this series.
Overcoming the limitations
User Authentication
Despite not having the ability to register users, nor having admin access for ourselves, with tools like Firebase we can power-up our static site with user authentication. Find more cool stuff here, from the same source.
Content management
We can edit the content of our SSGs directly from the web browser with Teletext.io. We can't create new pages, but we can edit pages' content easily. Follow the Teletext.io tutorial to learn how to implement this for your own website.
Contact Forms
Yes, we can offer contact forms in our static websites. We can't process the server-side script in our static-server, but there are some third-party services we can use for that. For example, you can try Formspree, FormKeep, Wufoo, FoxyForm, Google Forms or any other related service . However, if you want to take control over your mail script, you can try the parse method with SendGrid.
JavaScript disabled
Everything based on JavaScript is allowed to be added to our static sites. However, if
JavaScript is disabled on the user's browser, those scripts will not work. But there is
something we can do to minimize this issue. We can add a <noscript>
tag
to our web pages, containing a message that will be displayed only if JavaScript disabled:
<noscript>Please enable JavaScript on your browser for a better experience with this website!</noscript>
Conclusion
Hopefully now you understand the logic of Static Site Generators, how we can use them wisely, and what we can and cannot do with them. Dynamic websites are great, for sure. But if we don't need all their functionality, SSGs are certainly wonderful alternatives.
In the third post, which is the last chapter of this series, we will bring you a lot of examples for SSGs already running on GitLab Pages. Therefore, we're confident you'll be able to see and understand different GitLab CI configurations, and create your own.
We already have prepared a bunch of SSGs example projects, you'll find them in the GitLab Pages official group. You are very welcome to contribute with new SSGs.
Don't you have an account on GitLab.com yet? Let's create one! Remember, we can use GitLab Pages to build any SSG for us and host it for free!
Follow @GitLab on Twitter and stay tuned for updates!
Useful links
- GitLab Pages Quick Start - learn how to get started with GitLab Pages by forking an existing project
- GitLab Pages on GitLab.com - learn how to set up a GitLab Pages project from strach
- GitLab Pages Docs - the official documentation with all the details you might be interested in
- SSGs Part 1: Static vs Dynamic Websites - the first post of this series
- SSGs Part 3: Build any SSG site with GitLab Pages - the third post of this series