Current section

Files

Jump to
fermo lib fermo build.ex
Raw

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