--- layout: post title: "SSGs Part 2: Modern Static Site Generators" date: 2016-06-10 08:00:00 comments: true categories: engineering author: Marcia Ramos author_twitter: virtuacreative image_title: '/images/blogimages/ssg-gitlab-pages-series/ssg-overview-gitlab-pages-cover.jpg' --- 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**][part-1], 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][part-3]**! **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. {: .note} ---------- ### What's in this overview? {:.no_toc} - TOC {: 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][page-load] (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][server-crash] due to server overload [than dynamic ones][site-down]. **Note:** if you want to know more about it, read the introductory article for this series: "[SSGs Part 1: Static x Dynamic Websites][part-1]". {: .note} ## 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 {: #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][node]. ### Template engine {: #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][template-sys] 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][liquid]: ```html {% include head.html %} {% include header.html %}
{{ content }}
{% include footer.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} **[Markup language]** is a system to write documents making them somehow syntactically distinguishable from text. [Lightweight markup languages][wiki-markup] 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: ```markdown --- # 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: ```liquid

Title: {{ page.title }}

Date: {{ page.date }}

By {{ page.author }}

``` The output would be: ```

Title: Hello World

Date: 2016-04-30 11:00:00

By Foo Bar

``` The content for our example would output simply: ```html

An h1 heading

Some text.

``` ### Preprocessors {: #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: ```css h1 { color: #333; padding-top: 30px; } p { color: #333; } ``` Sass: ```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 {: #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][hexo-struc], [Middleman structure][middle-struc], [Jekyll structure][jekyll-struc]. 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]): ```liquid ``` 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][part-1]. 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][comment-systems]) - 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][google-cse], [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][html5-boiler], [Animate.css] - [Schema.org] markup, making [search engines][schema-seo] to understand our site content better. This is [one of the numerous SEO][seo] techniques - [Sitemaps], important for [SEO][seo-sitemaps] too. E.g., [Jekyll Sitemap plugin][jek-sitemap], [Middleman Sitemap][middle-sitemap], [Hexo Sitemap plugin][hexo-sitemap] ## 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][part-1]. ### 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][firebase-user-auth]. Find more [cool stuff][firebase-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][sendgrid-parse]. _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 [`