4.2 Publication Environments & State

Supporting various Indieweb features such as Webmentions & POSSE requires maintaining state regarding site publication. For instance, every time one publishes the site (whether to a local test server or to the live site) one now needs to scribble down new Webmentions that need to be sent for subsequent use. Incoming webmentions also need to be recorded upon receipt for potential use in subsequent publications.

indie-org implicitly defines the idea of “publication environment” to represent the various places to which one may wish to publish. This is implicit because they are named by arbitrary symbols chosen by the site author. For instance, one may choose to examine one’s site after simply publishing HTML to the local filesystem in a browswer with a “file:” URL, and name this publication environment :local.

Perhaps one has an Apache instance running locally for testing purposes: that could be named :staging. The only assumption made by indie-org is that the default site is named :prod.

indie-org associates each production environment with an instance of the struct indie-org-state-v2.

The struct contains the fields:

  1. last-published: the last time the site was published to this environment
  2. webmentions-made: a mapping from page-key to a list of Webmentions made by that page
  3. webmentions-sent: a mapping from page-key to a list of all Webmentions sent to-date for that page
  4. webmentions-received: a mapping from page-key to a list of all Webmentions received by that page
  5. posse-requests: a mapping from page-key to a list of POSSE requests for that page (i.e. an expressed desire for the post to be POSSE’d to Twitter, or Mastodon, or wherever)
  6. posse-responses: a mapping from page-key to a list of POSSE responses for that page (i.e. a record of a completed POSSE request for the page to various siloes).

While it is up to the site author to incorporate state into their publication process, indie-org provides basic utilities for doing so.

Use indie-org-make-publication-state to create a new indie-org-state-v2 instance, indie-org-state-write to write a property list mapping publication environment to state to file, and indie-org-state-read to read it back out.

A site’s publication function might then look something like this:

(defun my/publish (prod)
  "Publish my site to production if PROD is non-nil, locally else."
  (indie-org-enable)
  (let* ((env (if prod :prod :local))
         (pub-states
          (if (file-exists-p publication-state-file)
           (indie-org-state-read publication-state-file)
         `(:prod ,(indie-org-state-make) :local ,(indie-org-state-make))))
         (publication-state (plist-get pub-states env)))
    ;; Setup the call to `org-publish-all'.
    (let* (...)
      (org-publish-all t)
      ;; Update state
      ...
      (plist-put pub-states env publication-state)
      ;; and write it all out to disk.
      (indie-org-state-write pub-states ".state"))))