Skip to content

Commit af6ddd2

Browse files
committed
refactor: add Content module to manage static markdown content
- Added Algora.Content module to handle loading and listing markdown content with frontmatter. - Updated BlogLive module to utilize the new content management functions for loading blog posts and formatting dates. - Removed deprecated functions related to blog post loading and listing.
1 parent 844e8ce commit af6ddd2

File tree

2 files changed

+59
-51
lines changed

2 files changed

+59
-51
lines changed

lib/algora/content.ex

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
defmodule Algora.Content do
2+
@moduledoc """
3+
Handles markdown content with frontmatter for blog posts, changelogs, docs, etc.
4+
"""
5+
6+
alias Algora.Markdown
7+
8+
defstruct [:slug, :title, :date, :tags, :authors, :content]
9+
10+
def load_content(directory, slug) do
11+
with {:ok, content} <- File.read(Path.join(directory, "#{slug}.md")),
12+
[frontmatter, markdown] <- content |> String.split("---\n", parts: 3) |> Enum.drop(1),
13+
{:ok, parsed_frontmatter} <- YamlElixir.read_from_string(frontmatter) do
14+
{:ok,
15+
%__MODULE__{
16+
slug: slug,
17+
title: parsed_frontmatter["title"],
18+
date: parsed_frontmatter["date"],
19+
tags: parsed_frontmatter["tags"],
20+
authors: parsed_frontmatter["authors"],
21+
content: Markdown.render_unsafe(markdown)
22+
}}
23+
end
24+
end
25+
26+
def list_content(directory) do
27+
directory
28+
|> File.ls!()
29+
|> Enum.filter(&String.ends_with?(&1, ".md"))
30+
|> Enum.map(fn filename ->
31+
slug = String.replace(filename, ".md", "")
32+
{:ok, content} = load_content(directory, slug)
33+
content
34+
end)
35+
|> Enum.sort_by(& &1.date, :desc)
36+
end
37+
38+
def format_date(date_string) when is_binary(date_string) do
39+
case Date.from_iso8601(date_string) do
40+
{:ok, date} -> Calendar.strftime(date, "%B %d, %Y")
41+
_ -> date_string
42+
end
43+
end
44+
45+
def format_date(_), do: ""
46+
end

lib/algora_web/live/blog_live.ex

Lines changed: 13 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ defmodule AlgoraWeb.BlogLive do
22
@moduledoc false
33
use AlgoraWeb, :live_view
44

5-
alias Algora.Markdown
65
alias AlgoraWeb.Components.Footer
76
alias AlgoraWeb.Components.Header
87

8+
defp blog_path, do: Path.join([:code.priv_dir(:algora), "blog"])
9+
910
@impl true
1011
def mount(%{"slug" => slug}, _session, socket) do
11-
case load_blog_post(slug) do
12-
{:ok, {frontmatter, content}} ->
12+
case Algora.Content.load_content(blog_path(), slug) do
13+
{:ok, content} ->
1314
{:ok,
1415
assign(socket,
15-
content: Markdown.render_unsafe(content),
16-
frontmatter: frontmatter,
17-
page_title: frontmatter["title"]
16+
content: content,
17+
page_title: content.title
1818
)}
1919

2020
{:error, _reason} ->
@@ -24,7 +24,7 @@ defmodule AlgoraWeb.BlogLive do
2424

2525
@impl true
2626
def mount(_params, _session, socket) do
27-
posts = list_blog_posts()
27+
posts = Algora.Content.list_content(blog_path())
2828
{:ok, assign(socket, posts: posts, page_title: "Blog")}
2929
end
3030

@@ -44,7 +44,7 @@ defmodule AlgoraWeb.BlogLive do
4444
{post.title}
4545
</h2>
4646
<div class="flex items-center gap-4 text-sm text-muted-foreground">
47-
<time datetime={post.date}>{format_date(post.date)}</time>
47+
<time datetime={post.date}>{Algora.Content.format_date(post.date)}</time>
4848
<div class="flex items-center gap-2">
4949
<%= for author <- post.authors do %>
5050
<img src={"https://github.com/#{author}.png"} class="w-6 h-6 rounded-full" />
@@ -66,13 +66,13 @@ defmodule AlgoraWeb.BlogLive do
6666
<article class="prose dark:prose-invert max-w-none">
6767
<header class="mb-8 not-prose">
6868
<h1 class="text-5xl font-display font-extrabold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-emerald-400 to-emerald-300">
69-
{@frontmatter["title"]}
69+
{@content.title}
7070
</h1>
7171
7272
<div class="flex items-center gap-4 text-muted-foreground mb-4">
73-
<time datetime={@frontmatter["date"]}>{format_date(@frontmatter["date"])}</time>
73+
<time datetime={@content.date}>{Algora.Content.format_date(@content.date)}</time>
7474
<div class="flex items-center gap-3">
75-
<%= for author <- @frontmatter["authors"] do %>
75+
<%= for author <- @content.authors do %>
7676
<div class="flex items-center gap-2">
7777
<img src={"https://github.com/#{author}.png"} class="w-8 h-8 rounded-full" />
7878
<.link
@@ -88,58 +88,20 @@ defmodule AlgoraWeb.BlogLive do
8888
</div>
8989
9090
<div class="flex flex-wrap gap-2">
91-
<%= for tag <- @frontmatter["tags"] do %>
91+
<%= for tag <- @content.tags do %>
9292
<.badge>
9393
{tag}
9494
</.badge>
9595
<% end %>
9696
</div>
9797
</header>
9898
99-
{raw(@content)}
99+
{raw(@content.content)}
100100
</article>
101101
<% end %>
102102
</div>
103103
<Footer.footer />
104104
</div>
105105
"""
106106
end
107-
108-
defp load_blog_post(slug) do
109-
with {:ok, content} <- File.read(Path.join(blog_path(), "#{slug}.md")),
110-
[frontmatter, markdown] <- content |> String.split("---\n", parts: 3) |> Enum.drop(1),
111-
{:ok, parsed_frontmatter} <- YamlElixir.read_from_string(frontmatter) do
112-
{:ok, {parsed_frontmatter, markdown}}
113-
end
114-
end
115-
116-
defp list_blog_posts do
117-
blog_path()
118-
|> File.ls!()
119-
|> Enum.filter(&String.ends_with?(&1, ".md"))
120-
|> Enum.map(fn filename ->
121-
{:ok, {frontmatter, _content}} = load_blog_post(String.replace(filename, ".md", ""))
122-
123-
%{
124-
slug: String.replace(filename, ".md", ""),
125-
title: frontmatter["title"],
126-
date: frontmatter["date"],
127-
tags: frontmatter["tags"],
128-
authors: frontmatter["authors"]
129-
}
130-
end)
131-
|> Enum.sort_by(& &1.date, :desc)
132-
end
133-
134-
# Add this function to format dates
135-
def format_date(date_string) when is_binary(date_string) do
136-
case Date.from_iso8601(date_string) do
137-
{:ok, date} -> Calendar.strftime(date, "%B %d, %Y")
138-
_ -> date_string
139-
end
140-
end
141-
142-
def format_date(_), do: ""
143-
144-
defp blog_path, do: Path.join([:code.priv_dir(:algora), "blog"])
145107
end

0 commit comments

Comments
 (0)