diff --git a/lib/home73k_web/controllers/feed_controller.ex b/lib/home73k_web/controllers/feed_controller.ex index 0b7a4b5..eaf9cba 100644 --- a/lib/home73k_web/controllers/feed_controller.ex +++ b/lib/home73k_web/controllers/feed_controller.ex @@ -1,5 +1,7 @@ defmodule Home73kWeb.FeedController do use Home73kWeb, :controller + plug :put_layout, false + plug :put_root_layout, false alias Home73k.Blog @@ -9,7 +11,6 @@ defmodule Home73kWeb.FeedController do conn |> put_resp_content_type("application/rss+xml") - |> put_layout(:false) |> render("rss.xml", posts: posts, last_build_date: last_build_date) end end diff --git a/lib/home73k_web/live/blog_live.html.leex b/lib/home73k_web/live/blog_live.html.leex index a747291..6e9578f 100644 --- a/lib/home73k_web/live/blog_live.html.leex +++ b/lib/home73k_web/live/blog_live.html.leex @@ -26,7 +26,7 @@ <%= if length(post.tags) > 0 do %> -
+
<%= icon_div @socket, "mdi-tag-multiple", [class: "icon baseline text-gray-300"] %> <%= for {tag, i} <- Enum.with_index(post.tags) do %> #<%= live_redirect tag, to: Routes.blog_path(@socket, :tag, tag) %><%= i < (length(post.tags) - 1) && "," || "" %> diff --git a/lib/home73k_web/router.ex b/lib/home73k_web/router.ex index c3c2599..a276747 100644 --- a/lib/home73k_web/router.ex +++ b/lib/home73k_web/router.ex @@ -3,7 +3,7 @@ defmodule Home73kWeb.Router do alias Home73kWeb.CSPHeader pipeline :browser do - plug :accepts, ["html"] + plug :accepts, ~w(html xml) plug :fetch_session plug :fetch_live_flash plug :put_root_layout, {Home73kWeb.LayoutView, :root} @@ -12,10 +12,6 @@ defmodule Home73kWeb.Router do plug CSPHeader end - pipeline :xml_rss do - plug :accepts, ["xml", "rss", "atom"] - end - pipeline :api do plug :accepts, ["json"] end @@ -36,13 +32,9 @@ defmodule Home73kWeb.Router do live "/blog/page/:page", BlogLive, :page live "/blog/tag/:tag", BlogLive, :tag live "/blog/:id", BlogLive, :show - end - - scope "/feed", Home73kWeb do - pipe_through :xml_rss # Feeds - get "/", FeedController, :rss + get "/feed", FeedController, :rss end # Other scopes may use custom stacks. diff --git a/priv/content/2021/04/2021-04-07_rss-feed-phoenix-liveview.md b/priv/content/2021/04/2021-04-07_rss-feed-phoenix-liveview.md new file mode 100644 index 0000000..d92a922 --- /dev/null +++ b/priv/content/2021/04/2021-04-07_rss-feed-phoenix-liveview.md @@ -0,0 +1,32 @@ +--- +%{ + title: "RSS Feed When Using Elixir Phoenix LiveView", + id: "rss-feed-elixir-phoenix-liveview", + date: ~N[2021-04-07 12:31:00], + author: "Adam Piontek", + tags: ~w(tech elixir phoenix liveview coding routing rss feed development) +} +--- + +While [re-implementing my website in elixir/phoenix](/blog/blog-incorporated-2021), I wanted to include an RSS feed for the blog posts. Luckily I found pretty much everything I needed in Daniel Wachtel's [Building an RSS Feed with Phoenix](https://danielwachtel.com/phoenix/building-rss-feed-phoenix) post, but since I'm making use of LiveView, I ran into one hiccup --- errors about a missing `root.xml` layout! + + + +LiveView changes how Phoenix handles layouts --- there's a `root.html.leex` layout, and then for live views, a `live.html.leex` sub-layout, and for regular controller views, an `app.html.eex` sub-layout. + +Without LiveView, Daniel's controller directive `plug :put_layout, false`{:.lang-elixir} would be enough, but with LiveView, Phoenix is still looking for the *root* layout template, which for my `index.html` would be `root.xml` ... what to do? + +One option would be to create a whole separate router pipeline to skip the `plug :put_root_layout, {Home73kWeb.LayoutView, :root}`{:.lang-elixir} directive. It would work, but is a heavier approach. + +But luckily, there's a new [put_root_layout/2](https://hexdocs.pm/phoenix/Phoenix.Controller.html#put_root_layout/2) that we can leverage like so: + +```elixir +defmodule YourAppWeb.RSSController do + use YourAppWeb, :controller + plug :put_layout, false + + ... +end +``` + +With this in place, the rss xml is served plain, just like we want.