Blogging with Emacs org-mode

Introduction

For about an 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 misserably for the following reasons:

  • The default org-mode html export is designed to work on seperate 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 seperate org files, with dated directory names. Eg.: A hello-world.org 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 www.sadiqpk.org.

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/hello-world.org 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)
    (setq
     org-publish-project-alist
     '(("blog"
        :base-directory "src/blog"
        :base-extension "org"
        :publishing-directory "public/blog"
        :recursive t
        :publishing-function org-html-publish-to-html)
    
       ("website"
        :components ("blog"))))
    

The directory structure will look like this:

~/web/src$ tree
.
├── blog
│   └── 2018
│       └── 08
│           └── 08
│               └── hello-world.org
└── 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 hello-world.org will now be exported as ~/web/public/blog/2018/08/08/hello-world.html.

Conclusion

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.