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 :markdown_body, Types::String.default("".freeze) 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