+title: org2jekyll
+author: ardumont
[[https://travis-ci.org/ardumont/org2jekyll][file:https://travis-ci.org/ardumont/org2jekyll.svg?branch=master]]
[[https://coveralls.io/github/ardumont/org2jekyll?branch=master][file:https://coveralls.io/repos/github/ardumont/org2jekyll/badge.svg?branch=master]]
[[https://melpa.org/#/org2jekyll][file:https://melpa.org/packages/org2jekyll-badge.svg]]
[[https://stable.melpa.org/#/org2jekyll][file:https://stable.melpa.org/packages/org2jekyll-badge.svg]]
[[https://www.gnu.org/licenses/gpl-2.0.txt][file:https://img.shields.io/:license-GPLv2-blue.svg]]
[[https://archive.softwareheritage.org/badge/origin/https://github.com/ardumont/org2jekyll/][file:https://archive.softwareheritage.org/badge/origin/https://github.com/ardumont/org2jekyll/]]
Blogging with org-mode and jekyll without alien yaml headers.
-
Table of Contents :TOC_4:
-
[[#upgrade][Upgrade]]
- [[#026---027][0.2.6 -> 0.2.7]]
- [[#022---023][0.2.2 -> 0.2.3]]
- [[#021---022][0.2.1 -> 0.2.2]]
- [[#020---021][0.2.0 -> 0.2.1]]
- [[#018---019][0.1.8 -> 0.1.9]]
- [[#012---014][0.1.2 -> 0.1.4]]
-
[[#description][Description]]
- [[#rationale][Rationale]]
- [[#pre-requisite][Pre-requisite]]
-
[[#installsetup][Install/Setup]]
- [[#install][Install]]
- [[#setup][Setup]]
- [[#a-running-example][A running example]]
- [[#a-reproducible-example][A reproducible example]]
-
[[#use][Use]]
- [[#post][Post]]
- [[#headers][Headers]]
- [[#publish][Publish]]
- [[#how][How]]
- [[#extra-headers][Extra headers]]
- [[#page][Page]]
- [[#headers-1][Headers]]
- [[#publish-1][Publish]]
- [[#how-1][How]]
- [[#extra-headers-1][Extra-headers]]
- [[#publish-all-posts][Publish all posts]]
- [[#publish-all-pages][Publish all pages]]
- [[#previews][Previews]]
-
[[#minor-mode][Minor mode]]
-
[[#customization][Customization]]
- [[#layout][Layout]]
- [[#draft][Draft]]
-
[[#about-internal-publication-links][About internal publication links]]
-
[[#problems][Problems]]
- [[#dependencies][dependencies]]
-
Upgrade
** 0.2.6 -> 0.2.7
- We can now export properly links to other internal publications. See
[[#about-internal-publication-links][#about-internal-publication-links]] for more details.
** 0.2.2 -> 0.2.3
** 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 M-x org2jekyll-mode 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 [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Coding-Conventions.html][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.
Let org2jekyll export your org-mode file to jekyll.
What's the difference with [[https://github.com/juanre/org-jekyll][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 [[https://github.com/bmaland/happyblogger][happyblogger]]?
Only emacs' dependencies (org, etc...) no external ruby script.
** Rationale
Enters org2jekyll.
** Pre-requisite
You have:
** Install
Available on [[http://melpa.org/#/getting-started][melpa]].
Update your packages archives:
+begin_src emacs-lisp
(require 'package)
(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)
+end_src
/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 [[http://ardumont.github.io/][blog site configuration]]:
+begin_src emacs-lisp
(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")))))
+end_src
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 [[#layout][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 [[https://github.com/ardumont/org2jekyll/blob/master/testing-blog/org/blogging-with-org2jekyll.org][local article]].
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:
M-x org2jekyll-mode
This installs the necessary cogs for org2jekyll to work properly ([[https://github.com/ardumont/org2jekyll/issues/38][issue 38]]).
** Post
*** Headers
For a post (layout 'post'):
#+begin_src org
#+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
#+end_src
*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 [[https://github.com/ardumont/org2jekyll/issues/36][issue 36]], you could [[http://jekyllrb.com/docs/frontmatter/#predefined-global-variables][need to add some extra jekyll headers]].
Simply add them as org properties (thanks [[https://github.com/halcyon][@halcyon]] for his work on [[https://github.com/ardumont/org2jekyll/pull/41][#41]]).
For example, adding those properties in the org file:
#+BEGIN_SRC org
#+THEME: blah
#+PLUGIN: lightense
#+SCHEME-HOVER: "#ff00b4"
#+END_SRC
Then publishing, will generate:
#+BEGIN_SRC yaml
---
...
theme: blah
plugin: lightense
scheme-hover: "#ff00b4"
---
#+END_SRC
** Page
*** Headers
For a page (layout 'default').
#+begin_src org
#+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
#+end_src
*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. [[#extra-headers][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:
#+begin_src emacs-lisp
(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))
#+end_src
*Note* [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Key-Binding-Conventions.html#Key-Binding-Conventions][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:
#+BEGIN_SRC sh
(custom-set-variables
'(org2jekyll-jekyll-layout-page "page")
'(org2jekyll-jekyll-layout-post "post")
'(org2jekyll-jekyll-layouts '("page" "post")))
#+END_SRC
It's up to the users to make sure the entries are correctly configured in the
`org-publish-project-alist`.
See for example [[https://github.com/ardumont/org2jekyll/blob/master/testing-blog/testing-blog-config.el][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, [[https://github.com/ardumont/org2jekyll/issues/47][issue 47 need]], a user could define the following:
#+BEGIN_SRC emacs-lisp
(custom-set-variables
'(org2jekyll-default-template-entries-extra '(("comments" "true") ("theme" "awesome")))
#+END_SRC
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:
#+BEGIN_SRC org
[[local:/interesting-post]]
#+END_SRC
will render into a proper html `a` anchor linking to your interesting post. See
[[https://github.com/ardumont/org2jekyll/issues/66][#66 issue for more details]].
* Problems
** dependencies
As a note, org2jekyll [[https://github.com/ardumont/org2jekyll/blob/master/org2jekyll.el#L8][declares its dependencies]] but it's possible that
some are not fully respected. And then problem [[#43][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.