use v6.e.PREVIEW; use DB::Post; use DB::BlogMeta; use XML; unit module Atom; # get the link for a post sub post-link(BlogMeta:D $meta, Int:D $id, Post:D $post --> Str:D) { my @slugs = $post.all-slugs; my $base = $meta.get-base-url; if @slugs.elems { "$base/posts/by-slug/{@slugs[*-1]}.html" } else { "$base/posts/by-id/$id.html" } } #| Convert a single post to an atom item sub post-to-item(BlogMeta:D $meta, Int:D $id, Post:D $post --> XML::Element) { my $link = post-link $meta, $id, $post; my $desc = $post.description; my $xml = XML::Element.new(:name); $xml.append: XML::Element.new(:name, :nodes([$link])); $xml.append: XML::Element.new(:name, :nodes([$post.title])); $xml.append: XML::Element.new(:name<updated>, :nodes([$post.updated])); $xml.append: XML::Element.new(:name<published>, :nodes([$post.posted-at])); my $author = XML::Element.new(:name<author>); $author.append: XML::Element.new(:name<email>, :nodes(["thatonelutenist@stranger.systems"])); $author.append: XML::Element.new(:name<name>, :nodes(["Nathan McCarty"])); $xml.append: $author; $xml.append: XML::Element.new(:name<link>, :attribs({:href($link), :rel<alternate>})); $xml.append: XML::Element.new(:name<content>, :attribs({:src($link), :type<html>})); $xml.append: XML::Element.new(:name<summary>, :nodes([$desc])) if $desc; if $post.tags { for $post.tags -> $tag { $xml.append: XML::Element.new(:name<category>, :attribs({:term($tag)})); } } $xml } #| Produce an atom feed from the database sub posts-to-atom($db --> XML::Element) is export { my $updated = $db.posts.values.map(*.updated).max; my $xml = XML::Element.new( :name<feed>, :attribs({:xmlns('http://www.w3.org/2005/Atom')})); $xml.append: XML::Element.new(:name<id>, :nodes([$db.meta.get-base-url])); $xml.append: XML::Element.new(:name<title>, :nodes([$db.meta.title])); $xml.append: XML::Element.new(:name<updated>, :nodes([$updated])); for $db.sorted-posts -> $pair { unless $pair.value.hidden { $xml.append: post-to-item $db.meta, $pair.key, $pair.value; } } $xml }