Blogging with Emacs org-mode

All pages of this website has been designed in org-mode. Not just this blog. The repository contain source code for the complete website.


For about a year, I have been trying to find a suitable workflow to blog using Emacs org-mode. My idea was to put all articles (posts) in a single org file, which failed miserably for the following reasons:

  • The default org-mode html export is designed to work on separate files. So single file org export requires custom code which I don't want to write.
  • I wish to link to the source org file from each html article, which is not possible if every article is written in a single file.

Last year, I did write around 500 lines of code, which worked. Pretty much all of them were unmaintainable hacks. A few days back, I gave it a try again. This time, with a different design:

  • Each article is written in separate org files, with dated directory names. Eg.: A file in 2018/08/08 dir for Hello World article.
  • Manually created blog index and atom feeds so that I don't have to wait another year to pass the salt.

For the impatient, get the source code here. The complete source code (including the sass design style sheets) are released into public domain (CC0). Feel free to use it the way you like. If you wish to attribute me, link to my website

The work flow

The following is a barebone example on using Emacs org-mode for blogging. For a practically usable code, see the source of this website.

  • Create a directory for saving your website source, say ~/web/src/.
  • Create an org file with your favorite article, say ~/web/src/blog/2018/08/08/ with some content.

    #+author: Alice
    #+title: Hello world
    #+date: <2018-08-08 Wed>
    #+keywords: hello, world, emacs, blog
    #+description: Hello world
    I like ~org-mode~.
  • Create the project configuration and save it to some file, say ~/web/src/my-web.el.

    (require 'org)
        :base-directory "src/blog"
        :base-extension "org"
        :publishing-directory "public/blog"
        :recursive t
        :publishing-function org-html-publish-to-html)
        :components ("blog"))))

The directory structure will look like this:

~/web/src$ tree
├── blog
│   └── 2018
│       └── 08
│           └── 08
│               └──
└── my-web.el

4 directories, 2 files
  • Now we can publish the project to get the static HTML pages:

    ~/web$ emacs --batch -q -l src/my-web.el -f org-publish-all

That's it. The will now be exported as ~/web/public/blog/2018/08/08/hello-world.html.


This is an overly simplified example. To see how the Hello World blog post is written, see its source. Also see the project configuration file and atom feed generation script.

Update: See Hacker News discussion.