From a6d34d17fcc48df4feaa5daf21c23e21bafcccea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Engl=C3=B6f=20Ytterstr=C3=B6m?= Date: Thu, 3 Oct 2024 22:52:40 +0200 Subject: [PATCH] List and show events (#17) * Improve Directus client - Rearrange and group functions to match - Allow whitespace when searching - provide category to event list * Add event list view * Show band information on festival-ish events * Extract view helpers to reusable module Code is shared between ItemHTML and PageHTML, and they really do not belong in web anyway since it is usable outside web scope as well. * Rename utils to event helpers It is a file that handles the poor design choice of the datamodel for events, so let the module name describe that. * Sync event view - Replace scaffold markup with production markup - Send more data from Directus client --- lib/mse25/directus.ex | 50 ++++++------- lib/mse25/event_helpers.ex | 33 +++++++++ lib/mse25_web/controllers/item_controller.ex | 15 ++-- lib/mse25_web/controllers/item_html.ex | 1 + .../controllers/item_html/event.html.heex | 48 +++++++++++-- lib/mse25_web/controllers/page_controller.ex | 27 +++++-- lib/mse25_web/controllers/page_html.ex | 1 + .../controllers/page_html/events.html.heex | 72 +++++++++++++++++++ lib/mse25_web/router.ex | 8 +-- 9 files changed, 209 insertions(+), 46 deletions(-) create mode 100644 lib/mse25/event_helpers.ex create mode 100644 lib/mse25_web/controllers/page_html/events.html.heex diff --git a/lib/mse25/directus.ex b/lib/mse25/directus.ex index adc703f..8d0ac70 100644 --- a/lib/mse25/directus.ex +++ b/lib/mse25/directus.ex @@ -25,19 +25,19 @@ defmodule Mse25.Directus do get("/articles?" <> params) end - def get_event(slug) do + def get_album(externalId) do get_item( - :events, - slug, + :albums, + externalId, [ - "*", - "location.*", - "poster.filename_download", - "poster.width", - "poster.height", - "bands.artists_id.name", - "mia.artists_id.name", - "location.name" + "purchased_at", + "album", + "year", + "youtubeId", + "externalId", + "cover", + "songs.title", + "songs.artist.name" ] |> Enum.join(",") ) @@ -71,21 +71,16 @@ defmodule Mse25.Directus do end) end - def get_album(externalId) do + def get_event(slug) do get_item( - :albums, - externalId, + :events, + slug, [ - "purchased_at", - "album", - "year", - "youtubeId", - "externalId", - "cover.filename_download", - "cover.width", - "cover.height", - "songs.title", - "songs.artist.name" + "*", + "location.*", + "poster", + "bands.artists_id.name", + "mia.artists_id.name" ] |> Enum.join(",") ) @@ -108,9 +103,8 @@ defmodule Mse25.Directus do "title", "lead", "slug", - "poster.filename_download", - "poster.width", - "poster.height", + "poster", + "category", "bands.artists_id.name", "mia.artists_id.name" ], @@ -218,7 +212,7 @@ defmodule Mse25.Directus do case opts[:query] do nil -> params "" -> params - pg -> ["filter[title][_icontains]=" <> to_string(pg) | params] + pg -> ["filter[title][_icontains]=" <> String.replace(to_string(pg), " ", "%20") | params] end end end diff --git a/lib/mse25/event_helpers.ex b/lib/mse25/event_helpers.ex new file mode 100644 index 0000000..20fb630 --- /dev/null +++ b/lib/mse25/event_helpers.ex @@ -0,0 +1,33 @@ +defmodule Mse25.EventHelpers do + def bandlist(bands) do + bands + |> Enum.map(fn b -> b["artists_id"]["name"] end) + |> Enum.join(", ") + |> String.replace(~r/, ([^,]+?)$/, " och \\1") + end + + def hilights?(%{"bands" => bands, "category" => category}) do + _festival_band?(bands, category) + end + + def missed?(%{"mia" => bands, "category" => category}) do + _festival_band?(bands, category) + end + + def opening_acts?(%{"bands" => [_ | bands], "category" => "concert"}) do + not Enum.empty?(bands) + end + + def opening_acts?(_) do + false + end + + def _festival_band?(bands, category) + when category in ["cruise", "openairfestival", "cityfestival", "onedayfestival"] do + not Enum.empty?(bands) + end + + def _festival_band?(_b, _c) do + false + end +end diff --git a/lib/mse25_web/controllers/item_controller.ex b/lib/mse25_web/controllers/item_controller.ex index ed456bb..4e48c0c 100644 --- a/lib/mse25_web/controllers/item_controller.ex +++ b/lib/mse25_web/controllers/item_controller.ex @@ -67,16 +67,23 @@ defmodule Mse25Web.ItemController do defp assigns(:event, %{ "title" => heading, "contents" => contents, - "started_at" => published_at, - "lead" => lead + "started_at" => started_at, + "lead" => lead, + "poster" => poster, + "bands" => bands, + "mia" => mia, + "category" => category }) do [ page_title: heading, heading: heading, contents: Earmark.as_html!(contents), - published_at: published_at, lead: lead, - year: String.slice(published_at, 0..3) + year: String.slice(started_at, 0..3), + poster: poster, + bands: bands, + mia: mia, + category: category ] end diff --git a/lib/mse25_web/controllers/item_html.ex b/lib/mse25_web/controllers/item_html.ex index 3d61b61..9a103f0 100644 --- a/lib/mse25_web/controllers/item_html.ex +++ b/lib/mse25_web/controllers/item_html.ex @@ -1,5 +1,6 @@ defmodule Mse25Web.ItemHTML do use Mse25Web, :html + import Mse25.EventHelpers embed_templates "item_html/*" end diff --git a/lib/mse25_web/controllers/item_html/event.html.heex b/lib/mse25_web/controllers/item_html/event.html.heex index 0a60fbf..f762f1c 100644 --- a/lib/mse25_web/controllers/item_html/event.html.heex +++ b/lib/mse25_web/controllers/item_html/event.html.heex @@ -1,9 +1,45 @@ -
-
-<%= @published_at %> -

<%= @heading %>

-
+
+
+ +

<%= @heading %>

+
-<%= raw @contents %> +
    +
  • <%= @lead %>
  • + <%= if opening_acts?(%{"bands" => @bands, "category" => @category}) do %> +
  • Huvudakt: <%= @bands |> List.first() |> Map.get("artists_id") |> Map.get("name") %>
  • +
  • Förband: <%= @bands |> Enum.drop(1) |> bandlist() %>
  • + <% end %> + <%= if hilights?(%{"bands" => @bands, "category" => @category}) do %> +
  • Personliga höjdpunkter: <%= @bands |> bandlist() %>
  • + <% end %> + <%= if missed?(%{"mia" => @mia, "category" => @category}) do %> +
  • Band jag missade: <%= @mia |> bandlist() %>
  • + <% end %> +
+ <%= raw(@contents) %> + + <%= if @poster do %> + @poster} alt="affisch" loading="lazy" /> + <% end %>
diff --git a/lib/mse25_web/controllers/page_controller.ex b/lib/mse25_web/controllers/page_controller.ex index c179238..43d3a9b 100644 --- a/lib/mse25_web/controllers/page_controller.ex +++ b/lib/mse25_web/controllers/page_controller.ex @@ -20,9 +20,9 @@ defmodule Mse25Web.PageController do ) end - def articles(conn, _params) do + def articles(conn, params) do articles = - case conn.params do + case params do %{"q" => query_string} -> Directus.get_articles!(limit: 9999, query: query_string) _ -> Directus.get_articles!(limit: 9999) end @@ -31,8 +31,27 @@ defmodule Mse25Web.PageController do render(conn, :articles, page_title: "Webblogg", articles: articles, - q: conn.params["q"], - nosearch?: conn.params["q"] == nil or conn.params["q"] == "" + q: params["q"], + nosearch?: params["q"] == nil or params["q"] == "" + ) + end + + def events(conn, params) do + {_, %{"title" => title, "contents" => contents}} = Directus.get_page("evenemang") + + events = + case params do + %{"q" => query_string} -> Directus.get_events!(limit: 9999, query: query_string) + _ -> Directus.get_events!(limit: 9999) + end + |> group_annually + + render(conn, :events, + page_title: title, + contents: Earmark.as_html!(contents), + events: events, + q: params["q"], + nosearch?: params["q"] == nil or params["q"] == "" ) end diff --git a/lib/mse25_web/controllers/page_html.ex b/lib/mse25_web/controllers/page_html.ex index c5fb665..6108818 100644 --- a/lib/mse25_web/controllers/page_html.ex +++ b/lib/mse25_web/controllers/page_html.ex @@ -5,6 +5,7 @@ defmodule Mse25Web.PageHTML do See the `page_html` directory for all templates available. """ use Mse25Web, :html + import Mse25.EventHelpers embed_templates "page_html/*" end diff --git a/lib/mse25_web/controllers/page_html/events.html.heex b/lib/mse25_web/controllers/page_html/events.html.heex new file mode 100644 index 0000000..8b9e9de --- /dev/null +++ b/lib/mse25_web/controllers/page_html/events.html.heex @@ -0,0 +1,72 @@ +
+ +

<%= @page_title %>

+ <%= raw(@contents) %> +

+ <%= if @nosearch? do %> + Gå direkt till: + <% end %> +

+
    + <%= for {year, events} <- @events do %> +
  • + year}><%= year %> (<%= Enum.count(events) %>) +
  • + <% end %> +
+
+

+ <%= if @nosearch? do %> + Eller + <% end %> + : + + +

+
+ <%= for {year, events} <- @events do %> +
year}> +

<%= year %>

+
+ <%= for event <- events do %> +
+

+ event["slug"]}><%= event["title"] %> +

+

<%= event["lead"] %>

+ <%= if hilights?(event) do %> +

+ Personliga höjdpunkter: <%= bandlist(event["bands"]) %> +

+ <% end %> + <%= if missed?(event) do %> +

+ Band jag missade: <%= bandlist(event["mia"]) %> +

+ <% end %> + <%= if opening_acts?(event) do %> +

+ Förband: <%= event["bands"] |> Enum.drop(1) |> bandlist() %> +

+ <% end %> + <%= if event["poster"] do %> + event["poster"]} + alt="affisch" + width="150" + /> + <% end %> +
+ <% end %> +
+
+ <% end %> +
diff --git a/lib/mse25_web/router.ex b/lib/mse25_web/router.ex index 636a273..b7d83ff 100644 --- a/lib/mse25_web/router.ex +++ b/lib/mse25_web/router.ex @@ -19,15 +19,15 @@ defmodule Mse25Web.Router do get "/", PageController, :home - # get "/evenemang", EventController, :index - # get "/kommande-evenemang.ics", EventController, :calendar - # get "/event-map.js", EventController, :interactive_map - + get "/evenemang", PageController, :events get "/webblogg", PageController, :articles get "/delningar", PageController, :links + # get "/kommande-evenemang.ics", EventController, :calendar + # get "/event-map.js", EventController, :interactive_map # get "/:year", TimelineController, :annual # get "/prenumerera.xml", TimelineController, :feed + get "/*path", ItemController, :index end