How to Use Org With Jekyll to Blog
Table of Contents
Org-mode is awesome and it could be better if we can publish a blog post with it and Jekyll (not markdown).
Follow the steps that I've used to blog using org-mode.
Folder Structure
First of all, define the folder structure for your project to have org files and Jekyll folder structure.
. ├── zettels │ ├── _public │ │ └── 2024-06-06-how_to_use_org_with_jekyll_to_blog.org ├── assets │ └── me.png └── web ├── _config.yml ├── _posts │ └── 2024-06-06-how_to_use_org_with_jekyll_to_blog.html (generated) ├── _site (generated) ├── assets │ └── me.png ├── build.sh └── launch.sh
This is partially the structured folder that I've used for my Zettelkasten Brain (private).
The zettels
folder is for private notes, and the _public
folder is for public notes (as this post you're reading).
The web
folder is for the static result site.
At end of the day, the org file is converted to HTML file and put on web _posts folder.
Build and Run the Site
To build and run the Jekyll site, use these commands:
jekyll new web cd web bundle exec jekyll serve --livereload
Now, you'll see the "hello world" from Jekyll on port 4000.
The Org File
The org file must generate at the top of the file a Front-Matter markdown.
This is an example for this current post:
:PROPERTIES: :ID: 0311029D-11E0-4AFC-B5A1-1E8E9A761130 :END: #+title: How to Use Org With Jekyll to Blog #+created: [2024-06-06 Thu 18:57] #+filetags: :blog: #+status: #zettel/fleeting #+STARTUP: showall indent #+OPTIONS: toc:nil num:nil #+BEGIN_EXPORT html --- layout: post title: "How to Use Org With Jekyll to Blog" date: "2024-06-06 18:57:25" slug: "org-blog-jekyll" categories: - scripts - web --- #+END_EXPORT #+TOC: headlines 2 Org-mode is awesome and it could be better if we can publish a blog post with it and Jekyll (not markdown).
The first block is for org-roam identifier.
The startup defines how the Emacs handle the file (expand all headings and indent correctly).
This options block tells to the exporter to not add Table of Content automatically and do not add numbers for headings (I'll add manually after that).
The begin export block allows the exporter to copy and past the Front-Matter directly to the HTML output file. I mean, this is not parsed.
At the end, the toc block add the Table of Content and with two heading level.
The Correct Links for Exporting
The default org export generates hrefs links with name + org ID. Let's see an example: (2024-06-06-how_to_use_org_with_jekyll_to_blog.html#0311029D-11E0-4AFC-B5A1-1E8E9A761130
).
But, if we keep this default configuration, our links would be broken. However, we want to keep the relationship between org files.
If you want to keep the relationship between org files and at same time keep the correct web slug linking, you must use the relative link this: [[../my-slog]]
and for backlink IDs of Org-roam, add the links below headings with :noexport:
.
Now, when we export the HTML, only the correct link will be exported to the public web.
The Graph View and Org-roam keep working as expected.
*References :noexport: /backlinks here will be not exported/ - [[id:02D61138-0AAB-4657-A33E-4AF73E6B804E][How to Structure Zettelkasten Brain]] - [[id:8FD30EBD-8ADE-4941-B86A-A26F28B89F11][Org-Roam]] - [[id:05808B95-B7DF-4ED9-A8D0-7EBCBAEAF680][Org Mode CheatSheet]]
Generate notes
To generate some notes, you'll need to configure the Org-Roam (private) and org-mode with export feature.
The org-publish allow us to generate a HTML file from _public
to web/_posts
(And the assets
to web/assets
).
After that, the Jekyll will responsable for generating the final HTML.
Create a file ~/.emacs.d/scripts/org-export.el
and add this content:
(require 'ox) (require 'ox-html) (require 'ox-publish) (setq org-publish-project-alist '(("org-notes" ;; Path to your org files. :base-directory "~/brain/zettels/_public/" :base-extension "org" ;; Path to your Jekyll project. :publishing-directory "~/brain/web/_posts/" :recursive t :publishing-function org-html-publish-to-html :headline-levels 4 :html-extension "html" :body-only t) ;; Only export section between <body> </body> ("org-static" :base-directory "~/brain/assets" :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|php" :publishing-directory "~/brain/web/assets" :recursive t :publishing-function org-publish-attachment) ("org" :components ("org-notes" "org-static")))) (provide 'org-export)
Inside the .emacs
file, add the scripts folder to the path and load the new org-export file:
(add-to-list 'load-path "~/.emacs.d/scripts") (require 'org-export)
The file defines how the org-mode must generate the HTML files and where to put it.
Now, to export the Org file to HTML file use the shortcut:
C-c C-e P a
As shows in Org-mode CheatSheet (private) or run:
M-x org-publish-all (C-c n p)
.
Check the web
folder.
If you can see the result HTML file in _posts
, it worked!
Generate notes from Command-Line
To build from terminal, create a file ~/.emacs.d/scripts/build-site.el
and add the content:
(add-to-list 'load-path "~/.emacs.d/scripts") (require 'org-export) (org-publish-all t) (message "Build complete!")
Now, we can run this lisp script from terminal:
emacs -Q --script ~/.emacs.d/scripts/build-site.el
You can create a build.sh
file to run this scripts for you. Also the launch.sh
script to launch the Jekyll with live reload.