samhuri.net/lib/pressa/posts/models.rb
Sami Samhuri 007b1058b6
Migrate from Swift to Ruby (#33)
Replace the Swift site generator with a Ruby and Phlex implementation.
Loads site and projects from TOML, derive site metadata from posts.

Migrate from make to bake and add standardrb and code coverage tasks.

Update CI and docs to match the new workflow, and remove unused
assets/dependencies plus obsolete tooling.
2026-02-07 21:19:03 -08:00

95 lines
2.1 KiB
Ruby

require "dry-struct"
require "pressa/site"
module Pressa
module Posts
class Post < Dry::Struct
attribute :slug, Types::String
attribute :title, Types::String
attribute :author, Types::String
attribute :date, Types::Params::DateTime
attribute :formatted_date, Types::String
attribute :link, Types::String.optional.default(nil)
attribute :tags, Types::Array.of(Types::String).default([].freeze)
attribute :body, Types::String
attribute :excerpt, Types::String
attribute :path, Types::String
def link_post?
!link.nil?
end
def year
date.year
end
def month
date.month
end
def formatted_month
date.strftime("%B")
end
def padded_month
format("%02d", month)
end
end
class Month < Dry::Struct
attribute :name, Types::String
attribute :number, Types::Integer
attribute :padded, Types::String
def self.from_date(date)
new(
name: date.strftime("%B"),
number: date.month,
padded: format("%02d", date.month)
)
end
end
class MonthPosts < Dry::Struct
attribute :month, Month
attribute :posts, Types::Array.of(Post)
def sorted_posts
posts.sort_by(&:date).reverse
end
end
class YearPosts < Dry::Struct
attribute :year, Types::Integer
attribute :by_month, Types::Hash.map(Types::Integer, MonthPosts)
def sorted_months
by_month.keys.sort.reverse.map { |month_num| by_month[month_num] }
end
def all_posts
by_month.values.flat_map(&:posts).sort_by(&:date).reverse
end
end
class PostsByYear < Dry::Struct
attribute :by_year, Types::Hash.map(Types::Integer, YearPosts)
def sorted_years
by_year.keys.sort.reverse
end
def all_posts
by_year.values.flat_map(&:all_posts).sort_by(&:date).reverse
end
def recent_posts(limit = 10)
all_posts.take(limit)
end
def earliest_year
by_year.keys.min
end
end
end
end