defmodule Sayfa.Blocks.RecentPosts do @moduledoc """ Recent posts block. Renders a chronological list of the most recent posts with date and title. ## Assigns - `:contents` — list of all site contents (injected by block helper) - `:limit` — number of posts to show (default: 5) - `:show_view_all` — whether to show "View all" link (default: false) ## Examples <%= @block.(:recent_posts, limit: 3) %> <%= @block.(:recent_posts, limit: 5, show_view_all: true) %> """ @behaviour Sayfa.Behaviours.Block alias Sayfa.Block alias Sayfa.Content alias Sayfa.I18n @impl true def name, do: :recent_posts @impl true def render(assigns) do contents = Map.get(assigns, :contents, []) limit = Map.get(assigns, :limit, 5) show_view_all = Map.get(assigns, :show_view_all, false) t = Map.get(assigns, :t, I18n.default_translate_function()) lang = Map.get(assigns, :lang) site = Map.get(assigns, :site, %{}) contents = filter_by_lang(contents, lang) lang_prefix = lang_prefix_path(lang, site) posts = contents |> Content.all_of_type("posts") |> Content.recent(limit) if posts == [] do "" else items = Enum.map_join(posts, "\n", &render_post_item(&1, lang, site)) view_all_html = if show_view_all do "#{Block.escape_html(t.("view_all"))} " else "" end """
\
\

#{Block.escape_html(t.("recent_posts"))}

\ #{view_all_html}\
\
\ #{items}\
\
\ """ end end defp render_post_item(post, lang, site) do url = Content.url(post) title = Block.escape_html(post.title) date_html = if post.date do "" else "" end """ \ #{date_html}\ #{title}\ \ """ end defp filter_by_lang(contents, nil), do: contents defp filter_by_lang(contents, lang) do Enum.filter(contents, &(&1.lang == lang)) end defp lang_prefix_path(nil, _site), do: "" defp lang_prefix_path(lang, site) do case I18n.language_prefix(lang, site) do "" -> "" prefix -> "/#{prefix}" end end end