diff options
author | Vincent Ambo <tazjin@gmail.com> | 2017-11-12T22·48+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@gmail.com> | 2017-11-12T22·48+0100 |
commit | 3d4aba1803930453f1942b0e1b1648309c2da88b (patch) | |
tree | 30e56c931b5cd74b076594b9141d1d26f640d384 /blog.el | |
parent | e2c475542616c33d92067b21782a441dd396bd32 (diff) |
feat(blog): Add initial elblog implementation
Implements a (very) simple "blogging" software in Emacs Lisp using org-mode and elnode. Once loaded and started, elblog will serve individual blog posts at `localhost:8010/en/$post-name`, where "post-name" can be any string. Elblog will attempt to find a buffer called "$post-name.org" and render it to HTML. An index of blog posts is currently not implemented and everything is completely unthemed, but for a language this old this is ridiculously productive given the amount of code.
Diffstat (limited to 'blog.el')
-rw-r--r-- | blog.el | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/blog.el b/blog.el new file mode 100644 index 000000000000..0407f98c6ffe --- /dev/null +++ b/blog.el @@ -0,0 +1,49 @@ +;;; blog.el --- A simple org-mode & elnode blog software. +;;; -*- lexical-binding: t; -*- + +(require 'elnode) +(require 'f) + +(defun render-org-buffer (buffer &optional force) + "Renders an org-mode buffer as HTML and returns the name of the output buffer." + (letrec ((input-buffer (get-buffer buffer)) + (output-buffer (concat buffer "-rendered")) + ;; Don't re-render articles unless forced. + (must-render (or force + (not (get-buffer output-buffer))))) + (if (and input-buffer must-render) + (with-current-buffer input-buffer + (org-export-to-buffer 'html output-buffer nil nil t))) + (if input-buffer output-buffer nil))) + +(defun get-buffer-string (buffer) + "Returns the contents of the specified buffer as a string." + (with-current-buffer (get-buffer buffer) + (buffer-string))) + +(defvar-local article-not-found + '(404 . "<html><body><p>Oh no, the article was not found.</p></body></html>")) + +(defvar-local text-html '("Content-Type" . "text/html")) + +(defun render-article (article) + "Renders an article, if it exists." + (let ((output-buffer (render-org-buffer (concat article ".org")))) + (if output-buffer `(200 . ,(get-buffer-string output-buffer)) + article-not-found))) + +(defun blog-post-handler (httpcon) + "This handler servers a blog post from the configured blog post directory." + (let ((response (render-article (elnode-http-mapping httpcon 1)))) + (elnode-http-start httpcon (car response) text-html) + (elnode-http-return httpcon (cdr response)))) + +(defvar-local elblog-routes + '(("^.*//en/\\(.*\\)" . blog-post-handler))) + +(defun elblog-handler (httpcon) + (elnode-hostpath-dispatcher httpcon elblog-routes)) + +(elnode-start 'elblog-handler + :port 8010 + :host "localhost") |