my-op for org-page

my-op is a brief library for managing org-page sites.

Some meta on this blog: it’s built using org-page, a static site generator tightly integrated with Emacs org-mode. Using an editor to build a site is loopy, but it’s the best way to take advantage of org and it’s literate programming tricks.

Since ths is Emacs, org-page is controlled by global variables. These global variables are explicitly relevant, like op/repository-directory or implicit, like org-confirm-babel-evaluate. A site is built by a particular configuration of these global variables: a profile.

my-op provides tools for switching between and publishing profiles.


Sites profiles are kept in an assocation list, my-op-sites. Each site is a pair: (name . vars), where vars is ((name . value) ...). Here is this site’s configuration:

  (let* ((root (file-name-directory (file-truename buffer-file-name)))
         (theme-root-directory (file-name-as-directory (concat root "themes"))))
    (add-to-list 'my-op-sites
                 `(jtblog .
                          ((org-html-toplevel-hlevel . 4)
                           (org-confirm-babel-evaluate . nil)
                           (op/highlight-render . htmlize)
                           (op/repository-directory . ,root)
                           (op/site-domain . "http://jtmoulia.pocketknife.io")
                           (op/repository-org-branch . "source")
                           (op/repository-html-branch . "master")
                           (op/site-main-title . "jtmoulia")
                           (op/site-sub-title . "public notebook 📓")
                           (op/personal-github-link . "http://github.com/jtmoulia")
                           (op/theme-root-directory . ,theme-root-directory)
                           (op/theme . custom)
                           (op/personal-google-analytics-id . "UA-60774978-1")
                           (op/category-ignore-list . ("themes" "assets" "_build"))
                            . (("blog" ;; this is the default configuration
                                :show-meta t
                                :show-comment nil
                                :uri-generator op/generate-uri
                                :uri-template "/blog/%y/%m/%d/%t/"
                                :sort-by :date     ;; how to sort the posts
                                :category-index t) ;; generate category index or not
                                :show-meta nil
                                :show-comment nil
                                :uri-generator op/generate-uri
                                :uri-template "/"
                                :sort-by :date
                                :category-index nil)
                                :show-meta nil
                                :show-comment nil
                                :uri-generator op/generate-uri
                                :uri-template "/about/"
                                :sort-by :date
                                :category-index nil)))))))

The variable my-op-site references the currently selected site, and my-op-site-policy a 0-arity function which can choose which site to select. The default policy is to ask the user if my-op-site is falsy.


my-op provides a few interactive commands for publishing and selecting site profiles.

publish a site to _build/
publish a site to the html branch
set a site profile’s variables explicitly


There’s no fixed plan, but I’ll continue to tweak the behavior to fit my needs. org-page is happily hackable.

Written by