firehose/blogex/examples/blog_live_index.ex
Your Name bc14696f57 Static blog with front page summary
Goal: have a personal blog, and try out another point in the 'modular
app design with elixir' space.

Designing OTP systems with elixir had some interesting ideas.
2026-03-17 11:17:21 +00:00

78 lines
2.0 KiB
Elixir

defmodule FirehoseWeb.BlogLive.Index do
@moduledoc """
Example LiveView for the blog index page.
Copy this into your host app and customize the layout/styling.
Replace `Firehose.EngineeringBlog` with your actual blog module.
"""
use MyAppWeb, :live_view
import Blogex.Components
@impl true
def mount(%{"blog" => blog_id} = _params, _session, socket) do
blog = Blogex.get_blog!(String.to_existing_atom(blog_id))
{:ok,
socket
|> assign(:blog, blog)
|> assign(:page_title, blog.title())}
end
@impl true
def handle_params(params, _uri, socket) do
page = String.to_integer(params["page"] || "1")
tag = params["tag"]
blog = socket.assigns.blog
posts =
if tag do
blog.posts_by_tag(tag)
else
blog.all_posts()
end
per_page = 10
total = length(posts)
total_pages = max(ceil(total / per_page), 1)
entries =
posts
|> Enum.drop((page - 1) * per_page)
|> Enum.take(per_page)
{:noreply,
socket
|> assign(:posts, entries)
|> assign(:tags, blog.all_tags())
|> assign(:current_tag, tag)
|> assign(:page, page)
|> assign(:total_pages, total_pages)
|> assign(:base_path, blog.base_path())}
end
@impl true
def render(assigns) do
~H"""
<div class="max-w-3xl mx-auto py-8 px-4">
<h1 class="text-3xl font-bold mb-2">{@blog.title()}</h1>
<p class="text-gray-600 mb-8">{@blog.description()}</p>
<.tag_list tags={@tags} base_path={@base_path} current_tag={@current_tag} />
<div class="mt-8">
<.post_index posts={@posts} base_path={@base_path} />
</div>
<.pagination page={@page} total_pages={@total_pages} base_path={@base_path} />
<div class="mt-8 text-sm text-gray-500">
<a href={"#{@base_path}/feed.xml"} class="hover:underline">RSS Feed</a>
·
<a href={"#{@base_path}/atom.xml"} class="hover:underline">Atom Feed</a>
</div>
</div>
"""
end
end