bastibe / org-static-blog

A static site generator using org-mode
BSD 3-Clause "New" or "Revised" License
341 stars 74 forks source link

+TITLE: ORG-STATIC-BLOG

[[http://melpa.org/packages/org-static-blog-badge.svg]] [[http://stable.melpa.org/packages/org-static-blog-badge.svg]]

Static blog generators are a dime a dozen. This is one more, which focuses on being simple. All files are simple org-mode files in a directory. The only requirement is that every org file must have a =#+TITLE= and a =#+DATE=, and optionally, =#+FILETAGS=, =#+DESCRIPTION= and =#+IMAGE=.

=#+FILETAGS= set the tags for the post, which can be delimited by colons in the form of =#+FILETAGS: :foo bar:baz:=, or by whitespaces in the form of =#+FILETAGS: foo bar=. And you can put a short summary in =#+DESCRIPTION=, which will be converted to a HTML ~~ tag, it's good for SEO as described in Wikipedia's [[https://en.wikipedia.org/wiki/Meta_element#The_description_attribute][Meta element]].

If =org-static-blog-enable-og-tags= is set to =t=, =#+DESCRIPTION= and =#+IMAGE= (it must be e a relative url) will generate the =og:description= and =og:image= meta properties that will be used in URL previews generated in social networks and similar sites (see [[https://ogp.me/][Open Graph Protocol]]).

This file is also available from marmalade and melpa-stable.

Set up your blog by customizing org-static-blog's parameters, then call =M-x org-static-blog-publish= to render the whole blog or =M-x org-static-blog-publish-file filename.org= to render only only the file =filename.org=.

Above all, I tried to make org-static-blog as simple as possible. There are no magic tricks, and all of the source code is meant to be easy to read, understand and modify.

For org-static-blog, a blog consists of six parts:

Every HTML page in org-static-blog can be customized in the following ways:

You can customize the RSS feed output by setting =org-static-blog-rss-extra=. Its content is placed right before the sequence of posts. For example you can add an RSS icon for the feed, or advertise that you built your blog with org-static-blog. You can also limit the number of entries in the feed via =org-static-blog-rss-max-entries=.

There are some static texts like "/Other posts/", "/Tags/" etc that org-static-blog includes in produced html. By default org-static-blog uses english texts, but language chosen depends on value set to =org-static-blog-langcode=. If your language is not supported yet, you will see placeholders like =[other-posts:de]= and =[tags:de]=. You can add new language by adding texts to =org-static-blog-texts= list. And if you do, please share and create Pull Request.

If you want to activate a few convenience key bindings, add =(add-to-list 'auto-mode-alist (cons (concat org-static-blog-posts-directory ".*\.org\'") 'org-static-blog-mode))= to your /init.el/. These key bindings are:

If you have questions, if you find bugs, or if you would like to contribute something to org-static-blog, please open an issue or pull request on GitHub.

Finally, I would like to remind you that I am developing this project for free, and in my spare time. While I try to be as accommodating as possible, I can not guarantee a timely response to issues. Publishing Open Source Software on GitHub does not imply an obligation to /fix your problem right now/. Please be civil.

** Minimal Configuration This minimal configuration should be added to your /init.el/, and will set up a minimal org-static-blog for the URL https://staticblog.org, which will be saved in the directory ~/projects/blog/.

+begin_src elisp

 (setq org-static-blog-publish-title "My Static Org Blog")
 (setq org-static-blog-publish-url "https://staticblog.org/")
 (setq org-static-blog-publish-directory "~/projects/blog/")
 (setq org-static-blog-posts-directory "~/projects/blog/posts/")
 (setq org-static-blog-drafts-directory "~/projects/blog/drafts/")
 (setq org-static-blog-enable-tags t)
 (setq org-export-with-toc nil)
 (setq org-export-with-section-numbers nil)

 ;; This header is inserted into the <head> section of every page:
 ;;   (you will need to create the style sheet at
 ;;    ~/projects/blog/static/style.css
 ;;    and the favicon at
 ;;    ~/projects/blog/static/favicon.ico)
 (setq org-static-blog-page-header
       "<meta name=\"author\" content=\"John Dow\">
 <meta name=\"referrer\" content=\"no-referrer\">
 <meta name=\"viewport\" content=\"initial-scale=1,width=device-width,minimum-scale=1\">
 <link href= \"static/style.css\" rel=\"stylesheet\" type=\"text/css\" />
 <link rel=\"icon\" href=\"static/favicon.ico\">")

 ;; This preamble is inserted at the beginning of the <body> of every page:
 ;;   This particular HTML creates a <div> with a simple linked headline
 (setq org-static-blog-page-preamble
       "<div class=\"header\">
   <a href=\"https://staticblog.org\">My Static Org Blog</a>
 </div>")

 ;; This postamble is inserted at the end of the <body> of every page:
 ;;   This particular HTML creates a <div> with a link to the archive page
 ;;   and a licensing stub.
 (setq org-static-blog-page-postamble
       "<div id=\"archive\">
   <a href=\"https://staticblog.org/archive.html\">Other posts</a>
 </div>
 <center><a rel=\"license\" href=\"https://creativecommons.org/licenses/by-sa/3.0/\"><img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-sa/3.0/88x31.png\" /></a><br /><span xmlns:dct=\"https://purl.org/dc/terms/\" href=\"https://purl.org/dc/dcmitype/Text\" property=\"dct:title\" rel=\"dct:type\">bastibe.de</span> by <a xmlns:cc=\"https://creativecommons.org/ns#\" href=\"https://bastibe.de\" property=\"cc:attributionName\" rel=\"cc:attributionURL\">Bastian Bechtold</a> is licensed under a <a rel=\"license\" href=\"https://creativecommons.org/licenses/by-sa/3.0/\">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</center>")

 ;; This HTML code is inserted into the index page between the preamble and
 ;;   the blog posts
 (setq org-static-blog-index-front-matter
       "<h1> Welcome to my blog </h1>\n")

+end_src

In order for this to work, you will also need to create a style sheet at /~/projects/blog/static/style.css/, which might for example change the appearance of the ~#preamble~, the ~#content~, and the ~#postamble~.

To write posts, you can now call ~org-static-blog-create-new-post~, and render your blog with ~org-static-blog-publish~.

Each post is an org-mode file such as

+begin_src org-mode

+title: How to Write a Blog Post

+date: <2020-07-03 08:57>

+filetags: computers emacs blog

Step one: Install ~org-static-blog~. \ Step Two: Execute ~M-x org-static-blog-create-new-post~ and write the content. \ Step Three: Execute ~M-x org-static-blog-publish~ and upload to your webhost. \ Done.

+end_src

You can find more complete examples by looking at my [[https://github.com/bastibe/.emacs.d/blob/master/init.el#L670][init.el]] and the [[https://github.com/bastibe/bastibe.github.com][repository]] for my blog ([[http://bastibe.de/][bastibe.de]]) itself to see an example of how to use =org-static-blog= in practice.

*** Other org-static-blog blogs:

** Features *** Hide some subtrees when publishing

*** Extended cleaning of the suggested filename

If you regularly find yourself editing the suggested filename when creating new posts, e.g. replacing slashes (/), then you can modify the value of org-static-blog-suggested-filename-cleaning-regexp. With its default value, "\s", it only replaces whitespace.

For example, a post with the title "Using bastibe/org-static-blog for your blog" would, with the default result in a suggested filename of 2023-10-02-using-bastibe/org-static-blog-for-your-blog.org. If the value of org-static-blog-suggested-filename-cleaning-regexp is changed like this

(setq org-static-blog-suggested-filename-cleaning-regexp (rx (or "/" (in white)))

the / will be replaced too and the suggested filename will be 2023-10-02-using-bastibe-org-static-blog-for-your-blog.org.

Copyright 2015, Bastian Bechtold

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.