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.
69 lines
1.5 KiB
Elixir
69 lines
1.5 KiB
Elixir
defmodule Blogex.Post do
|
|
@moduledoc """
|
|
Struct representing a single blog post.
|
|
|
|
Posts are parsed from markdown files with frontmatter metadata.
|
|
The filename determines the date and slug:
|
|
|
|
priv/blog/engineering/2026/03-10-our-new-architecture.md
|
|
|
|
Frontmatter example:
|
|
|
|
%{
|
|
title: "Our New Architecture",
|
|
author: "Jane Doe",
|
|
tags: ~w(elixir architecture),
|
|
description: "How we rebuilt our platform"
|
|
}
|
|
---
|
|
Your markdown content here...
|
|
"""
|
|
|
|
@enforce_keys [:id, :title, :author, :body, :description, :date]
|
|
defstruct [
|
|
:id,
|
|
:title,
|
|
:author,
|
|
:body,
|
|
:description,
|
|
:date,
|
|
:blog,
|
|
tags: [],
|
|
published: true
|
|
]
|
|
|
|
@type t :: %__MODULE__{
|
|
id: String.t(),
|
|
title: String.t(),
|
|
author: String.t(),
|
|
body: String.t(),
|
|
description: String.t(),
|
|
date: Date.t(),
|
|
tags: [String.t()],
|
|
blog: atom(),
|
|
published: boolean()
|
|
}
|
|
|
|
@doc """
|
|
Build callback for NimblePublisher.
|
|
|
|
Extracts the date from the filename path and merges with frontmatter attrs.
|
|
The `blog` atom is injected by the parent Blog module.
|
|
"""
|
|
def build(filename, attrs, body) do
|
|
[year, month_day_id] =
|
|
filename
|
|
|> Path.rootname()
|
|
|> Path.split()
|
|
|> Enum.take(-2)
|
|
|
|
[month, day, id] = String.split(month_day_id, "-", parts: 3)
|
|
date = Date.from_iso8601!("#{year}-#{month}-#{day}")
|
|
|
|
struct!(
|
|
__MODULE__,
|
|
[id: id, date: date, body: body] ++ Map.to_list(attrs)
|
|
)
|
|
end
|
|
end
|