~mika/www.m1kadev.nl

ref: bce19303cd873fea1ee082f7c87b407300d38e23 www.m1kadev.nl/kethel/lib/pages.ex -rw-r--r-- 1.8 KiB
bce19303 — m1kadev kethel: add support for pages/ 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
require Rambo

defmodule Pages do
  defstruct [ :source_files, :main_template, :project_root, :bricks ]

  def trim_abs_path(path, context) do
    begin = byte_size(context.project_root) + byte_size("pages/") # ROOT + pages/ 
    binary_part(path, begin, byte_size(path) - begin - byte_size(".fxg")) # remove extension
  end

  @spec collect(%Context{}) :: %Pages{}
  def collect(context) do
    pages_root = context.project_root <> "/pages"
    %Pages{
      project_root: context.project_root,
      source_files: Path.wildcard(pages_root <> "/**/*.fxg")
        |> Enum.map(fn path -> { path, File.read!(path) } end)
        |> Enum.map(fn { path, data } -> { trim_abs_path(path, context), data } end),
      main_template: File.read!(context.project_root <> "/templates/base.thtml"),
      bricks: context.bricks,
    }
  end

  @spec compile(%Pages{}) :: none()
  def compile(pages) do
    Task.async_stream(pages.source_files, fn page -> compile_file(pages, page) end) |> Enum.to_list()
  end

  defp compile_file(pages, { page_path, page_data }) do
    output_path = "#{pages.project_root}/build#{page_path}.html"
    IO.puts("#{pages.project_root}/pages#{page_path}.fxg -> #{output_path}")
    # check for a custom template
    custom_template_path = "#{pages.project_root}/templates/pages#{page_path}.thtml"
    template = case File.read(custom_template_path) do
      {:ok, custom_template} -> custom_template
      {:error, :enoent} -> pages.main_template
      {:error, err } -> raise err
    end
    mustache_context = Map.merge(%{fxg_content: invoke_fxg(page_data), location: page_path}, pages.bricks)
    page_rendered = Mustache.render(template, mustache_context)
    File.write!(output_path, page_rendered)
  end

  # TODO: switch this to Rambo
  defp invoke_fxg(data) do
    {:ok, res} = Rambo.run("fxg", ["-"], in: data)
    res.out
  end
end