From 0571a16dabd71c7ea68b71d449748b6c7557c6e7 Mon Sep 17 00:00:00 2001 From: Nathan McCarty Date: Sun, 9 Feb 2025 01:50:37 -0500 Subject: [PATCH] Add series data structure --- lib/Config.rakumod | 1 + lib/DB.rakumod | 23 ++++++++++++++++++++++- lib/DB/Series.rakumod | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 lib/DB/Series.rakumod diff --git a/lib/Config.rakumod b/lib/Config.rakumod index 68c8172..a16d9f4 100644 --- a/lib/Config.rakumod +++ b/lib/Config.rakumod @@ -24,6 +24,7 @@ method generate-post(Post:D $post, BlogMeta:D $meta) { ] ] ]; + # TODO: Setup Comments # TODO: Setup footer # my $footer; diff --git a/lib/DB.rakumod b/lib/DB.rakumod index dac655d..d977061 100644 --- a/lib/DB.rakumod +++ b/lib/DB.rakumod @@ -9,6 +9,7 @@ use XML; use XQ; use DB::Post; +use DB::Series; use DB::BlogMeta; use DB::MarkdownPost; use DB::IdrisPost; @@ -25,6 +26,8 @@ class PostDB { #| A mapping from post ids to posts # has %.posts is Posts; has %.posts{Int} of PostTypes = %(); + #| A mapping from series ids to series + has %.series{Int} of Series = %(); #| The post id to use for placeholder posts has Int $.placeholder-id = 0; @@ -57,9 +60,11 @@ class PostDB { #| Write a database to a directory method write(IO::Path:D $dir) { my $posts-dir = $dir.add('posts/'); + my $series-dir = $dir.add('series/'); # Make sure directory structrue exists mkdir $dir unless $dir.e; mkdir $posts-dir unless $posts-dir.e; + mkdir $series-dir unless $series-dir.e; # Write out metadata # TODO: Track changes and only write changed files $dir.add('meta.json').spurt: $!meta.to-json(:sorted-keys); @@ -67,6 +72,10 @@ class PostDB { for %!posts.kv -> $key, $value { $posts-dir.add("$key.json").spurt: $value.to-json(:sorted-keys); } + # Write out the series + for %!series.kv -> $key, $value { + $series-dir.add("$key.json").spurt: $value.to-json(:sorted-keys); + } } #| Render the site to the provided output directory @@ -114,6 +123,7 @@ class PostDB { $tags-dir.add("$tag.html").spurt: $config.generate-tag-page(self, $tag); } + # TODO: Generate the series pages # Render the rss/atom feed my $atom-path = $out-dir.add('atom.xml'); my $atom = posts-to-atom self; @@ -135,6 +145,7 @@ class PostDB { #| Read the database out of a directory sub read-db(IO::Path:D $dir --> PostDB:D) is export { my $posts-dir = $dir.add('posts/'); + my $series-dir = $dir.add('series/'); die "DB directory does not exist" unless $dir.e; die "posts directory does not exist" unless $posts-dir.e; # Read metadata @@ -160,6 +171,16 @@ sub read-db(IO::Path:D $dir --> PostDB:D) is export { } } } + # Read series + my %series{Int} of PostTypes = %(); + # For backwards compatability, the series directory is optional. It will be + # created on the next db operation, but we don't need it to read the site + if $series-dir.e { + for dir $series-dir -> $series { + my $id = $series.extension("").basename.Int; + %series{$id} = Series.from-json: $series.slurp; + } + } # Build db structure - PostDB.new: meta => $meta, posts => %posts + PostDB.new: meta => $meta, posts => %posts, series => %series } diff --git a/lib/DB/Series.rakumod b/lib/DB/Series.rakumod new file mode 100644 index 0000000..2241215 --- /dev/null +++ b/lib/DB/Series.rakumod @@ -0,0 +1,15 @@ +use v6.e.PREVIEW; + +use JSON::Class:auth; + +#| A plain markdown post +unit class Series is json(:pretty); + +#| The title of a series +has Str:D $.title is required; + +#| The description of a series +has Str:D $.desc is required; + +#| The ids of the posts in the series, in series order +has Int:D @.post-ids = [];