-
Notifications
You must be signed in to change notification settings - Fork 55
/
Copy pathnimble_publisher.ex
86 lines (67 loc) · 1.89 KB
/
nimble_publisher.ex
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
Mix.install([
{:nimble_publisher, "~> 1.0"},
{:makeup_elixir, ">= 0.0.0"},
{:bandit, ">= 0.0.0"}
])
defmodule Example.Post do
@enforce_keys [:id, :title, :body, :date]
defstruct [:id, :title, :body, :date]
def build(filename, attrs, body) do
[year, month, day, id] =
filename |> Path.basename() |> String.split("-", parts: 4)
date = Date.from_iso8601!("#{year}-#{month}-#{day}")
struct!(__MODULE__, [id: id, date: date, body: body] ++ Map.to_list(attrs))
end
end
defmodule Example.Blog do
dir = Path.join(System.tmp_dir!(), "mix_install_examples_nimble_publisher")
File.rm_rf!(dir)
File.mkdir_p!(dir)
File.write!(Path.join(dir, "2023-04-03-hello-world.md"), ~S"""
%{
title: "Hello world"
}
---
Body of the "Hello world" article.
This is a *markdown* document with support for code highlighters:
```elixir
IO.puts "hello world"
```
""")
use NimblePublisher,
build: Example.Post,
from: "#{dir}/*.md",
as: :posts,
highlighters: [:makeup_elixir]
@posts Enum.sort_by(@posts, & &1.date, {:desc, Date})
def list_posts do
@posts
end
end
defmodule Example.Plug do
import Plug.Conn
def init(options), do: options
def call(conn, _) do
html = ~S"""
<style>
<%= Makeup.stylesheet(:tango_style, "makeup") %>
</style>
<h1>NimblePublisher example</h1>
<%= for post <- posts do %>
<h2><%= post.title %> (<%= post.date %>)</h2>
<%= post.body %>
<% end %>
"""
posts = Example.Blog.list_posts()
html = EEx.eval_string(html, posts: posts)
conn
|> put_resp_content_type("text/html")
|> send_resp(200, html)
end
end
bandit = {Bandit, plug: Example.Plug, scheme: :http, port: 4000}
{:ok, _} = Supervisor.start_link([bandit], strategy: :one_for_one)
# unless running from IEx, sleep idenfinitely so we can serve requests
unless IEx.started?() do
Process.sleep(:infinity)
end