A kethel/lib/thoughts.ex => kethel/lib/thoughts.ex +64 -0
@@ 0,0 1,64 @@
+defmodule Thoughts do
+ defstruct [:thoughts, :template, :bricks, :project_root]
+
+ @spec urlify(binary()) :: binary()
+ defp urlify(name) do
+ name
+ |> String.replace(" ", "_")
+ end
+
+ @spec trim_abs_path(binary(), binary()) :: binary()
+ defp trim_abs_path(path, project_root) do
+ # ROOT + thoughts/
+ begin = byte_size(project_root) + byte_size("/thoughts/")
+ binary_part(path, begin, byte_size(path) - begin)
+ end
+
+ @spec collect(binary(), %{binary() => binary()}) :: %{}
+ def collect(project_root, bricks) do
+ %Thoughts{
+ thoughts:
+ Path.wildcard("#{project_root}/thoughts/*")
+ |> Enum.map(fn path -> {path, File.read!(path)} end),
+ template: File.read!("#{project_root}/templates/thought.thtml"),
+ bricks: bricks,
+ project_root: project_root
+ }
+ end
+
+ @spec ensure_folders(binary()) :: :ok
+ def ensure_folders(project_root) do
+ File.mkdir_p!("#{project_root}/build/thoughts/")
+ end
+
+ @spec compile(%Thoughts{}) :: :ok
+ def compile(thoughts) do
+ ensure_folders(thoughts.project_root)
+
+ thoughts.thoughts
+ |> Task.async_stream(fn thought ->
+ compile_file(thought, thoughts.template, thoughts.bricks, thoughts.project_root)
+ end)
+ |> Enum.to_list()
+ end
+
+ defp compile_file({path, thought}, template, bricks, project_root) do
+ name = trim_abs_path(path, project_root)
+ # unix timestamp
+ date = get_file_commit_date(path)
+ output_path = "#{project_root}/build/thoughts/#{urlify(name)}.html"
+ mustache_context = Map.merge(bricks, %{thought: thought, name: name, date: date})
+
+ File.write!(output_path, Mustache.render(template, mustache_context))
+ IO.puts("[COMPILED] #{path} -> #{output_path}")
+ end
+
+ def get_file_commit_date(path) do
+ {ts_string, 0} = System.cmd("git", ["log", "--format=%ct", path])
+
+ time =
+ String.to_integer(String.trim_trailing(ts_string))
+ |> DateTime.from_unix!()
+ |> Calendar.strftime("%d/%m/%y (%H:%M)")
+ end
+end
M kethel/main.exs => kethel/main.exs +12 -3
@@ 15,17 15,26 @@ if folder != nil do
statics_task = Task.async(fn -> Statics.compile(project_root) end)
styles_task = Task.async(fn -> Styles.collect(project_root) end)
- pages_task = Task.async(fn -> Pages.collect(project_root, bricks) end)
scripts_task = Task.async(fn -> Scripts.collect(project_root) end)
+ pages_task = Task.async(fn -> Pages.collect(project_root, bricks) end)
+ thoughts_task = Task.async(fn -> Thoughts.collect(project_root, bricks) end)
- [styles, pages, scripts] = Task.await_many([styles_task, pages_task, scripts_task], :infinity)
+ [styles, pages, scripts, thoughts] =
+ Task.await_many([styles_task, pages_task, scripts_task, thoughts_task], :infinity)
pages_compile_task = Task.async(fn -> Pages.compile(pages) end)
styles_compile_task = Task.async(fn -> Styles.compile(styles) end)
scripts_compile_task = Task.async(fn -> Scripts.compile(scripts) end)
+ thoughts_compile_task = Task.async(fn -> Thoughts.compile(thoughts) end)
Task.await_many(
- [pages_compile_task, styles_compile_task, statics_task, scripts_compile_task],
+ [
+ pages_compile_task,
+ styles_compile_task,
+ statics_task,
+ scripts_compile_task,
+ thoughts_compile_task
+ ],
:infinity
)
else
M templates/thought.thtml => templates/thought.thtml +3 -3
@@ 7,7 7,7 @@
<link rel="stylesheet" href="/styles/thought.css">
- <title> {{ thought }} - m1kadev</title>
+ <title> {{ name }} - m1kadev</title>
{{ &ogp }}
@@ 19,9 19,9 @@
<div id="content">
<main>
- <h2> {{ thought }} </h2>
+ <h2> {{ name }} </h2>
<span id="thought">
- {{ &fxg_content }}
+ {{ thought }}
</span>
<small>-mika, {{ date }}</small>
<hr>