Skip to content

ardumont/org2jekyll

Repository files navigation

org2jekyll

https://travis-ci.org/ardumont/org2jekyll.svg?branch=master https://coveralls.io/repos/github/ardumont/org2jekyll/badge.svg?branch=master https://melpa.org/packages/org2jekyll-badge.svg https://stable.melpa.org/packages/org2jekyll-badge.svg https://img.shields.io/:license-GPLv2-blue.svg https://archive.softwareheritage.org/badge/origin/https://github.com/ardumont/org2jekyll/

Blogging with org-mode and jekyll without alien yaml headers.

Table of Contents

Upgrade

0.2.6 -> 0.2.7

0.2.2 -> 0.2.3

  • User can now extend the default templates with default values on their own (at draft creation time). Thanks for issue 47 which revealed the need. See #draft for more details.

0.2.1 -> 0.2.2

  • The toc:t is now respected. Please make sure you want your table of contents (`toc:t`) or not (`toc:nil`).
  • Note that org2jekyll changed internally how it’s working and rely a bit further on org-mode mechanism (so it’s good ;). Notably, it uses a hook at the end of the publishing step to prepend the jekyll yaml headers. You need to activate <kbd>M-x org2jekyll-mode</kbd> for that hook to be installed though (respectively deactivate org2jkeyll-mode to remove that hook).

0.2.0 -> 0.2.1

  • The `tags:nil` option is now respected, aligning with org-mode. So, when nil, those are not exported in yaml headers. Please make sure you want those activated (`tags:t`) or not (`tags:nil`).
  • When generating new org2jekyll buffer, the default option is now `tags:t`
  • `#+TAGS` and `#+CATEGORIES` are no longer comma separated values but space separated values. This is also to be in check with org-mode.

0.1.8 -> 0.1.9

  • Remove deprecated api function names mentioned in 0.1.2 -> 0.1.4 migration.
  • Allow user to define on per-buffer setup or per-custom variable basis some extra yaml header

0.1.2 -> 0.1.4

The elisp coding convention was not respected up to this version. So between the 0.1.2 and 0.1.3 version, the names and variables were updated to respect them. Now every command and variables uses `org2jekyll-` and no longer `org2jekyll/` prefix.

Description

Let org2jekyll export your org-mode file to jekyll.

What’s the difference with org-jekyll?

You don’t need to add some alien yaml in your org-mode file. You add specific org-mode headers and this will be used to format the jekyll post.

What’s the difference with happyblogger?

Only emacs’ dependencies (org, etc…) no external ruby script.

Rationale

  • org-mode rocks
  • Github uses Jekyll
  • Jekyll is nice
  • Existing solutions regarding org-mode and jekyll need the org-mode files to be altered with non-org notations to work together
  • I don’t want to alter my org-mode files with alien yaml headers to satisfy jekyll

Enters org2jekyll.

Pre-requisite

You have:

Install/Setup

Install

Available on melpa.

Update your packages archives:

(require 'package)
(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)

M-x package-install RET org2jekyll RET

Setup

org2jekyll leverage org-mode’s publish abilities (`ox-publish`), so it needs the `org-publish-project-alist` custom to be defined to something sensible regarding your blogging setup.

M-x customize-group RET org2jekyll RET

For example, here is my blog site configuration:

(require 'org)
(require 'org2jekyll)

(custom-set-variables '(org2jekyll-blog-author "ardumont")
                      '(org2jekyll-source-directory (expand-file-name "~/org/"))
                      '(org2jekyll-jekyll-directory (expand-file-name "~/repo/public/ardumont.github.io/"))
                      '(org2jekyll-jekyll-drafts-dir "")
                      '(org2jekyll-jekyll-posts-dir "_posts/")
                      '(org-publish-project-alist
                        `(("default"  ;; mostly static pages: about me, about, etc...
                           :base-directory ,(org2jekyll-input-directory)
                           :base-extension "org"
                           :publishing-directory ,(org2jekyll-output-directory)
                           :publishing-function org-html-publish-to-html
                           :headline-levels 4
                           :html-head "<link rel=\"stylesheet\" href=\"./css/style.css\" type=\"text/css\"/>"
                           :html-preamble t
                           :recursive t
                           :make-index t
                           :html-extension "html"
                           :body-only t)
                          ("post"  ;; dynamic pages like blog articles
                           :base-directory ,(org2jekyll-input-directory)
                           :base-extension "org"
                           :publishing-directory ,(org2jekyll-output-directory org2jekyll-jekyll-posts-dir)
                           :publishing-function org-html-publish-to-html
                           :headline-levels 4
                           :html-head "<link rel=\"stylesheet\" href=\"./css/style.css\" type=\"text/css\"/>"
                           :html-preamble t
                           :recursive t
                           :make-index t
                           :html-extension "html"
                           :body-only t)
                          ("images"
                           :base-directory ,(org2jekyll-input-directory "img")
                           :base-extension "jpg\\|gif\\|png"
                           :publishing-directory ,(org2jekyll-output-directory "img")
                           :publishing-function org-publish-attachment
                           :recursive t)
                          ("js"
                           :base-directory ,(org2jekyll-input-directory "js")
                           :base-extension "js"
                           :publishing-directory ,(org2jekyll-output-directory "js")
                           :publishing-function org-publish-attachment
                           :recursive t)
                          ("css"
                           :base-directory ,(org2jekyll-input-directory "css")
                           :base-extension "css\\|el"
                           :publishing-directory ,(org2jekyll-output-directory "css")
                           :publishing-function org-publish-attachment
                           :recursive t)
                          ("web" :components ("images" "js" "css")))))

source: https://gitlab.com/ardumont/home/-/blob/master/emacs/blog-pack.el#L18-69

The previous sample contains important information:

  • default and post represent the possible jekyll layouts you can use in your org2jekyll buffer `#+LAYOUT: default|post` (you can name those differently, follow the customization layout section)
  • images, js, css represent where you choose to store those kinds of files (you can name these as you wish)
  • web is a composition of web files you may need to create a full post or page, typically, css, images, html, js, etc… (do not name this one differently either)

A running example

Note Yes, I may have to merge the last 2 repositories at some point…

A reproducible example

You can clone this repository. Then, try and follow this local article.

Use

For a post (layout ‘post’) or page (layout ‘default’), add org headers (layout, title, author, date, description, categories) to your org files.

Activate the `org2jekyll-mode` in the buffer you wish to publish: <kdb>M-x org2jekyll-mode</kbd>

This installs the necessary cogs for org2jekyll to work properly (issue 38).

Post

Headers

For a post (layout ‘post’):

#+STARTUP: showall
#+STARTUP: hidestars
#+OPTIONS: H:2 num:nil tags:nil toc:nil timestamps:t
#+LAYOUT: post
#+AUTHOR: ardumont
#+DATE: 2014-12-19 Fri 23:49
#+TITLE: hello
#+DESCRIPTION: some description
#+CATEGORIES: category0, category1

Note To easily do that, M-x org2jekyll-create-draft, this will ask you for everything needed and create a file with such metadata.

Publish

Now write your article in org-mode.

When ready, M-x org2jekyll-publish to publish it.

This will be published as post article.

How

  • The #+LAYOUT entry refers to the post entry in org-publish-project-alist.
  • This will create another temporary org-mode file based on the current one with the right naming convention, transform the org headers into yaml, publish to the jekyll directory (according to your org-publish setup) and delete the temporary file.

Extra headers

As in issue 36, you could need to add some extra jekyll headers.

Simply add them as org properties (thanks @halcyon for his work on #41).

For example, adding those properties in the org file:

#+THEME: blah
#+PLUGIN: lightense
#+SCHEME-HOVER: "#ff00b4"

Then publishing, will generate:

---
...
theme: blah
plugin: lightense
scheme-hover: "#ff00b4"
---

Page

Headers

For a page (layout ‘default’).

#+STARTUP: showall
#+STARTUP: hidestars
#+OPTIONS: H:2 num:nil tags:nil toc:nil timestamps:t
#+LAYOUT: default
#+AUTHOR: ardumont
#+DATE: 2014-12-19 Fri 23:49
#+TITLE: hello
#+DESCRIPTION: some description
#+CATEGORIES: some-category

Note To easily do that, M-x org2jekyll-create-draft, this will ask you for everything needed and create a file with such metadata.

Now create your article and publish it when ready M-x org2jekyll-publish.

Publish

Write your page. When ready, M-x org2jekyll-publish to publish it.

How

  • The #+LAYOUT entry refers to the default entry in org-publish-project-alist.
  • This will update the current org-mode with the necessary yaml and publish to the jekyll directory (according to your org-publish setup), then revert back to your normal org-mode file.

Extra-headers

cf. post extra-headers

Publish all posts

M-x org2jekyll-publish-posts

Depending on your org-publish configuration and org2jekyll, this will compile the list of org-mode posts (#+LAYOUT with ‘post’ value) and publish them.

Publish all pages

M-x org2jekyll-publish-pages

Depending on your org-publish configuration and org2jekyll, this will compile the list of org-mode pages (#+LAYOUT with ‘default value) and publish them.

Previews

You can keep an org file in your blog directory without publishing it, by writing it as a plain org file without the org2jekyll headers. Once you’re ready to publish it as a post or an article, add the appropriate metadata headers and org2jekyll will now publish the file.

Minor mode

org2jekyll provides you a minor mode with the following default binding:

(setq org2jekyll-mode-map
      (let ((map (make-sparse-keymap)))
        (define-key map (kbd "C-c . n") 'org2jekyll-create-draft)
        (define-key map (kbd "C-c . p") 'org2jekyll-publish-post)
        (define-key map (kbd "C-c . P") 'org2jekyll-publish-posts)
        (define-key map (kbd "C-c . l") 'org2jekyll-list-posts)
        (define-key map (kbd "C-c . d") 'org2jekyll-list-drafts)
        map))

Note Respecting the default minor mode convention for binding

To (de)activate this in an org file: M-x org2jekyll-mode

As usual, you can use emacs’ power to setup your own bindings.

Customization

Layout

By default org2jekyll uses the layouts “post” (for article blog post) and “default” (for mostly dynamic pages, e.g. contact, about, …). This now can be customized:

(custom-set-variables
 '(org2jekyll-jekyll-layout-page  "page")
 '(org2jekyll-jekyll-layout-post  "post")
 '(org2jekyll-jekyll-layouts     '("page" "post")))

It’s up to the users to make sure the entries are correctly configured in the `org-publish-project-alist`.

See for example this sample configuration which define their own while keeping correctly the `org-publish-project-alist` in sync.

Draft

By default, a draft has a fixed set of headers. It is now possible to configure extra set of headers (with fixed values).

To answer, for example, issue 47 need, a user could define the following:

(custom-set-variables
  '(org2jekyll-default-template-entries-extra '(("comments" "true") ("theme" "awesome")))

Which would then append the `#+COMMENTS: true` and `#+THEME: awesome` to the default template org2jekyll generates by default. All following created drafts would be created with that extra comments headers.

About internal publication links

You can now link properly between your jekyll publications. You need however to prefix your local links with the `local:` prefix.

For example:

[[local:/interesting-post]]

will render into a proper html `a` anchor linking to your interesting post. See #66 issue for more details.

Problems

dependencies

As a note, org2jekyll declares its dependencies but it’s possible that some are not fully respected. And then problem may arise. So if you found out a problem about it, feel free to open an issue mentioning the version of the library you are using.