Using org-publish

Table of Contents

Excerpt from config file

I use org-publish for my websites. This block has a lot going on:

  1. I set some default options for publishing projects.
  2. I use a custom function to generate postamble.
  3. Include my three sites in org-publish-project-alist.
(use-package ox-publish
  :defer t
  (use-package ox-jamzattack
    (ox-jamzattack :type git
                   :repo ""))
  (defvar my-org-publish-default-options
    "Default options for `org-publish-project-alist'.

This variable must be spliced into `org-publish-project-alist'
when set, i.e.
    (setq org-publish-project-alist
   org-html-postamble t ; needed to use custom format
   org-export-headline-levels 6
    "Author: %A")
   org-publish-timestamp-directory "~/.cache/org/timestamps/"
   org-html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\"/>"
      :base-directory "~/"
      :with-toc t
      :publishing-directory "~/"
      :html-postamble-format ,(my-org-html-postamble-format
                               "Author: %A"
                               "Date: %d (modified %M)"
                               "Top: <a href=\"/index.html\">The Yeet Log</a>")
      :sitemap-filename ""
      :sitemap-title "The Yeet Log"
      (lambda (entry style project)
        (cond ((not (directory-name-p entry))
               (format "%s [[file:%s][%s]]"
                        (org-publish-find-date entry project))
                       (org-publish-find-title entry project)))
              ((eq style 'tree)
               ;; Return only last subdir.
               (file-name-nondirectory (directory-file-name entry)))
              (t entry)))
      :sitemap-sort-files anti-chronologically)
      :base-directory "~/"
      :recursive t
      :html-postamble-format ,(my-org-html-postamble-format
                               "Author: %A"
                               "Top: <a href=\"/sitemap.html\">All projects</a>")
      :publishing-directory "~/"
      :sitemap-title "My Music Projects")
      :base-directory "~/"
      :publishing-directory "~/"))))

Generate postamble

A little function to generate postamble.

(defun my-org-html-postamble-format (&rest args)
  "Generate an html postamble using ARGS.

This generates a paragraph for each item in ARGS.  For format
strings, see the docstring of `org-html-postamble-format'."
  (unless args
    (setq args '("Author: %a <%e>")))
  (list (list "en"
              (mapconcat (lambda (str)
                           (format "<p>%s</p>" str))

Default export options

A list of default export options.

:auto-sitemap t
:publishing-function org-html-publish-to-html
:html-metadata-timestamp-format "%Y-%m-%d"
:with-toc nil
:with-email t
:with-drawers nil
:section-numbers nil
:with-todo-keywords nil


I wrote the library ox-jamzattack in a vain attempt to make this section less dense, but it still has a lot going on.

In ox-jamzattack, I define a formatting function to replace org-html-format-spec. This allows me to extract the date that a file was last edited using git (as seen at the bottom of this page).

Publishing locally or via TRAMP?

I used to use TRAMP directories as the publishing directory for my website(s). This is actually really simple, and can just be done as though they were local directories:

(setq org-publish-project-alist
         :base-directory "~/"
         :publishing-directory "/")
         :base-directory "~/"
         :publishing-directory "/")))

This worked fine for a while, but I found it kind of awkward if I needed to make additional edits.

Now, I publish to a local directory and use rsync to send the files to my server:

(setq org-publish-project-alist
         :base-directory "~/"
         :publishing-directory "~/")
         :base-directory "~/"
         :publishing-directory "~/")))
rsync -rLv --exclude '*~' ~/*

This has a few benefits:

  1. I can check that everything works fine (links, images, etc.) before pushing to my server.
  2. I don't need to resort to any hackery to publish non-org files.
  3. I can use symlinks and have the server's directory mimic the local one. This is really useful for publishing my sheet music.
  4. I have offline access to all the exported html files.

Author: Jamie Beardslee

Date: 2020-06-20 (modified 2020-08-21)

Top: The Yeet Log