Org-jekyll

(Please note: I am no longer using org-jekyll.)

Export jekyll blog posts from org-mode

Extracts subtrees from your org-publish project files that have a :blog: keyword and an :on: property with a timestamp, and exports them to a subdirectory _posts of your project's publishing directory in the year-month-day-title.html format that Jekyll expects. Properties are passed over as yaml front-matter in the exported files. The title of the entry is the title of the subtree.

Download and installation

Download org-jekyll.el from github, put it in a directory where emacs will find it, and add (require 'org-jekyll) to your .emacs.

Moving to Orgmode 8.0

The master branch now supports 8.0. If you are still in Orgmode 7.* use instead the org-mode-7 branch.

Configuration options

Org-jekyll understands three options that you can add to your project's org-publish-project-alist:

  1. :blog-publishing-directory, where to publish the blog within your site. By default goes to root.
  2. :site-root is your blog's site name, like "http://juanreyero.com". Used to build the entries' titles as absolute links. If not set the links will be relative, and will appear broken in some feeds aggregators and in Google Buzz.
  3. :jekyll-sanitize-permalinks, set to t if you want your permalinks to be free of áccènted çhars (and therefore safe for all browsers). You probably want to set this to t anyway, just in case.

As an example, this is my site's configuration alist:

(setq org-publish-jr "~/cjr/jr/publish/")
(setq org-publish-jr-blog "~/cjr/jr/")

(setq org-jekyll-lang-subdirs '(("en" . "publish-blog/blog/")))

(add-to-list 'org-publish-project-alist
             `("jr-org"
               :base-directory "~/cjr/jr/"
               :recursive t
               :base-extension "org"
               :publishing-directory ,org-publish-jr
               :exclude "^blog\\|^bitacora\\|jr.org"
               :site-root "http://juanreyero.com"
               :jekyll-sanitize-permalinks t
               :publishing-function org-html-publish-to-html
               :section-numbers nil
               :headline-levels 4
               :table-of-contents t
               :auto-index nil
               :auto-preamble nil
               :body-only nil
               :auto-postamble nil))

(add-to-list 'org-publish-project-alist
             `("jr-img"
               :base-directory "~/cjr/jr/"
               :recursive t
               :exclude "^publish"
               :base-extension "jpg\\|gif\\|png"
               :publishing-directory ,org-publish-jr
               :publishing-function org-html-publish-attachment))

(add-to-list 'org-publish-project-alist
             '("jr" :components ("jr-org"
                                 "jr-img")))

(add-to-list 'org-publish-project-alist
             `("jr-blog"
               :base-directory "~/cjr/jr/"
               :recursive t
               :base-extension "org"
               :publishing-directory ,org-publish-jr
               :blog-publishing-directory ,org-publish-jr-blog
               :site-root "http://juanreyero.com"
               :jekyll-sanitize-permalinks t
               :publishing-function org-html-publish-to-html
               :section-numbers nil
               :headline-levels 4
               :table-of-contents nil
               :auto-index nil
               :auto-preamble nil
               :body-only t
               :auto-postamble nil))

See also localization and categories options.

Overview

Jekyll is a web-site generator that filters a site's files through a templating system. It will process any file that has yaml front-matter, so if you want the export of any file to be modified by Jekyll you only have to add something like this at the very beginning of the file:

#+begin_html
---
layout: default
title: Who knows
---
#+end_html

But Jekyll has a special deal for files in the _posts directory whose name is of the form year-month-day-something-or-other.html: it considers them blog posts and makes their exported versions available to the templating system, so you can use them to build RSS feeds and indexes.

Other approaches rely on writing your blog posts in separate files and exporting them to _posts with the right name, which is perfectly good if you want each post it a file. Org-jekyll is for you if you want to litter your outlines with posts, as I do, without having to think too much about where to store them.

See also the tutorial on jekyll and org-mode integration.

Where do you write your posts

It doesn't matter, but if you want to combine your blog with a site exported by org-publish it is convenient to have them as sub-trees of a tree with the :noexport: and :blog: keywords. The :noexport: prevents double exporting (as blog posts with org-jekyll and as parts of the file they belong to when exported with org-publish).

A simple way to set it up is with org-remember and the great date-tree. The remember template looks something like this:

("Jac" ?c
 "* %^{Title}  :blog:\n  :PROPERTIES:\n  :on: %T\n  :END:\n  %?\n  %x"
 "~/cjr/jac/jac.org" date-tree)

Usage

Visit a file that belongs to the org-publish project that contains your blog posts. Run M-x org-jekyll-export-blog if you want to export the whole blog, or M-x org-jekyll-export-current-entry if you only want to update the current entry. See the _posts/ subdirectory of your project's publish directory being populated with your posts. Then run jekyll.

Localization

Org-jekyll has some support for localization. If you define a :lang: property in an entry it will be used to look for a [lang].yml localization file in the org-jekyll-localize-dir directory (by default loc/). This yaml file will be included in the front matter of the exported entry. Look at the source of GreaterSkies for an example of how this works.

Categories

Categories have a special treatment in Jekyll: they are used to change the directory to which the post is written, as in [category]/_posts. You can use org-jekyll-category to specify a property which, if defined in an entry, will be used as a category. It defaults to lang, so that if you are using the :lang: property to localize you'll end up with posts in places like en/_posts/.

Stability and known issues

It works well enough that I can use it to produce the blog without much trouble, but I do find glitches from time to time.

Do not finish an entry with #+end_quote

It messes things up pretty bad. Add an empty line at the end. I don't know yet why this happens.

Acknowledgements

Special thanks to Eric Schulte, who saved the day with some org-babel code and this timely help.

Also to Nathan Neff, who spotted a bug, Sebastian Rose, who provided a suggestion of how to solve it.

Matt Curtis formatted for package manager in Emacs 24, Guillaume Papin made post tiles clickable, Jianing Yang fixed compatibility for Orgmode 8.0 and added org-jekyll-export-project.

Juan Reyero Barcelona, 2009-12-27
 

blog comments powered by Disqus