Add controllers/templates to show blog posts.

This commit is contained in:
Jessica Canady 2024-06-04 14:09:14 -04:00
parent 39c8612480
commit fc1b264f1b
Signed by: phoenix
SSH key fingerprint: SHA256:aaLOzOrLi+0n4eDZNQKH97PehwRt6KSE5fYJc+ZRKCQ
14 changed files with 79 additions and 8 deletions

View file

@ -58,7 +58,8 @@ config :jol, JOLWeb.Endpoint,
patterns: [
~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
~r"priv/gettext/.*(po)$",
~r"lib/jol_web/(controllers|live|components)/.*(ex|heex)$"
~r"lib/jol_web/(controllers|live|components)/.*(ex|heex)$",
~r"posts/*/.*(md)$"
]
]

View file

@ -1,6 +1,12 @@
defmodule JOL.Blog do
<<<<<<< HEAD
alias JOL.Blog.Post
alias JOL.Blog.Parser
=======
defmodule NotFoundError do
defexception [:message, plug_status: 404]
end
>>>>>>> 77c7828 (Add controllers/templates to show blog posts.)
use NimblePublisher,
build: JOL.Blog.Post,
@ -11,9 +17,22 @@ defmodule JOL.Blog do
@posts Enum.sort_by(@posts, & &1.date, {:desc, Date})
@tags @posts |> Enum.flat_map(& &1.tags) |> Enum.uniq() |> Enum.sort()
@spec posts() :: []
def posts, do: @posts
@spec unique_tag_list() :: []
def all_posts, do: @posts
def unique_tag_list, do: @tags
def recent_posts(num \\ 10) do
Enum.take(all_posts(), num)
end
def get_post_by_slug!(slug) do
Enum.find(all_posts(), &(&1.slug == slug)) ||
raise NotFoundError, "post ``slug=#{slug}` not found"
end
def get_posts_by_tag!(tag) do
case Enum.filter(all_posts(), &(tag in &1.tags)) do
[] -> raise NotFoundError, "posts tagged `#{tag}` not found"
posts -> posts
end
end
end

View file

@ -24,7 +24,8 @@ defmodule JOL.Blog.Parser do
title: toml_attrs["title"],
draft: toml_attrs["draft"],
tags: toml_attrs["taxonomies"]["tags"],
date: toml_attrs["date"]
date: toml_attrs["date"],
slug: toml_attrs["slug"]
}
parsed_body = String.trim(body)

View file

@ -1,6 +1,6 @@
defmodule JOL.Blog.Post do
@enforce_keys [:author, :draft, :title, :body, :tags, :date]
defstruct [:author, :draft, :title, :body, :tags, :date]
@enforce_keys [:author, :title, :body, :tags, :date, :slug]
defstruct [:author, :draft, :title, :body, :tags, :date, :slug]
def build(_filename, attrs, body) do
struct!(__MODULE__, [author: "Jessica Phoenix Canady", body: body] ++ Map.to_list(attrs))

View file

@ -0,0 +1,13 @@
defmodule JOLWeb.BlogController do
use JOLWeb, :controller
alias JOL.Blog
def index(conn, _params) do
render(conn, "index.html", posts: Blog.recent_posts())
end
def show(conn, %{"slug" => slug}) do
render(conn, "show.html", post: Blog.get_post_by_slug!(slug))
end
end

View file

@ -0,0 +1,5 @@
defmodule JOLWeb.BlogHTML do
use JOLWeb, :html
embed_templates "blog_html/*"
end

View file

@ -0,0 +1,7 @@
<h1>The Blog</h1>
<ul>
<%= for post <- @posts do %>
<li><.link href={~p"/blog/#{post.slug}"}><%= post.title %></.link></li>
<% end %>
</ul>

View file

@ -0,0 +1,13 @@
<.link href={~p"/blog"}>← All posts</.link>
<h1><%= @post.title %></h1>
<p>
<time><%= @post.date %></time> by <%= @post.author %>
</p>
<p>
Tagged as <%= Enum.join(@post.tags, ", ") %>
</p>
<%= raw @post.body %>

View file

@ -23,6 +23,9 @@ defmodule JOLWeb.Router do
get "/about", PageController, :about
get "/now", PageController, :now
get "/code", PageController, :code
get "/blog", BlogController, :index
get "/blog/:slug", BlogController, :show
end
# Other scopes may use custom stacks.

View file

@ -1,4 +1,5 @@
+++
slug = "mumble_voice_chat"
title = "LAN Voice Chat with Mumble"
date = 2024-04-16 11:51:33-04:00
draft = false

View file

@ -1,4 +1,5 @@
+++
slug = "odyssey_ark_gen2_kvm"
title = "HOWTO: Use the KVM in the Odyssey Ark Gen2"
draft = false
date = 2024-01-02 14:00:00-05:00

View file

@ -1,5 +1,6 @@
+++
title = "HOWTO: Fix Steam Deck Unresponsive Touchscreen"
slug = "fix_steam_deck_touchscreen"
date = 2024-01-07 13:40:00-05:00
[taxonomies]

View file

@ -1,5 +1,6 @@
+++
title = "The Names We Discard"
slug = "names_we_discard"
date = 2024-01-30 15:53:22-05:00
[taxonomies]

View file

@ -6,6 +6,7 @@ defmodule JOL.Blog.ParserTest do
content = """
+++
title = "test post"
slug = "test_post"
draft = false
date = 2024-01-02 14:00:00-05:00
@ -29,6 +30,10 @@ defmodule JOL.Blog.ParserTest do
assert post.attrs.title == "test post"
end
test "parses the title from zola-style posts", post do
assert post.attrs.title == "test_post"
end
test "parses the tags from zola-style posts", post do
assert post.attrs.tags == ["howto", "hardware"]
end