An experiment with using Org mode to write Jekyll blog posts.
Table of Contents
Much of what I've read about Org mode has focused on its utility as a task management tool. That's great. I wouldn't mind spending some time on that aspect. Mostly I've been focused on its usefulness for note-taking and writing.
Org mode includes features which make it attractive for blogging and journaling. It has a relatively simple set of markup rules for common constructs such as paragraphs, lists, source code, and tables. The mode itself provides an editing interface which simplifies creating and managing those constructs. Most importantly for the blogger, org files can be exported to a range of formats including Markdown and HTML.
When I'm using Org mode to write the blog pages, Jekyll becomes an
implementation detail specific to publishing the blog. One folder
contains all of the Jekyll project files, and an
mirrors the content-specific structure of the
+jekyll +- css +- _data +- _drafts +- img +- _includes +- _layouts +- pages +- _plugins +- _posts +- _sass +- _scripts +- _site +org +- _drafts +- _posts +- pages
_drafts because I don't always know when I will be
publishing a post, and
pages because I have legacy content that
will get rewritten in Org format as it gets updated.
The front matter used by Jekyll and other engines to determine content metadata requires some special handling to get exported correctly by Org mode. The most straightforward thing is to use the suggestion from the instructions mentioned earlier. Put your front matter in a HTML block right at the top of the file.
#+BEGIN_HTML --- title: Blog Writing in Org Mode layout: post category: Emacs tags: org jekyll --- #+END_HTML
Okay, it's not HTML. But Org mode doesn't really care. It will get passed through untouched when you export.
Configure HTML Export
HTML and other output needs to be placed correctly within the
Jekyll layout conventions. A proper
will take care of this.
(setq org-publish-project-alist '( ("org-randomgeekery" ;; Location of org files :base-directory "~/Projects/randomgeekery.org/org/" :base-extension "org" ;; Location of Jekyll files :publishing-directory "~/Projects/randomgeekery.org/jekyll/" :recursive t :publishing-function org-publish-org-to-html :headline-levels 4 :html-extension "html" ;; Only export section between <body></body> :body-only t) ("org-static-randomgeekery" :base-directory "~/Projects/randomgeekery.org/org/" :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg" :publishing-directory "~/Projects/randomgeekery.org/" :recursive t :publishing-function org-publish-attachment) ("rg" :components ("org-randomgeekery" "org-static-randomgeekery")) ))
Now when I export the project with
org-mode-export (C-c C-e X) rg, all of my org
content for the project gets put in the correct spot. I even get a
table of contents, which is not such a bad thing.
Publishing A Post
So when you've been editing a draft long enough and you're ready to
make it a real live post, you need to move the file from
_posts, with the publish date prefixing the filename.
I could do that manually, but it's tedious to do that for every blog post.
I experiment with my rudimentary Emacs Lisp skills to create a new filename that looks about right.
(defun post-it () "Write current draft file as a Jekyll post file" (interactive) (if (string-match "_drafts" buffer-file-name) (let ((draft-copy buffer-file-name) (post-copy ;; _drafts/<stub>.org ;; becomes ;; _posts/yyyy-mm-dd-<stub>.org (concat (replace-regexp-in-string "_drafts" "_posts" (file-name-directory buffer-file-name)) (format-time-string "%Y-%m-%d") "-" (file-name-nondirectory buffer-file-name) ) )) (write-file post-copy) ) (message "%s is not in _drafts!" (file-name-nondirectory buffer-file-name)) ) )
Awkward, but it works. It worked at least once, anyways. Should
manually remove the original
_draft file until I know what I'm
doing a little more.
Warning: See that Lisp I wrote? It's probably wrong in some horrible way. It's the most complex Elisp I've ever managed. Look at it for interesting ideas, but please don't just copy and paste.
I wonder if maybe this isn't the best approach, since it seems to
confuse the heck out of Org mode. My lone org file just would not
republish until I found this post for a similar situation. If it's
just not rebuilding, force it with a numeric argument:
C-u 0 C-c e.
This works well enough to get one post published, anyways. I'm sure to revisit this topic as I continue to learn more about Org mode and Emacs.