Add controllers/templates to show blog posts.
This commit is contained in:
parent
274f2b0068
commit
77c7828d61
|
@ -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)$"
|
||||
]
|
||||
]
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule JOL.Blog do
|
||||
defmodule NotFoundError do
|
||||
defexception [:message, plug_status: 404]
|
||||
end
|
||||
|
||||
use NimblePublisher,
|
||||
build: JOL.Blog.Post,
|
||||
from: Application.app_dir(:jol, "priv/posts/**/*.md"),
|
||||
|
@ -8,6 +12,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()
|
||||
|
||||
def posts, do: @posts
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
13
lib/jol_web/controllers/blog_controller.ex
Normal file
13
lib/jol_web/controllers/blog_controller.ex
Normal 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
|
5
lib/jol_web/controllers/blog_html.ex
Normal file
5
lib/jol_web/controllers/blog_html.ex
Normal file
|
@ -0,0 +1,5 @@
|
|||
defmodule JOLWeb.BlogHTML do
|
||||
use JOLWeb, :html
|
||||
|
||||
embed_templates "blog_html/*"
|
||||
end
|
7
lib/jol_web/controllers/blog_html/index.heex
Normal file
7
lib/jol_web/controllers/blog_html/index.heex
Normal 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>
|
13
lib/jol_web/controllers/blog_html/show.heex
Normal file
13
lib/jol_web/controllers/blog_html/show.heex
Normal 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 %>
|
|
@ -17,7 +17,8 @@ defmodule JOLWeb.Router do
|
|||
scope "/", JOLWeb do
|
||||
pipe_through :browser
|
||||
|
||||
get "/", PageController, :home
|
||||
get "/blog", BlogController, :index
|
||||
get "/blog/:slug", BlogController, :show
|
||||
end
|
||||
|
||||
# Other scopes may use custom stacks.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
+++
|
||||
title = "The Names We Discard"
|
||||
slug = "names_we_discard"
|
||||
date = 2024-01-30 15:53:22-05:00
|
||||
|
||||
[taxonomies]
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue