Item views (#7)
* Add Earmark dependency For markdown to HTML conversion * Display items by slug: articles, pages * Handle 401 Forbidden responses in Directus * Add item controller as pokemon route * Strip out generated layouts * Plan future routes * Look for item in order: article, link, event, album * Add item templates
This commit is contained in:
parent
e907e347c9
commit
8bbe8a1b24
13 changed files with 264 additions and 70 deletions
|
|
@ -7,12 +7,16 @@ defmodule Mse25.Directus do
|
|||
params =
|
||||
[
|
||||
"sort=-pubDate",
|
||||
"fields=" <> Enum.join([
|
||||
"slug",
|
||||
"title",
|
||||
"date_updated",
|
||||
"pubDate"
|
||||
], ",")
|
||||
"fields=" <>
|
||||
Enum.join(
|
||||
[
|
||||
"slug",
|
||||
"title",
|
||||
"date_updated",
|
||||
"pubDate"
|
||||
],
|
||||
","
|
||||
)
|
||||
]
|
||||
|> query_params_string(options)
|
||||
|
||||
|
|
@ -41,18 +45,22 @@ defmodule Mse25.Directus do
|
|||
params =
|
||||
[
|
||||
"sort=-started_at",
|
||||
#"filter={\"upcoming\":{\"_eq\":true}}",
|
||||
"fields=" <> Enum.join([
|
||||
"started_at",
|
||||
"ended_at",
|
||||
"title",
|
||||
"lead",
|
||||
"poster.filename_download",
|
||||
"poster.width",
|
||||
"poster.height",
|
||||
"bands.artists_id.name",
|
||||
"mia.artists_id.name"
|
||||
], ",")
|
||||
# "filter={\"upcoming\":{\"_eq\":true}}",
|
||||
"fields=" <>
|
||||
Enum.join(
|
||||
[
|
||||
"started_at",
|
||||
"ended_at",
|
||||
"title",
|
||||
"lead",
|
||||
"poster.filename_download",
|
||||
"poster.width",
|
||||
"poster.height",
|
||||
"bands.artists_id.name",
|
||||
"mia.artists_id.name"
|
||||
],
|
||||
","
|
||||
)
|
||||
]
|
||||
|> query_params_string(options)
|
||||
|
||||
|
|
@ -67,15 +75,19 @@ defmodule Mse25.Directus do
|
|||
params =
|
||||
[
|
||||
"sort=-pubDate",
|
||||
"fields=" <> Enum.join([
|
||||
"slug",
|
||||
"title",
|
||||
"date_updated",
|
||||
"pubDate",
|
||||
"h1",
|
||||
"source",
|
||||
"contents"
|
||||
], ",")
|
||||
"fields=" <>
|
||||
Enum.join(
|
||||
[
|
||||
"slug",
|
||||
"title",
|
||||
"date_updated",
|
||||
"pubDate",
|
||||
"h1",
|
||||
"source",
|
||||
"contents"
|
||||
],
|
||||
","
|
||||
)
|
||||
]
|
||||
|> query_params_string(options)
|
||||
|
||||
|
|
@ -99,11 +111,16 @@ defmodule Mse25.Directus do
|
|||
[base_url: base_url, token: token] = Application.fetch_env!(:mse25, :directus)
|
||||
req = Req.new(base_url: base_url <> "/items")
|
||||
|
||||
Req.get!(req, url: resource, auth: {:bearer, token})
|
||||
|> payload
|
||||
case Req.get!(req, url: resource, auth: {:bearer, token})
|
||||
|> payload do
|
||||
{:ok, payload} -> payload
|
||||
{:forbidden, message} -> message
|
||||
end
|
||||
end
|
||||
|
||||
defp payload(%Req.Response{body: %{"data" => payload}}), do: payload
|
||||
defp payload(%Req.Response{status: 200, body: %{"data" => payload}}), do: {:ok, payload}
|
||||
|
||||
defp payload(%Req.Response{status: 401}), do: {:forbidden, "Invalid Directus credentials"}
|
||||
|
||||
defp query_params_string(params, options),
|
||||
do:
|
||||
|
|
|
|||
|
|
@ -1,32 +1,32 @@
|
|||
<header class="px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center justify-between border-b border-zinc-100 py-3 text-sm">
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="/">
|
||||
<img src={~p"/images/logo.svg"} width="36" />
|
||||
</a>
|
||||
<p class="bg-brand/5 text-brand rounded-full px-2 font-medium leading-6">
|
||||
v<%= Application.spec(:phoenix, :vsn) %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-4 font-semibold leading-6 text-zinc-900">
|
||||
<a href="https://twitter.com/elixirphoenix" class="hover:text-zinc-700">
|
||||
@elixirphoenix
|
||||
</a>
|
||||
<a href="https://github.com/phoenixframework/phoenix" class="hover:text-zinc-700">
|
||||
GitHub
|
||||
</a>
|
||||
<a
|
||||
href="https://hexdocs.pm/phoenix/overview.html"
|
||||
class="rounded-lg bg-zinc-100 px-2 py-1 hover:bg-zinc-200/80"
|
||||
>
|
||||
Get Started <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="px-4 py-20 sm:px-6 lg:px-8">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<.flash_group flash={@flash} />
|
||||
<%= @inner_content %>
|
||||
</div>
|
||||
</main>
|
||||
<b>madr</b><br>
|
||||
|> Hårdrock<br>
|
||||
|> Programmering<br>
|
||||
|> Ljudteknik<br>
|
||||
|> Åsikter
|
||||
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="/om">Om mig</a></li>
|
||||
<li><a href="/webblogg">Webblogg</a></li>
|
||||
<li><a href="/delningar">Delningar</a></li>
|
||||
<li><a href="/evenemang">Evenemang</a></li>
|
||||
<li><a href="/vad-jag-gor">Vad jag gör</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<form metod="get" action="/search">
|
||||
<label>Search site <input type="search" name="q"></label>
|
||||
</form>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/madr" rel="external">Github</a></li>
|
||||
<li><a href="https://linkedin.com/anders-ytterstrom" rel="external">LinkedIn</a></li>
|
||||
<li><a href="https://discogs.com/madr" rel="external">Discogs</a></li>
|
||||
<li><a href="https://songkick.com/madr" rel="external">Songkick</a></li>
|
||||
</ul>
|
||||
|
||||
<%= @inner_content %>
|
||||
|
||||
<footer>
|
||||
<p><a href="https://madr.se" rel="home">madr.se</a> av Anders Englöf Ytterström, sedan 2006. <a href="/colophon">Kolofon</a>.</p>
|
||||
</footer>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" class="[scrollbar-gutter:stable]">
|
||||
<html lang="sv">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="csrf-token" content={get_csrf_token()} />
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="csrf-token" content={get_csrf_token()}>
|
||||
<.live_title suffix=" · Phoenix Framework">
|
||||
<%= assigns[:page_title] || "Mse25" %>
|
||||
</.live_title>
|
||||
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
|
||||
<script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
|
||||
</script>
|
||||
<link rel="stylesheet" href={~p"/assets/app.css"}>
|
||||
</head>
|
||||
<body class="bg-white">
|
||||
<%= @inner_content %>
|
||||
|
|
|
|||
100
lib/mse25_web/controllers/item_controller.ex
Normal file
100
lib/mse25_web/controllers/item_controller.ex
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
defmodule Mse25Web.ItemController do
|
||||
use Mse25Web, :controller
|
||||
alias Mse25.Directus
|
||||
|
||||
def index(conn, _params) do
|
||||
case conn.path_info |> fetch do
|
||||
{:ok, item_type, item_data} ->
|
||||
render(conn, item_type, assigns(item_type, item_data))
|
||||
|
||||
{:not_found, message} ->
|
||||
render(conn, message)
|
||||
end
|
||||
end
|
||||
|
||||
defp fetch([year, slug], :article) do
|
||||
case Directus.get_article(year <> "/" <> slug) do
|
||||
{:ok, response} -> {:ok, :article, response}
|
||||
_ -> fetch([year, slug], :link)
|
||||
end
|
||||
end
|
||||
|
||||
defp fetch([year, slug], :link) do
|
||||
case Directus.get_link(year <> "/" <> slug) do
|
||||
{:ok, response} -> {:ok, :link, response}
|
||||
_ -> fetch([year, slug], :event)
|
||||
end
|
||||
end
|
||||
|
||||
defp fetch([year, slug], :event) do
|
||||
case Directus.get_event(year <> "/" <> slug) do
|
||||
{:ok, response} -> {:ok, :event, response}
|
||||
not_found -> not_found
|
||||
end
|
||||
end
|
||||
|
||||
defp fetch([year, slug]) do
|
||||
fetch([year, slug], :article)
|
||||
end
|
||||
|
||||
defp fetch([slug]) do
|
||||
case Directus.get_page(slug) do
|
||||
{:ok, response} -> {:ok, :page, response}
|
||||
not_found -> not_found
|
||||
end
|
||||
end
|
||||
|
||||
defp assigns(:article, %{
|
||||
"title" => heading,
|
||||
"contents" => contents,
|
||||
"pubDate" => published_at,
|
||||
"date_updated" => updated_at
|
||||
}) do
|
||||
[
|
||||
heading: heading,
|
||||
contents: Earmark.as_html!(contents),
|
||||
published_at: published_at,
|
||||
updated_at: updated_at
|
||||
]
|
||||
end
|
||||
|
||||
defp assigns(:event, %{
|
||||
"title" => heading,
|
||||
"contents" => contents,
|
||||
"started_at" => published_at
|
||||
}) do
|
||||
[
|
||||
heading: heading,
|
||||
contents: Earmark.as_html!(contents),
|
||||
published_at: published_at
|
||||
]
|
||||
end
|
||||
|
||||
defp assigns(:link, %{
|
||||
"title" => heading,
|
||||
"contents" => contents,
|
||||
"pubDate" => published_at,
|
||||
"source" => url,
|
||||
"h1" => title
|
||||
}) do
|
||||
[
|
||||
heading: heading,
|
||||
contents: Earmark.as_html!(contents),
|
||||
published_at: published_at,
|
||||
url: url,
|
||||
title: title
|
||||
]
|
||||
end
|
||||
|
||||
defp assigns(:page, %{
|
||||
"title" => heading,
|
||||
"contents" => contents,
|
||||
"date_updated" => updated_at
|
||||
}) do
|
||||
[
|
||||
heading: heading,
|
||||
contents: Earmark.as_html!(contents),
|
||||
updated_at: updated_at
|
||||
]
|
||||
end
|
||||
end
|
||||
5
lib/mse25_web/controllers/item_html.ex
Normal file
5
lib/mse25_web/controllers/item_html.ex
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
defmodule Mse25Web.ItemHTML do
|
||||
use Mse25Web, :html
|
||||
|
||||
embed_templates "item_html/*"
|
||||
end
|
||||
12
lib/mse25_web/controllers/item_html/article.html.heex
Normal file
12
lib/mse25_web/controllers/item_html/article.html.heex
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<article>
|
||||
<header>
|
||||
<date><%= @published_at %></date>
|
||||
<h1><%= @heading %></h1>
|
||||
</header>
|
||||
|
||||
<%= raw @contents %>
|
||||
|
||||
<footer>
|
||||
<p>Skribent: Anders Englöf Ytterström. Publicerad <%= @published_at %> och senast uppdaterad <%= @updated_at %>.</p>
|
||||
</footer>
|
||||
</article>
|
||||
9
lib/mse25_web/controllers/item_html/event.html.heex
Normal file
9
lib/mse25_web/controllers/item_html/event.html.heex
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<article>
|
||||
<header>
|
||||
<date><%= @published_at %></date>
|
||||
<h1><%= @heading %></h1>
|
||||
</header>
|
||||
|
||||
<%= raw @contents %>
|
||||
|
||||
</article>
|
||||
14
lib/mse25_web/controllers/item_html/link.html.heex
Normal file
14
lib/mse25_web/controllers/item_html/link.html.heex
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<article>
|
||||
<header>
|
||||
<date><%= @published_at %></date>
|
||||
<h1><%= @heading %></h1>
|
||||
</header>
|
||||
|
||||
<%= raw @contents %>
|
||||
<p>
|
||||
Källa: <a href={@url} rel="external"><%= @title %></a>
|
||||
</p>
|
||||
<footer>
|
||||
<p>Skribent: Anders Englöf Ytterström. Publicerad <%= @published_at %>.</p>
|
||||
</footer>
|
||||
</article>
|
||||
11
lib/mse25_web/controllers/item_html/page.html.heex
Normal file
11
lib/mse25_web/controllers/item_html/page.html.heex
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<article>
|
||||
<header>
|
||||
<h1><%= @heading %></h1>
|
||||
</header>
|
||||
|
||||
<%= raw @contents %>
|
||||
|
||||
<footer>
|
||||
<p>Skribent: Anders Englöf Ytterström. Senast uppdaterad <%= @updated_at %>.</p>
|
||||
</footer>
|
||||
</article>
|
||||
12
lib/mse25_web/controllers/item_html/show.html.heex
Normal file
12
lib/mse25_web/controllers/item_html/show.html.heex
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<article>
|
||||
<header>
|
||||
<date><%= @published_at %></date>
|
||||
<h1><%= @heading %></h1>
|
||||
</header>
|
||||
|
||||
<%= raw @contents %>
|
||||
|
||||
<footer>
|
||||
<p>Skribent: Anders Englöf Ytterström. Publicerad <%= @published_at %> och senast uppdaterad <%= @updated_at %>.</p>
|
||||
</footer>
|
||||
</article>
|
||||
|
|
@ -18,6 +18,20 @@ defmodule Mse25Web.Router do
|
|||
pipe_through :browser
|
||||
|
||||
get "/", PageController, :home
|
||||
|
||||
# get "/evenemang", EventController, :index
|
||||
# get "/kommande-evenemang.ics", EventController, :calendar
|
||||
# get "/event-map.js", EventController, :interactive_map
|
||||
|
||||
# get "/webblogg", ArticleController, :index
|
||||
# get "/webblogg/prenumerera.xml", ArticleController, :feed
|
||||
|
||||
# get "/delningar", ShareController, :index
|
||||
# get "/delningar/prenumerera.xml", ShareController, :feed
|
||||
|
||||
# get "/:year", TimelineController, :annual
|
||||
# get "/prenumerera.xml", TimelineController, :feed
|
||||
get "/*path", ItemController, :index
|
||||
end
|
||||
|
||||
# Other scopes may use custom stacks.
|
||||
|
|
|
|||
3
mix.exs
3
mix.exs
|
|
@ -45,7 +45,8 @@ defmodule Mse25.MixProject do
|
|||
{:jason, "~> 1.2"},
|
||||
{:dns_cluster, "~> 0.1.1"},
|
||||
{:bandit, "~> 1.5"},
|
||||
{:req, "~> 0.5.0"}
|
||||
{:req, "~> 0.5.0"},
|
||||
{:earmark, "~> 1.4"}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
|||
1
mix.lock
1
mix.lock
|
|
@ -2,6 +2,7 @@
|
|||
"bandit": {:hex, :bandit, "1.5.7", "6856b1e1df4f2b0cb3df1377eab7891bec2da6a7fd69dc78594ad3e152363a50", [:mix], [{:hpax, "~> 1.0.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "f2dd92ae87d2cbea2fa9aa1652db157b6cba6c405cb44d4f6dd87abba41371cd"},
|
||||
"castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"},
|
||||
"dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"},
|
||||
"earmark": {:hex, :earmark, "1.4.47", "7e7596b84fe4ebeb8751e14cbaeaf4d7a0237708f2ce43630cfd9065551f94ca", [:mix], [], "hexpm", "3e96bebea2c2d95f3b346a7ff22285bc68a99fbabdad9b655aa9c6be06c698f8"},
|
||||
"esbuild": {:hex, :esbuild, "0.8.1", "0cbf919f0eccb136d2eeef0df49c4acf55336de864e63594adcea3814f3edf41", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "25fc876a67c13cb0a776e7b5d7974851556baeda2085296c14ab48555ea7560f"},
|
||||
"expo": {:hex, :expo, "1.0.1", "f9e2f984f5b8d195815d52d0ba264798c12c8d2f2606f76fa4c60e8ebe39474d", [:mix], [], "hexpm", "f250b33274e3e56513644858c116f255d35c767c2b8e96a512fe7839ef9306a1"},
|
||||
"file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue