#+TITLE: Blogging with org mode and nikola #+DATE: 2017-07-01 12:00:00 UTC #+DESCRIPTION: How I use emacs and nikola to write my blog #+FILETAGS: emacs:python #+CATEGORY: emacs #+SLUG: blogging-with-org-mode-and-nikola #+BEGIN_COMMENT .. title: Blogging with org mode and nikola .. slug: blogging-with-org-mode-and-nikola .. date: 2017-07-01 12:00:00 UTC .. tags: emacs, python .. category: emacs .. description: How I use emacs and nikola to write my blog .. type: text #+END_COMMENT Below are some tips and technologies used to write and deploy this blog. ** Getting started To get started creating your blog first install nikola with pip or use the docker container, then run =nikola init= to create your new blog. ** Org header attributes All org files should start with this header containing the blog entry meta data, the below example is from this post. #+BEGIN_EXAMPLE #+BEGIN_COMMENT .. title: Blogging with org mode and nikola .. slug: blogging-with-org-mode-and-nikola .. date: 2017-01-02 12:00:00 UTC .. tags: emacs, python .. category: emacs .. description: How I use emacs and nikola to write my blog .. type: text #+END_COMMENT #+END_EXAMPLE Nikola lets you create your blog entries in various formats like org, markdown, rtf and ascii doc as a few examples, The main advantage is that you don't need a database and can redistribute your files as plain documents, if you use orgmode format in particular this works very well because you can export to various formats like pdf or word documents which works great for sending to people or for making offline or printable copies. Basically you get a lot of power with little effort. ** Updating nikola configuration To use org you will need to adjust =conf.py= the examples below are the relevant parts to find and update with the org extensions. =ORG_REGEX_REPLACE= is only needed if your using my modified plugin. #+BEGIN_EXAMPLE POSTS = ( ("posts/*.rst", "posts", "post.tmpl"), ("posts/*.txt", "posts", "post.tmpl"), ("posts/*.org", "posts", "post.tmpl"), ("posts/*.md", "posts", "post.tmpl"), ) PAGES = ( ("stories/*.rst", "stories", "story.tmpl"), ("stories/*.txt", "stories", "story.tmpl"), ("stories/*.org", "stories", "story.tmpl"), ("stories/*.md", "stories", "story.tmpl"), ) #+END_EXAMPLE #+BEGIN_EXAMPLE COMPILERS = { "rest": ('.rst', '.txt'), "markdown": ('.md', '.mdown', '.markdown'), "textile": ('.textile',), "txt2tags": ('.t2t',), "bbcode": ('.bb',), "wiki": ('.wiki',), "ipynb": ('.ipynb',), "html": ('.html', '.htm'), "orgmode": ('.org',), "php": ('.php',), } #+END_EXAMPLE #+BEGIN_EXAMPLE ORG_REGEX_REPLACE = [(r'src\=\"(../)*', 'src="/')] ORG_PRETTY_URL_ADJUST = True #+END_EXAMPLE ** Hosting your blog I hast my blog on my own server and domain which is an option but you can also deploy your blog to github pages if you don't want the cost and hassle of maintaining your own environment. ** Containers The setup I use below involves using containers to generate deploy an host the container, this means the setup is portable you just need docker available on your machine the rest of the technologies are installed inside the containers. If you want a similar setup you can copy the docker compose and drone files below. To generate your blog you just need to run the following command. #+BEGIN_SRC shell docker-compose up #+END_SRC ** Nikola org file tips *** Hiding posts If you want to deploy but hide your posts from the index's you can tag them with draft. #+BEGIN_EXAMPLE .. tags: emacs, python, draft #+END_EXAMPLE You can also stop your posts from being deploy altogether by putting =DEPLOY_DRAFT = False= in your nikola config. see https://getnikola.com/handbook.html#drafts for more information. *** Inline images Emacs lets you render your images direct in your document which is great for verifying your image paths, however there is an issue with nikola currently which means it changes the depth of your post so the deployed images will not display: You have a couple of options + Manually put in the correct path for nikola and loose the display and verification that the path is correct, you can still run the server locally to verify. + The other option is to use a patched version which I am doing, this means i never actually need to test my pages I can write the post commit and be confident its correct. https://github.com/olymk2/plugins + Bug the dev's they are not planning on fixing this currently but if enough people want it fixed they might, so if you want to get this fixed i suggest you add to the issue below or raise a new issue. https://github.com/getnikola/plugins/issues/188 ** Docker images for rendering your org files You can use the container below to generate your blog, its a simple container with emacs added with org mode which is called to generate the html pages. #+BEGIN_SRC yaml FROM olymk2/emacs RUN apt-get update RUN apt-get install -y locales locales-all python3 python3-pip python3-gdbm RUN dpkg-reconfigure locales ENV LC_ALL C.UTF-8 RUN locale-gen en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LANG C.UTF-8 ENV LANGUAGE en_US:en COPY ./build/requirements.txt /app/requirements.txt RUN pip3 install -r /app/requirements.txt RUN nikola plugin -i orgmode WORKDIR /app ENTRYPOINT nikola clean; nikola build #+END_SRC ** Auto deploy with drone I use drone to deploy my blog you can use other CI services, but using drone keeps it simple as i can use the same containers I host my site with. #+BEGIN_SRC yaml workspace: base: /drone path: src pipeline: publish: pull: True image: appleboy/drone-ssh host: ${SSH_DOMAIN} user: ${SSH_USER} key: ${SSH_KEY} port: 22 command_timeout: 240 script: - cd /var/www/your-site-location/ - git pull - docker-compose build - docker-compose up --remove-orphans - echo 'Finished deploy' #+END_SRC ** Nikola Emacs plugin I have been working on a simple plugin for emacs to give you a magit style menu to nikola from inside nikola if you would like to try this visit the link below. https://github.com/olymk2/emacs-nikola