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.
53 lines
1.5 KiB
Elixir
53 lines
1.5 KiB
Elixir
defmodule Blogex.Registry do
|
|
@moduledoc """
|
|
Registry that tracks all blog modules in the host application.
|
|
|
|
Configure in your app's config:
|
|
|
|
config :blogex,
|
|
blogs: [MyApp.EngineeringBlog, MyApp.ReleaseNotes]
|
|
|
|
Then you can query across all blogs:
|
|
|
|
Blogex.Registry.all_posts() # posts from all blogs, sorted by date
|
|
Blogex.Registry.blogs() # list of blog modules
|
|
Blogex.Registry.get_blog!(:engineering) # get a specific blog module
|
|
"""
|
|
|
|
@doc "Returns the list of configured blog modules."
|
|
def blogs do
|
|
Application.get_env(:blogex, :blogs, [])
|
|
end
|
|
|
|
@doc "Returns a blog module by its blog_id, or raises."
|
|
def get_blog!(blog_id) do
|
|
Enum.find(blogs(), fn mod -> mod.blog_id() == blog_id end) ||
|
|
raise Blogex.NotFoundError, "blog #{inspect(blog_id)} not found"
|
|
end
|
|
|
|
@doc "Returns a blog module by its blog_id, or nil."
|
|
def get_blog(blog_id) do
|
|
Enum.find(blogs(), fn mod -> mod.blog_id() == blog_id end)
|
|
end
|
|
|
|
@doc "Returns all posts from all blogs, sorted newest first."
|
|
def all_posts do
|
|
blogs()
|
|
|> Enum.flat_map(& &1.all_posts())
|
|
|> Enum.sort_by(& &1.date, {:desc, Date})
|
|
end
|
|
|
|
@doc "Returns all unique tags across all blogs."
|
|
def all_tags do
|
|
blogs()
|
|
|> Enum.flat_map(& &1.all_tags())
|
|
|> Enum.uniq()
|
|
|> Enum.sort()
|
|
end
|
|
|
|
@doc "Returns a map of %{blog_id => blog_module} for all registered blogs."
|
|
def blogs_map do
|
|
Map.new(blogs(), fn mod -> {mod.blog_id(), mod} end)
|
|
end
|
|
end
|