Fermo

A static site generator, build for speed and flexibility.

Usage

  1. Create an Elixir project:
$ mix new myProject
  1. Modify mix.exs

See Mix configuration.

  1. Get dependencies:
$ mix deps.get
  1. Create lib/{{project name}}.ex

See Configuration.

  1. Build the project:
$ mix fermo.build

Capabilities

Project Structure

+-- build             - The built site
+-- lib
|   +-- my_project.ex - See [Configuration](#configuration)
|   +-- helpers.ex
+-- mix.exs           - See [Mix configuration](#mix-configuration)
+-- priv
    +-- locales       - See [Localization](#localization)
    |   +-- en.yml
    |   +-- ...
    +-- source
        +-- javascripts
        +-- layouts
        +-- localizable
        +-- templates
        +-- partials
        +-- static
        +-- stylesheets
        +-- templates

Mix Configuration

defmodule MyProject.MixProject do
  use Mix.Project

  def project do
    [
      ...
      compilers: Mix.compilers() ++ [:fermo],
      ...
      deps: deps()
    ]
  end

  defp deps do
    [
      {:fermo, "~> 0.5.1"}
    ]
  end
end

Configuration

Create a module (under lib) with a name matching your MixProject module defined in [mix.exs](#mix-configuration).

This module must implement build/0, a function that returns an updated [config](#config-object).

defmodule MyProject do
  @moduledoc """
  Documentation for MyProject.
  """

  use Fermo

  def build do
    config = initial_config()

    {:ok, config}
  end
end

Fermo Invocation

The command

use Fermo

prepares the initial config structure.

Simple Excludes

In order to not have your template files automatically built as simple files use :exclude.

  use Fermo, %{
    exclude: ["templates/*", "layouts/*", "javascripts/*", "stylesheets/*"],
  }

Config-defined Pages

Most static site generators build one webpage for every source page (e.g. Hugo).

Middleman provides the very powerful but strangely named proxy, which allows you to produce many pages from one template. So, if you have a local JSON of YAML file, or even better an online CMS, as a source, you can build a page for each of your items without having to commit the to your Git repo.

In Fermo, dynamic, data-based pages are created with the page method in your project configuration's build/0 method.

  def build do
    ...
    foo = ... # loaded from some external source
    page(
      config,
      "templates/foo.html.slim",
      "/foos/#{foo.slug}/index.html",
      %{foo: foo},
      %{locale: :en}
    )
    ...
  end

Templating

Currently, Fermo only supports SLIM templates for HTML.

There are various types of templates:

  • simple templates - any templates found under priv/source will be built. The partials directory is exluded by default - see excludes.
  • page templates - used with config-defined pages,
  • partials - used from other templates,
  • localized - build for each configured locale. See localization

Parameters

Top level pages are called with the following parameters:

  • params - the parameters passed directly to the template or partial,
  • context - hash of contextual information.

Context

  • :env - the application environment,
  • :module - the module of the compiled template,
  • :template - the top-level page or partial template pathname, with path relative to the source root,
  • :page - see below.

Page

Information about the top-level page.

  • :template - the template path and name relative to the source root,
  • :target - the path of the generated file,
  • :path - the online path of the page,
  • :params - the parameters passed to the template,
  • :options - other options, e.g. the locale.

Partials

Partials are also called with the same 2 parameters, but the values in :page are those of the top-level page, not the partial itself.

Associated Libraries

Localization

If you pass an :i18n key with a list of locales to Fermo, your locale files will be loaded at build time and files under localizable will be built for each locale.

defmodule MyProject do
  @moduledoc """
  Documentation for MyProject.
  """

  use Fermo, %{
    ...
    i18n: [:en, :fr]
  }

  ...
end

Middleman to Fermo

Fermo was created as an improvement on Middleman, so its defaults tend to be the same its progenitor.

See here.