Filter future-dated posts from public views and add unfiltered post access

- all_posts/0 now excludes posts where date > today
- all_tags/0 computed at runtime from filtered posts
- posts_by_tag/1 and recent_posts/1 inherit date filtering
- Add unfiltered_posts/0 to Blog macro and FakeBlog
- Add all_posts_unfiltered/0 to Registry for dashboard use
This commit is contained in:
Willem van den Ende
2026-04-01 20:30:27 +00:00
parent 037e9f86ff
commit 0577ceced0
8 changed files with 99 additions and 6 deletions
+1
View File
@@ -119,5 +119,6 @@ defmodule Blogex do
defdelegate get_blog!(blog_id), to: Blogex.Registry
defdelegate get_blog(blog_id), to: Blogex.Registry
defdelegate all_posts, to: Blogex.Registry
defdelegate all_posts_unfiltered, to: Blogex.Registry
defdelegate all_tags, to: Blogex.Registry
end
+13 -3
View File
@@ -73,12 +73,17 @@ defmodule Blogex.Blog do
@doc "Returns the base URL path for this blog."
def base_path, do: @blog_base_path
@doc "Returns all compiled posts regardless of published status or date."
def unfiltered_posts, do: @posts
@doc "Returns all visible posts, newest first. Drafts are included in dev/test."
def all_posts do
today = Date.utc_today()
if Blogex.show_drafts?() do
@posts
Enum.filter(@posts, &(not Date.after?(&1.date, today)))
else
Enum.filter(@posts, & &1.published)
Enum.filter(@posts, &(&1.published and not Date.after?(&1.date, today)))
end
end
@@ -86,7 +91,12 @@ defmodule Blogex.Blog do
def recent_posts(n \\ 5), do: Enum.take(all_posts(), n)
@doc "Returns all unique tags across all published posts."
def all_tags, do: @tags
def all_tags do
all_posts()
|> Enum.flat_map(& &1.tags)
|> Enum.uniq()
|> Enum.sort()
end
@doc "Returns all published posts matching the given tag."
def posts_by_tag(tag) do
+7
View File
@@ -37,6 +37,13 @@ defmodule Blogex.Registry do
|> Enum.sort_by(& &1.date, {:desc, Date})
end
@doc "Returns all posts from all blogs (unfiltered), sorted newest first."
def all_posts_unfiltered do
blogs()
|> Enum.flat_map(& &1.unfiltered_posts())
|> Enum.sort_by(& &1.date, {:desc, Date})
end
@doc "Returns all unique tags across all blogs."
def all_tags do
blogs()
+35
View File
@@ -15,6 +15,24 @@ defmodule Blogex.BlogTest do
assert "draft-post" not in ids
end
test "excludes future-dated posts", %{blog: blog} do
ids = blog.all_posts() |> Enum.map(& &1.id)
refute "future-post" in ids
end
test "includes today-dated published posts" do
{:ok, _} = FakeBlog.start([
build(id: "today", date: Date.utc_today(), published: true),
build(id: "tomorrow", date: Date.add(Date.utc_today(), 1), published: true)
])
ids = FakeBlog.all_posts() |> Enum.map(& &1.id)
assert "today" in ids
refute "tomorrow" in ids
end
test "returns posts newest first", %{blog: blog} do
dates = blog.all_posts() |> Enum.map(& &1.date)
@@ -23,6 +41,13 @@ defmodule Blogex.BlogTest do
end
describe "recent_posts/1" do
test "excludes future-dated posts", %{blog: blog} do
posts = blog.recent_posts(100)
ids = Enum.map(posts, & &1.id)
refute "future-post" in ids
end
test "returns at most n posts", %{blog: blog} do
assert length(blog.recent_posts(2)) == 2
end
@@ -35,6 +60,12 @@ defmodule Blogex.BlogTest do
end
describe "posts_by_tag/1" do
test "excludes future-dated posts", %{blog: blog} do
posts = blog.posts_by_tag("future-only")
assert posts == []
end
test "returns only posts with the given tag", %{blog: blog} do
posts = blog.posts_by_tag("testing")
@@ -59,6 +90,10 @@ defmodule Blogex.BlogTest do
end
describe "all_tags/0" do
test "excludes tags only on future-dated posts", %{blog: blog} do
refute "future-only" in blog.all_tags()
end
test "returns unique sorted tags from published posts", %{blog: blog} do
tags = blog.all_tags()
+27
View File
@@ -8,12 +8,24 @@ defmodule Blogex.RegistryTest do
def blog_id, do: :alpha
def all_posts, do: [Blogex.Test.PostBuilder.build(id: "a1", date: ~D[2026-03-01], blog: :alpha)]
def all_tags, do: ["elixir"]
def unfiltered_posts,
do: [
Blogex.Test.PostBuilder.build(id: "a1", date: ~D[2026-03-01], blog: :alpha),
Blogex.Test.PostBuilder.build(id: "a-draft", date: ~D[2026-03-05], blog: :alpha, published: false)
]
end
defmodule BetaBlog do
def blog_id, do: :beta
def all_posts, do: [Blogex.Test.PostBuilder.build(id: "b1", date: ~D[2026-03-15], blog: :beta)]
def all_tags, do: ["devops"]
def unfiltered_posts,
do: [
Blogex.Test.PostBuilder.build(id: "b1", date: ~D[2026-03-15], blog: :beta),
Blogex.Test.PostBuilder.build(id: "b-future", date: ~D[2099-01-01], blog: :beta)
]
end
setup do
@@ -77,6 +89,21 @@ defmodule Blogex.RegistryTest do
end
end
describe "all_posts_unfiltered/0" do
test "returns all posts including drafts and future-dated" do
ids = Registry.all_posts_unfiltered() |> Enum.map(& &1.id)
assert "a1" in ids
assert "a-draft" in ids
assert "b1" in ids
assert "b-future" in ids
end
test "sorts by date descending" do
dates = Registry.all_posts_unfiltered() |> Enum.map(& &1.date)
assert dates == Enum.sort(dates, {:desc, Date})
end
end
describe "blogs_map/0" do
test "returns map keyed by blog_id" do
map = Registry.blogs_map()
+9 -2
View File
@@ -51,9 +51,16 @@ defmodule Blogex.Test.FakeBlog do
def description, do: get(:description)
def base_path, do: get(:base_path)
def all_posts do
def unfiltered_posts do
get(:posts)
|> Enum.filter(& &1.published)
|> Enum.sort_by(& &1.date, {:desc, Date})
end
def all_posts do
today = Date.utc_today()
get(:posts)
|> Enum.filter(&(&1.published and not Date.after?(&1.date, today)))
|> Enum.sort_by(& &1.date, {:desc, Date})
end
+6
View File
@@ -44,6 +44,12 @@ defmodule Blogex.Test.Setup do
date: ~D[2026-03-12],
tags: ["elixir"],
published: false
),
build(
id: "future-post",
date: ~D[2099-01-01],
tags: ["future-only"],
published: true
)
]
end