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.
78 lines
2.0 KiB
Elixir
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
|