# This creates the static files that make up my blog from the Markdown # files in this repository. # # All blog posts are rendered from Markdown by cheddar. { depot, lib, pkgs, ... }@args: with depot.nix.yants; let inherit (builtins) readFile; inherit (depot.nix) renderMarkdown; inherit (depot.web) atom-feed; inherit (lib) singleton; # Type definition for a single blog post. post = struct "blog-post" { key = string; title = string; date = int; # Optional time at which this post was last updated. updated = option int; # Path to the Markdown file containing the post content. content = path; # Whether dangerous HTML tags should be filtered in this post. Can # be disabled to, for example, embed videos in a post. tagfilter = option bool; # Optional name of the author to display. author = option string; # Should this post be included in the index? (defaults to true) listed = option bool; # Is this a draft? (adds a banner indicating that the link should # not be shared) draft = option bool; # Previously each post title had a numeric ID. For these numeric # IDs, redirects are generated so that old URLs stay compatible. oldKey = option string; }; # Rendering fragments for the HTML version of the blog. fragments = import ./fragments.nix args; # Functions for generating feeds for these blogs using //web/atom-feed. toFeedEntry = { baseUrl, ... }: defun [ post atom-feed.entry ] (post: rec { id = "${baseUrl}/${post.key}"; title = post.title; content = readFile (renderMarkdown post.content); published = post.date; updated = post.updated or post.date; links = singleton { rel = "alternate"; href = id; }; }); in { inherit post toFeedEntry; inherit (fragments) renderPost; # Helper function to determine whether a post should be included in # listings (on homepages, feeds, ...) includePost = post: !(fragments.isDraft post) && !(fragments.isUnlisted post); }