tangled
alpha
login
or
join now
kacaii.dev
/
blog
0
fork
atom
💻 My personal website
blog.kacaii.dev/
blog
gleam
lustre
0
fork
atom
overview
issues
pulls
pipelines
:truck: move post view function to `content.gleam`
kacaii.dev
2 months ago
c72d3d9d
f820f841
1/1
fly.yml
success
49s
+42
-39
2 changed files
expand all
collapse all
unified
split
src
blog
page
content.gleam
post.gleam
+42
-4
src/blog/page/content.gleam
···
2
2
import blog/page/navbar
3
3
import blog/post
4
4
import blog/root
5
5
+
import contour
5
6
import gleam/list
7
7
+
import gleam/option
8
8
+
import jot
9
9
+
import lustre/attribute.{class}
10
10
+
import lustre/element
6
11
import web
7
12
import wisp
8
13
9
14
pub fn handle_request(ctx: web.Context, post_uri: String) -> wisp.Response {
10
15
case list.find(ctx.posts, fn(post) { post.to_uri_path(post) == post_uri }) {
11
16
Error(_) -> wisp.not_found()
12
12
-
Ok(post) -> view(post)
17
17
+
Ok(found_post) -> {
18
18
+
let title = found_post.meta.title
19
19
+
20
20
+
root.view(title:, content: [
21
21
+
navbar.view(),
22
22
+
view(found_post),
23
23
+
footer.view(),
24
24
+
])
25
25
+
}
13
26
}
14
27
}
15
28
16
16
-
fn view(found_post: post.Post) -> wisp.Response {
17
17
-
let content = [navbar.view(), post.view(found_post), footer.view()]
18
18
-
root.view(title: found_post.meta.title, content:)
29
29
+
pub fn view(post: post.Post) -> element.Element(a) {
30
30
+
let content =
31
31
+
post.body.content
32
32
+
|> list.map(highlight_codeblock)
33
33
+
34
34
+
let post_body =
35
35
+
jot.Document(..post.body, content:)
36
36
+
|> jot.document_to_html
37
37
+
38
38
+
let style =
39
39
+
class(
40
40
+
"grid grid-cols-1 gap-4"
41
41
+
<> " mx-auto max-w-md sm:max-w-lg md:max-w-2xl"
42
42
+
<> " text-pretty post-content",
43
43
+
)
44
44
+
45
45
+
element.fragment([element.unsafe_raw_html("", "article", [style], post_body)])
46
46
+
}
47
47
+
48
48
+
fn highlight_codeblock(container: jot.Container) -> jot.Container {
49
49
+
case container {
50
50
+
jot.Codeblock(_, language: option.Some("gleam"), content:) -> {
51
51
+
let code = "<pre><code>" <> contour.to_html(content) <> "</code></pre>"
52
52
+
jot.RawBlock(code)
53
53
+
}
54
54
+
55
55
+
other -> other
56
56
+
}
19
57
}
-35
src/blog/post.gleam
···
1
1
-
import contour
2
1
import frontmatter
3
2
import gleam/int
4
3
import gleam/list
···
8
7
import gleam/string
9
8
import gleam/time/calendar
10
9
import jot
11
11
-
import lustre/attribute.{class}
12
12
-
import lustre/element
13
10
import simplifile
14
11
import tom
15
12
···
51
48
}
52
49
}
53
50
54
54
-
pub fn view(post: Post) -> element.Element(a) {
55
55
-
let content =
56
56
-
post.body.content
57
57
-
|> list.map(highlight_codeblock)
58
58
-
59
59
-
let post_body =
60
60
-
jot.Document(..post.body, content:)
61
61
-
|> jot.document_to_html
62
62
-
63
63
-
let style =
64
64
-
class(
65
65
-
"grid grid-cols-1 gap-4"
66
66
-
<> " mx-auto max-w-md sm:max-w-lg md:max-w-2xl"
67
67
-
<> " text-pretty post-content",
68
68
-
)
69
69
-
70
70
-
let html = element.unsafe_raw_html("", "article", [style], post_body)
71
71
-
72
72
-
element.fragment([html])
73
73
-
}
74
74
-
75
51
fn parse_metadata(metadata: String) -> Result(Metadata, PostError) {
76
52
use toml <- result.try(
77
53
tom.parse(metadata)
···
103
79
get(toml, [field])
104
80
|> result.replace_error(WrongMetadataField(field))
105
81
|> result.try(then)
106
106
-
}
107
107
-
108
108
-
fn highlight_codeblock(container: jot.Container) -> jot.Container {
109
109
-
case container {
110
110
-
jot.Codeblock(_, language: option.Some("gleam"), content:) -> {
111
111
-
let code = "<pre><code>" <> contour.to_html(content) <> "</code></pre>"
112
112
-
jot.RawBlock(code)
113
113
-
}
114
114
-
115
115
-
other -> other
116
116
-
}
117
82
}
118
83
119
84
pub fn compare(a: Post, b: Post) -> order.Order {