How to generate a website with org-mode
In a previous blog-post, we looked at how a single org-mode
file can be
converted into HTML using the
ox-html
exporter.
However, when generating an entire website one needs to generate multiple
inter-linked pages, sitemaps etc. Additionally, one may want to generate output
that is different than what is generated by ox-html
. How do we accomplish
these things? Let’s find out!
Exporter back-ends
Org files can be exported into multiple formats with the help of exporter back-ends.
Org can convert and export documents to a variety of other formats while retaining as much structure (see Document Structure) and markup (see Markup for Rich Contents) as possible.
The libraries responsible for translating Org files to other formats are called back-ends.
ox-html
is one such exporter back-end that exports an org-file to the HTML
format. ox-latex
,
meanwhile, is an exporter back-end that exports to
either .tex
or .pdf
formats.
Customizing the output of exporter back-ends
Sometimes, however, the stock output generated by an exporter back-end may not be sufficient for one’s needs. One way to modify the output of an exporter back-end is by defining filter functions that are chained together.
Filters are lists of functions to be applied to certain parts for a given back-end. The output from the first function in the filter is passed on to the next function in the filter.1The first filter function operates on the output of the exporter back-end. The final output is the output from the final function in the filter.
However, sometimes the changes one wishes to make are larger in scope than those that may be feasible using filter functions alone. In such situations, it might make sense to define a derived exporter back-end.
In addition to standalone exporter back-ends, some back-ends are instead
derived from others.2Where the derived back-end has the same behaviour
as the base back-end, except in some specific situations where the behaviour
differs. A notable example of this is
ox-beamer
which derives
from ox-latex
and can be used to create
Beamer
presentations. Another is
ox-tufte
which derives from
ox-html
and produces HTML output in the style of
tufte-css
.3Such as
the sidenotes which
are used in the present blog.
Adding a custom exporter back-end, while relatively straightforward, still has
a number of details that need to be
understood.
The Orgmode manual has some details to get started, but perhaps the best way
is to review the code of an existing derived back-end.4A future blog post
will review the ox-tufte
derived back-end in depth.
So given an exporter back-end, one can convert an org-file into various
generic or specific output formats.5Specific in the sense that the output
contains additional structure. Each exporter back-end may also define some
back-end specific export properties or keywords which can be used to customize
the generated output. Thus, a naive way of exporting multiple files to a desired
format would be to invoke the specific exporter back-end on each file.6In
a manner similar to what was presented in the blog-post on ox-html
.
Sharing configuration options via SETUPFILE
s
Configuration options that are the same across multiple files7For instance,
the value of HTML_HEAD
, HTML_HEAD_EXTRA
, HTML_LINK_HOME
etc. can be
shared and specified once with the help of SETUPFILE
s.
A SETUPFILE
is an org-mode
file that specifies various in-buffer settings
such as the value of various export keywords. It can be included in other
org-mode
files using the following syntax:
#+SETUPFILE: <filename or URL>
Exporting multiple files via ox-publish
8Using ox-publish
requires knowledge of Emacs Lisp. This reference sheet may be a good starting point.
While SETUPFILE
s can be used to great effect, they have a limitation in that
the settings can only be specified in a defunctionalized form.9Unless, the
setting in question allows one to specify the name of a function. I.e., they
allow one to specify the value, but not describe computations that will yield
the value of interest. A way to address this is to use
ox-publish
. ox-publish
also allows one to generate sitemaps
and indexes. Additionally, linking to other org-mode
files within the project
automatically inserts the link to the corresponding published target.
At the heart of ox-publish
is the org-publish-project-alist
variable that
describes the project specification.10Since the variable is specified using
Emacs Lisp (as opposed to plain text), one can, if so desired, describe a
computation that yields its value instead. Among other things, it allows one to
specify the specific exporter back-end to use (by specifying the publishing
action)11Via the :publishing-function
key. as well
as the
destination
directory.12Via the :publishing-directory
key.
When generating a website13Or publishing a book. a number of aspects may
need to be configured. ox-publish
allows one to do just that. As one might
expect the devil is in the details, and for a first-timer it might help to
consult some sample configurations first.14A future blog post will go into the
specifics of how the present blog is published.
Comments
Comments can be left on twitter, mastodon, as well as below, so have at it.
New post!
— The Weary Travelers blog (@wearyTravlrsBlg) August 27, 2023
Part 2: Have you ever wanted to publish a blog from org-mode files? Find out how.https://t.co/KORQlWXojL
Reply here if you have comments.
Footnotes:
The first filter function operates on the output of the exporter back-end.
Where the derived back-end has the same behaviour as the base back-end, except in some specific situations where the behaviour differs.
Such as the sidenotes which are used in the present blog.
Specific in the sense that the output contains additional structure.
In
a manner similar to what was presented in the blog-post on ox-html
.
For instance,
the value of HTML_HEAD
, HTML_HEAD_EXTRA
, HTML_LINK_HOME
etc.
Using ox-publish
requires knowledge of Emacs Lisp. This reference sheet may be a good starting point.
Unless, the setting in question allows one to specify the name of a function.
Since the variable is specified using Emacs Lisp (as opposed to plain text), one can, if so desired, describe a computation that yields its value instead.
Via the :publishing-function
key.
Via the :publishing-directory
key.
Or publishing a book.
A future blog post will go into the specifics of how the present blog is published.