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: [
|
patterns: [
|
||||||
~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
|
~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
|
||||||
~r"priv/gettext/.*(po)$",
|
~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 JOL.Blog do
|
||||||
|
defmodule NotFoundError do
|
||||||
|
defexception [:message, plug_status: 404]
|
||||||
|
end
|
||||||
|
|
||||||
use NimblePublisher,
|
use NimblePublisher,
|
||||||
build: JOL.Blog.Post,
|
build: JOL.Blog.Post,
|
||||||
from: Application.app_dir(:jol, "priv/posts/**/*.md"),
|
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})
|
@posts Enum.sort_by(@posts, & &1.date, {:desc, Date})
|
||||||
@tags @posts |> Enum.flat_map(& &1.tags) |> Enum.uniq() |> Enum.sort()
|
@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 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
|
end
|
||||||
|
|
|
@ -24,7 +24,8 @@ defmodule JOL.Blog.Parser do
|
||||||
title: toml_attrs["title"],
|
title: toml_attrs["title"],
|
||||||
draft: toml_attrs["draft"],
|
draft: toml_attrs["draft"],
|
||||||
tags: toml_attrs["taxonomies"]["tags"],
|
tags: toml_attrs["taxonomies"]["tags"],
|
||||||
date: toml_attrs["date"]
|
date: toml_attrs["date"],
|
||||||
|
slug: toml_attrs["slug"]
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed_body = String.trim(body)
|
parsed_body = String.trim(body)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
defmodule JOL.Blog.Post do
|
defmodule JOL.Blog.Post do
|
||||||
@enforce_keys [:author, :draft, :title, :body, :tags, :date]
|
@enforce_keys [:author, :title, :body, :tags, :date, :slug]
|
||||||
defstruct [:author, :draft, :title, :body, :tags, :date]
|
defstruct [:author, :draft, :title, :body, :tags, :date, :slug]
|
||||||
|
|
||||||
def build(_filename, attrs, body) do
|
def build(_filename, attrs, body) do
|
||||||
struct!(__MODULE__, [author: "Jessica Phoenix Canady", body: body] ++ Map.to_list(attrs))
|
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
|
scope "/", JOLWeb do
|
||||||
pipe_through :browser
|
pipe_through :browser
|
||||||
|
|
||||||
get "/", PageController, :home
|
get "/blog", BlogController, :index
|
||||||
|
get "/blog/:slug", BlogController, :show
|
||||||
end
|
end
|
||||||
|
|
||||||
# Other scopes may use custom stacks.
|
# Other scopes may use custom stacks.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
+++
|
+++
|
||||||
|
slug = "mumble_voice_chat"
|
||||||
title = "LAN Voice Chat with Mumble"
|
title = "LAN Voice Chat with Mumble"
|
||||||
date = 2024-04-16 11:51:33-04:00
|
date = 2024-04-16 11:51:33-04:00
|
||||||
draft = false
|
draft = false
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
+++
|
+++
|
||||||
|
slug = "odyssey_ark_gen2_kvm"
|
||||||
title = "HOWTO: Use the KVM in the Odyssey Ark Gen2"
|
title = "HOWTO: Use the KVM in the Odyssey Ark Gen2"
|
||||||
draft = false
|
draft = false
|
||||||
date = 2024-01-02 14:00:00-05:00
|
date = 2024-01-02 14:00:00-05:00
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
+++
|
+++
|
||||||
title = "HOWTO: Fix Steam Deck Unresponsive Touchscreen"
|
title = "HOWTO: Fix Steam Deck Unresponsive Touchscreen"
|
||||||
|
slug = "fix_steam_deck_touchscreen"
|
||||||
date = 2024-01-07 13:40:00-05:00
|
date = 2024-01-07 13:40:00-05:00
|
||||||
|
|
||||||
[taxonomies]
|
[taxonomies]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
+++
|
+++
|
||||||
title = "The Names We Discard"
|
title = "The Names We Discard"
|
||||||
|
slug = "names_we_discard"
|
||||||
date = 2024-01-30 15:53:22-05:00
|
date = 2024-01-30 15:53:22-05:00
|
||||||
|
|
||||||
[taxonomies]
|
[taxonomies]
|
||||||
|
|
|
@ -6,6 +6,7 @@ defmodule JOL.Blog.ParserTest do
|
||||||
content = """
|
content = """
|
||||||
+++
|
+++
|
||||||
title = "test post"
|
title = "test post"
|
||||||
|
slug = "test_post"
|
||||||
draft = false
|
draft = false
|
||||||
date = 2024-01-02 14:00:00-05:00
|
date = 2024-01-02 14:00:00-05:00
|
||||||
|
|
||||||
|
@ -29,6 +30,10 @@ defmodule JOL.Blog.ParserTest do
|
||||||
assert post.attrs.title == "test post"
|
assert post.attrs.title == "test post"
|
||||||
end
|
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
|
test "parses the tags from zola-style posts", post do
|
||||||
assert post.attrs.tags == ["howto", "hardware"]
|
assert post.attrs.tags == ["howto", "hardware"]
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue