firehose/blogex/lib/blogex.ex
Willem van den Ende 0577ceced0 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
2026-04-01 20:30:27 +00:00

125 lines
3.4 KiB
Elixir

defmodule Blogex do
@moduledoc """
Blogex — a multi-blog engine for Phoenix apps, powered by NimblePublisher.
Blogex lets you host multiple blogs (e.g. engineering blog, release notes)
from markdown files in your repo. Posts are compiled into the BEAM at build
time for instant reads with zero runtime I/O.
## Quick Start
1. Add `blogex` to your dependencies:
```elixir
def deps do
[
{:blogex, "~> 0.1.0"}
]
end
```
2. Create your markdown posts:
```
priv/blog/engineering/2026/03-10-our-new-architecture.md
priv/blog/release-notes/2026/03-01-v2-launch.md
```
Each file has frontmatter + content:
```markdown
%{
title: "Our New Architecture",
author: "Jane Doe",
tags: ~w(elixir architecture),
description: "How we rebuilt our platform"
}
---
Your markdown content here...
```
3. Define blog modules in your app:
```elixir
defmodule Firehose.EngineeringBlog do
use Blogex.Blog,
blog_id: :engineering,
app: :firehose,
from: "priv/blog/engineering/**/*.md",
title: "Engineering Blog",
description: "Deep dives into our tech stack",
base_path: "/blog/engineering"
end
defmodule Firehose.ReleaseNotes do
use Blogex.Blog,
blog_id: :release_notes,
app: :firehose,
from: "priv/blog/release-notes/**/*.md",
title: "Release Notes",
description: "What's new in our product",
base_path: "/blog/releases"
end
```
4. Register blogs in your config:
```elixir
config :blogex,
blogs: [Firehose.EngineeringBlog, Firehose.ReleaseNotes]
```
5. Mount routes in your Phoenix router:
```elixir
scope "/blog" do
pipe_through :browser
forward "/engineering", Blogex.Router, blog: Firehose.EngineeringBlog
forward "/releases", Blogex.Router, blog: Firehose.ReleaseNotes
end
```
6. Enable live reloading in `config/dev.exs`:
```elixir
live_reload: [
patterns: [
...,
~r"priv/blog/*/.*(md)$"
]
]
```
## Architecture (Poncho Pattern)
Blogex is designed as a "poncho" — it wraps NimblePublisher and provides
a clean public API while the inner library does the heavy lifting of
markdown parsing and compilation. The host app's supervision tree is used
directly; Blogex adds no processes of its own since all data is compiled
into module attributes at build time.
## Modules
* `Blogex.Blog` — macro to define a blog context
* `Blogex.Post` — post struct
* `Blogex.Registry` — cross-blog queries
* `Blogex.Feed` — RSS/Atom feed generation
* `Blogex.SEO` — meta tags and sitemap generation
* `Blogex.Components` — Phoenix function components
* `Blogex.Router` — mountable Plug router
"""
@doc "Returns true if draft posts should be visible (dev/test environments)."
def show_drafts? do
Application.get_env(:blogex, :show_drafts, false)
end
defdelegate blogs, to: Blogex.Registry
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