This subsection outlines the generic Org Export process with an eye
toward customizing it for our purposes. While we defer the
fully-customized implementation to See Customizing the Publication Process, it is here that we introduce indie-org.sh, a live example of an Org-generated static site built on
top of indie-org
.
The Org Export publication process, in broad terms, looks like this:
The main entrypoint to the Org Export facility is See org-publish-all.
org-publish-all
refers to the variable See org-publish-project-alist, which
describes our publication “project” to Org Mode. For each project
(the root project can have sub-projects), Org Export will iterate over
each file, copying it to its configured destination and, in general,
transforming the contents in some way.
Of particular note is the info
, or plist
argument which
is initialized at the beginning of the process of publishing each
project (in org-publish-file
) and is passed down through the
entire call stack. It begins as the project plist (i.e. the project
entry in org-publish-project-alist
) and is augmented at each
step. It is a property list that the different pieces of the
publication pipeline use to communicate, and indie-org
will use
it as well.
The process of transforming the Org Mode document to another format is
governed by the :publishing-function
attribute for each
project. It is invoked with the input filename, the publication
directory, and the project plist.
indie-org.sh
has two sub-projects salient to this discussion:
“pages” and “posts”. The former contains a few top-level pages
(home, about & so forth) whereas the latter contains all the site
posts. Each employs a lambda as its publishing-function
; the
lambdas simply provide one more argument to the true publishing
implementation, iosh/publish-page
. The additional argument is
the Org Export back-end to use ( see Back-end in Adding Export Back-ends ).
iosh/publish-page
passes that back-end on to
org-publish-org-to
and thence to org-export-to-file
and
org-export-as
, which is where the real work begins. The
function has a lot of functionality packed into its 171 lines; of note
to us, it will:
We introduce an Emacs Lisp file, indie-org.sh.el
to the project
where we can setup this boilerplate & invoke org-publish-all
:
(defun iosh/publish (prod) "Publish indie-org.sh to production if PROD is non-nil, locally else." ;; Define a derived backend to insert our template: (org-export-define-derived-backend 'iosh/page-html 'html :translate-alist '((template . iosh/page-html))) (org-export-define-derived-backend 'iosh/post-html 'html :translate-alist '((template . iosh/post-html))) ;; ... (let* ((publishing-root (concat (file-name-as-directory project-dir) "www")) (org-publish-project-alist `(("indie-org.sh" :components ("pages")) ("pages" :base-directory ,(concat project-dir "pages") :publishing-directory ,(concat project-dir "www") :publishing-function ,(list (lambda (plist filename pub-dir) (iosh/publish-page plist filename pub-dir 'iosh/page-html))) :html-doctype "html4-strict" ... ) ("posts" :base-directory ,(concat project-dir "posts") :publishing-directory ,(concat project-dir "www/posts") :publishing-function ,(list (lambda (plist filename pub-dir) (iosh/publish-page plist filename pub-dir 'iosh/post-html))) :html-doctype "html4-strict" ... )))) (org-publish-all t) ;; ... ))