Layout/Partial Examples

Last updated:
2021-01-12 16:23

Find below a series of examples of how you might setup your layouts or partials to achieve specific effect.

Blog entries and list of updates

Here are two snippets that, combined, create blog posts and an ordered list of entries on the blog. It is possible to create multiple different themed “blogs” as part of a given site, by creating multiple modified versions of this template.

This layout formats the list of blog entries:

(defn blog
  [{:keys [build-url title render partials]}]
  (let [{:keys [head]} partials]
     (head build-url)
         [:h1 title]
         ;; List files that are "FIRN_UNDER" the "Updates" page
         (render :sitemap {:start-at ["Updates"]
                           :depth 1
                           :sort-by :newest})
          [:p "Back to main index: "
           [:a {:href "./index"} "Index"]]]

The layout should be accompanied by an Org mode file like the following:

#+title: Updates

(Text written here will be overwritten when the page is rendered.)

The following layout formats an individual blog entry that will be added to the list described above.

(defn blog-update
  [{:keys [render partials title meta date-created build-url]}]
  (let [{:keys [head]} partials]
     (head build-url)
        [:h1 title]
        [:i (str date-created " — " (-> meta :keywords :author))]
        [:div (render :file)]
        (when-let [backlinks (render :backlinks)] 
            [:h4 "Backlinks to this document:"]
        [:div.back [:p "Back to blog: " [:a {:href "./updates"} "Updates"]]]]]]]))

Individual blog updates should contain header information as follows:

#+title: Your descriptive text here
#+FIRN_UNDER: Updates
#+FIRN_LAYOUT: update
#+DATE_CREATED: <2021-01-06 Wed>
#+DATE_UPDATED: <2021-01-16 Sat>
#+AUTHOR: Your name here

(The DATE_UPDATED field is optional relative to these layouts; see below for one way in which it can be used. Also, notice the date format is year, month, day.)

Recently Updated / Published

This snippet demonstrates how to display a list of most recent recently published or updated org-files.

(defn processed-files
  "Provides access to the list of processed files in the 'map of the world' that
  gets passed to each layout."
  (-> data :config :processed-files vals))

(defn mru
  "`mru` stands for most-recently-updated, but this function also can provide most recently published.
  this function requires that your files have a #+DATE_UPDATED and #+DATE_CREATED
  front matter."
  ;; `data` - map - the entire configuration map passed to all layouts must be passed here.
  ;; `num-to-show` - integer to determine how many recent files should be shown
  ;; `recently` - a keyword that can be `:updated` or `:published`.
  [data {:keys [num-to-show recently]
         :or   {recently :updated}}]
  ;; we determine the keyword to use so that we may sort our files.
  (let [date-type (case recently
                    :updated :date-updated-ts
                    :created :date-created-ts)
        ;; we use the helper fn defined above to get access too all files.
        files     (processed-files data)
        ;; now we use clojure's sorting mechanism to sort by the determined
        ;; date-updated/created ts (timestamp -- which is internally available
        ;; to firn.)
        by-date   (sort-by (fn [a]
                             ; get-in's nill fallback doesn't seem to work so I'm using `or`.
                             (or (get-in a [:meta date-type]) 0)) >  files)

    ;; Here is the hiccup/html that is renderering a list of links to the fecent files
     (for [f    (take num-to-show by-date)
           :let [{:keys [title date-updated-ts date-created-ts]}(f :meta)]]
       (when (and title date-updated-ts date-created-ts)
         [:li.px2 [:a {:href (f :path-web)} title]]))]))

Example usage:

(mru data {:num-to-show 5 :recently :updated})