Packages
fermo
0.12.0
0.20.1
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.1
0.17.0
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.0
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.4
0.2.2
0.2.1
0.2.0
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
A static site generator
Current section
Files
Jump to
Current section
Files
lib/fermo/build.ex
defmodule Fermo.Build do
def run(config) do
# TODO: check if Webpack assets are ready before building HTML
# TODO: avoid passing config into tasks - decide the layout beforehand
Task.async_stream(
config.pages,
&(render_cache_and_save(&1)),
[timeout: :infinity]
) |> Enum.to_list
put_in(config, [:stats, :build_pages_completed], Time.utc_now)
end
def render_page(page) do
content = render_body(page.options.module, page)
if page.options.layout do
build_layout_with_content(page.options.layout, content, page)
else
content
end
end
defp render_cache_and_save(page) do
with {:ok, hash} <- cache_key(page),
{:ok, cache_pathname} <- cached_page_path(hash),
{:ok} <- is_cached?(cache_pathname) do
Fermo.File.copy(cache_pathname, page.pathname)
else
{:build_and_cache, cache_pathname} ->
body = render_page(page)
Fermo.File.save(cache_pathname, body)
Fermo.File.save(page.pathname, body)
_ ->
body = render_page(page)
Fermo.File.save(page.pathname, body)
end
end
defp cache_key(%{options: %{surrogate_key: surrogate_key}}) do
hash = :crypto.hash(:sha256, surrogate_key) |> Base.encode16
{:ok, hash}
end
defp cache_key(_page), do: {:no_key}
defp cached_page_path(hash) do
{:ok, Path.join("tmp/page_cache", hash)}
end
defp is_cached?(cached_pathname) do
if File.exists?(cached_pathname) do
{:ok}
else
{:build_and_cache, cached_pathname}
end
end
defp render_body(module, %{template: template} = page) do
params = Fermo.Template.params_for(module, page)
Fermo.Template.render_template(module, template, page, params)
end
defp build_layout_with_content(layout, content, page) do
module = Fermo.Template.module_for_template(layout)
layout_params = Map.merge(page.params, %{content: content})
Fermo.Template.render_template(module, layout, page, layout_params)
end
end