org-mode as a Static Site Generator
Created: 2022-06-14 Last updated: 2022-06-14
Introduction
There are a lot of static site generators out there, you can think of Jekyll, Hugo, sblg. Those are good (I guess) but, as I was too lazy to check them out, I tried to perform the same task (In this case, generating a website from a language in a weird markup language) that looks very much the same as it was written in pure html. And emacs’ org-mode was able to do this perfectly. Not much flaws were found in this process.
And yes, this article was written in org-mode
.
The basics
Every emacs users (I hope) knows about org-mode, it is a very powerful
markup language, in my opinion, better than markdown as it uses more
common sense, like bold text are written with only one asterisk and
italic text is written with slashes, which makes more sense inside
my head than markdown’s one asterisk for italic and two asterisks for
bold. The headers are written with an asterisk followed by the text,
and you can insert code blocks with #+begin_src <language>
. (and close
them with #+end_src) And
guess what! Emacs will export the source code highlighted to html!
The output colors will be defined by your current Emacs theme
When you are finished writing your .org file, you can export it to
html with M-x org-html-export-to-html
. This will create a .html
file
with the same name of the .org
file. You can open it and it won’t be
so much different than a .md
file converted to .html
using pandoc
. But
we can fix that using the multiple org-mode
options!
org-mode options
There are a lot of org-mode
. You can check all of them here and
here. Check them if you need an option that is not here. Pretty sure
there’s an option for whatever you want.
So, when you make a website, you most likely want to make it somewhat
artistic, so you want to add, say, a header, and a stylesheet
file. This is possible with org-mode
options. The following text lines
will insert a header file and a stylesheet file into the resulting
.html file:
#+INCLUDE: "inc/header.html" export html #+HTML_HEAD_EXTRA: <link rel="stylesheet" type="text/css" href="css/styles.css"/>
This will include, before everything in the .org
file, the content of
the file located at inc/header.html
. And will append that <link/> HTML
tag to the <head> section of the resulting .html
file. So it will give
the stylesheet to the resulting html site.
n
But by default org-mode
gives us the number of headings, preambles and
postambles, a table of contents, some html style we never asked for,
and a lot of things we never asked for. But obviously, theres an
option to take care of all of that!
#+options: toc:nil #+OPTIONS: html-postamble:nil #+OPTIONS: html-style:nil #+OPTIONS: num:nil p:nil pri:nil stat:nil tags:nil tasks:nil tex:nil timestamp:nil toc:nil title:nil
That snippet inside the codeblock will disable all the things we don’t
want in a personal website (but maybe we want in an academic
article?). I don’t know. The thing is that you can disable or enable
them as needed. As you should know, nil
in emacs-lisp means false
and
t
means true
. So if you want to enable some option of those you give
it t
instead of nil
.
So you have to add that to all the .org files you have. You can
probably setup those options as default by setting the family of
org-export
variables to nil
as needed. But I keep it that way because
I am too lazy to set all of those variables.
Then, you have to do M-x org-html-export-to-html
in each .org file and
upload them to your webroot. And everything should work when you visit
your website. If not, check if the path of the css and header is
correct (In this post i’m assuming your .html files are in inc/
and
your css is in css/styles.css
, which are both relative paths).
Inserting custom HTML in Org
Something great about Markdown is that you can insert HTML by simply
adding it as normal text. You cannot do this in org-mode. You can’t
just put <b>thing</b> and expect org-mode to compile that as html. You
have to use an export
block. Those work just as the codeblocks we’ve
seen before. But instead of src, it’s export, so it will
be #+begin_export html. Following there’s an example
Exporting a whole directory with .org files to html
For most of the time running this website using org-mode
as static
site generator, i used to run M-x org-html-export-to-html
as
needed. But I thought this was unnecessary and repetitive and there
wasn’t really a need to do that. I wanted something like make
. Where
you run and you get everything compiled. And if a file didn’t change,
don’t compile it again (as it isn’t needed). So I asked about this in
the #emacs irc channel:
<sukamu> Hello, is it possible to use org-html-export-to-html in a emacs lisp program to export a file? Documentation says it only "exports the current buffer", But i want to export all the .org files in a directory as html <sukamu> (I'm using org-mode as a ssg) <wgreenhouse> > export all the .org files in a directory as html <wgreenhouse> sukamu: it sounds like you want org-publish <wgreenhouse> (info "(org) Publishing")
So I checked out that “org-publish
” thing this IRC user was talking
about. And indeed it was exactly what I needed. I had to read the
documentation. And I came to this following emacs-lisp files which can
compile my website just well:
;; Change this (setq org-publish-project-alist '(("suragu.net" :base-directory "~/repos/suragu_org/" :publishing-directory "~/repos/suragu" :section-numbers nil :publishing-function org-html-publish-to-html :table-of-contents nil :recursive t ))) (defun sosa/make-suragu () (interactive) (org-publish "suragu.net")
And that’s it! Everytime I want to recompile this website I just have
to run M-x make-suragu
and org-publish will do the rest for me!
Automatically publishing your site with sshfs
sshfs is a filesystem client based on ssh and FUSE. This means remote
directories using sshfs. So you can mount your server’s webroot in
your local machine, so publishing sites can be easy if you set the
publishing-directory
in the org-publish-project-alist
to the
remote mountpoint:
sshfs root@192.168.1.57:/var/www/sites/suragu.net ~/repos/suragu
So when you run the function to publish your website
(sosa/make-suragu
in this case). It will automatically publish to
the sshfs mounted directory. So your website will be updated.
Conclusion
org-mode
is a great markup language that can repleace markdown in most
tags and also works well as a static site generator. What else do you
want me to say