The goal of ox-blog
is to be a user-friendly, batteries-included blogging environment for emacs.
It is built on top of the awesome org export framework and provides
- development server with livereload
- automatic export on save
- post categories (with index page for each category)
- small codebase & dependency list
- dependencies:
org-plus-contrib
,htmlize
- < 1000 lines of code
- dependencies:
- motivation to actually write posts (i wish… this package exists because I’m procrastinating and not writing posts)
- Put
ox-blog.el
into your load path - Create a blog directory
- Create
.dir-locals.el
in the blog directory with the following contents;; .dir-locals.el in ~/blog. Adapt directories to your liking ((nil . ((eval . (ox-blog-mode 1)) (ox-blog-project . (:source-directory "~/blog/source/" :export-directory "~/blog/export/")))))
- Create a post in the source-directory and visit
localhost:8000
#+TITLE: Hello World #+DATE: <2018-01-01> #+TYPE: post Lorem Ipsum
- Check out the exported example blog and its source
- ox-blog project option can be found under the
org-export-blog
group incustomize
.
The values can be changed by setting the defaults or overwriting them in yourox-blog-project
definition.(get 'org-export-blog 'custom-group)
((ox-blog-project custom-variable) (ox-blog-excluded-files custom-variable) (ox-blog-force-export custom-variable) (ox-blog-with-drafts custom-variable) (ox-blog-index-head custom-variable) (ox-blog-babel-header-args custom-variable) (ox-blog-babel-evaluate custom-variable) (ox-blog-server-idle-seconds custom-variable) (ox-blog-server-port custom-variable) (ox-blog-server-livereload-script custom-variable) (ox-blog-server-base-url custom-variable) (ox-blog-index-template custom-variable) (ox-blog-index-format-function custom-variable) (ox-blog-index-item-format-function custom-variable) (ox-blog-page-category custom-variable))
org-export-html
options can be listed with(org-export-get-all-options 'html)
(org-export-get-all-options 'html)
((:html-doctype "HTML_DOCTYPE" nil org-html-doctype) (:html-container "HTML_CONTAINER" nil org-html-container-element) (:description "DESCRIPTION" nil nil newline) (:keywords "KEYWORDS" nil nil space) (:html-html5-fancy nil "html5-fancy" org-html-html5-fancy) (:html-link-use-abs-url nil "html-link-use-abs-url" org-html-link-use-abs-url) (:html-link-home "HTML_LINK_HOME" nil org-html-link-home) (:html-link-up "HTML_LINK_UP" nil org-html-link-up) (:html-mathjax "HTML_MATHJAX" nil "" space) (:html-postamble nil "html-postamble" org-html-postamble) (:html-preamble nil "html-preamble" org-html-preamble) (:html-head "HTML_HEAD" nil org-html-head newline) (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline) (:subtitle "SUBTITLE" nil nil parse) (:html-head-include-default-style nil "html-style" org-html-head-include-default-style) (:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts) (:html-allow-name-attribute-in-anchors nil nil org-html-allow-name-attribute-in-anchors) (:html-divs nil nil org-html-divs) (:html-checkbox-type nil nil org-html-checkbox-type) (:html-extension nil nil org-html-extension) (:html-footnote-format nil nil org-html-footnote-format) (:html-footnote-separator nil nil org-html-footnote-separator) (:html-footnotes-section nil nil org-html-footnotes-section) (:html-format-drawer-function nil nil org-html-format-drawer-function) (:html-format-headline-function nil nil org-html-format-headline-function) (:html-format-inlinetask-function nil nil org-html-format-inlinetask-function) (:html-home/up-format nil nil org-html-home/up-format) (:html-indent nil nil org-html-indent) (:html-infojs-options nil nil org-html-infojs-options) (:html-infojs-template nil nil org-html-infojs-template) (:html-inline-image-rules nil nil org-html-inline-image-rules) (:html-link-org-files-as-html nil nil org-html-link-org-files-as-html) (:html-mathjax-options nil nil org-html-mathjax-options) (:html-mathjax-template nil nil org-html-mathjax-template) (:html-metadata-timestamp-format nil nil org-html-metadata-timestamp-format) (:html-postamble-format nil nil org-html-postamble-format) (:html-preamble-format nil nil org-html-preamble-format) (:html-table-align-individual-fields nil nil org-html-table-align-individual-fields) (:html-table-caption-above nil nil org-html-table-caption-above) (:html-table-data-tags nil nil org-html-table-data-tags) (:html-table-header-tags nil nil org-html-table-header-tags) (:html-table-use-header-tags-for-first-column nil nil org-html-table-use-header-tags-for-first-column) (:html-tag-class-prefix nil nil org-html-tag-class-prefix) (:html-text-markup-alist nil nil org-html-text-markup-alist) (:html-todo-kwd-class-prefix nil nil org-html-todo-kwd-class-prefix) (:html-toplevel-hlevel nil nil org-html-toplevel-hlevel) (:html-use-infojs nil nil org-html-use-infojs) (:html-validation-link nil nil org-html-validation-link) (:html-viewport nil nil org-html-viewport) (:html-inline-images nil nil org-html-inline-images) (:html-table-attributes nil nil org-html-table-default-attributes) (:html-table-row-open-tag nil nil org-html-table-row-open-tag) (:html-table-row-close-tag nil nil org-html-table-row-close-tag) (:html-xml-declaration nil nil org-html-xml-declaration) (:html-klipsify-src nil nil org-html-klipsify-src) (:html-klipse-css nil nil org-html-klipse-css) (:html-klipse-js nil nil org-html-klipse-js) (:html-klipse-selection-script nil nil org-html-klipse-selection-script) (:infojs-opt "INFOJS_OPT" nil nil) (:creator "CREATOR" nil org-html-creator-string) (:with-latex nil "tex" org-html-with-latex) (:latex-header "LATEX_HEADER" nil nil newline))
Publishing is done via git. Use ox-blog-publish
to export & push the exported files.
All you need to do is
- create a git repository in your
:export-directory
- set the origin remote
- OPTIONAL
- check out a branch
- add a
.gitignore
file (e.g. to not push files in thedrafts/
folder)
Follow https://pages.github.com/
In the :export-directory
run
git init
git remote add origin git@github.com:username/username.github.io.git
Run ox-blog-publish
make install
make test
https://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html emacsattic/org-magit#5
- :filter-alist overrides in project
Sometimes posts are related and it would be nice to keep them in the same file. Problem: Caching via modified timestamp of file falls apart for multi-post files
The emacs --batch
already works using 2 lines of glue code so this is low
priority.
- Htmlize css classes seems like a fragile solution. Requires an up to date list of all faces used in the blog.
- Export from clean emacs session using
emacs --batch
. Can load any theme and set variables to liking without conflicting with actual session. This already works (see Makefile export task) - Change where htmlize gets it’s face definitions from. loading a theme adds
the face definitions to the face symbol. Could look at the symbol plist
rather than the currently applied setting. Also look into
htmlize-face-overrides
:feed-template
:feed-function
:feed-item-function
naming is hard - no good ideas yet file-name -> file -> post (doesn’t work for non-post org-nodes)