Octopress Setup with Github, Org Mode, and LiveReload
Note: This is post applies to Emacs 23 with org-mode 7.8.x. See Org-Mode Octopress Setup v2 for the updated version applying to Emacs 24.3 and org-mode 8.2.x
WordPress seemed like a good blogging platform, but it just didn't feel right. I spend all my day editing text files using vim key-bindings, and I love Org Mode for all non-coding writing. If you don't know Org Mode, it's like having Markdown mode on steroids. You can have a numbered list in Markdown, but org-mode lets you re-order the list, and that's just the beginning. Editing blog documents in the WordPress editor felt almost as bad as being told to use MS Word. I found that ergonomics of Org Mode, including all the goodness of recent versions of Emacs, including Evil (Vim emulation), just made organization of creative thoughts so much more enjoyable.
So I bit the bullet one weekend, and dove into Octopress. You're looking at the results of this endeavor, including my first Octopress article, and the latest tips on recreating this sort of blog using Octopress with Org Mode authoring, using LiveReload, and deployed at no charge on github.com.
If you used to writing real web applications, rather than know the intricacies of a giant monolithic blogging platform, then the customization of Octopress seems so much more straightforward. This is so much more like the Unix philosophy that so many of us love, which is small and modular, rather than monolithic.
I like Rob Dodson's summary (noting Org Mode plus Emacs):
Octopress is a blogging framework written by Brandon Mathis (@imathis) which sits on top of Jekyll. Jekyll is a static site generator, meaning there's no database associated with your blog. Instead of writing everything in a WSYWIG linked to MySQL (like Wordpress or Blogger) you produce text files using Markdown which are then converted to static HTML. There are 3 huge benefits to this approach. First, writing in Markdown [org-mode for Justin] is awesome. Once you learn the syntax it's incredibly fast and you don't have to spend time playing with a tiny little editor window just to
addsome style to your posts. Second, writing in your favorite text editor is also awesome. I produce everything in Sublime Text 2 [Emacs for Justin] and every day I discover new tricks to make the process better. If you've ever had to write a blog post using one of those horrible little TinyMCE editors you will appreciate this feature. And lastly, static HTML is fast.
I found it totally neat that I could embed markdown inside the org-mode document. See below for how this is done.
This article should be useful for:
- Any interest in using org-mode to publish to Octopress including some reasons I use Org Mode (with Emacs).
- Some explanation of what Octopress and git are doing.
- How to use LiveReload with Octopress and Org Mode.
- Anybody curious about how using free github pages works to host Octopress.
Basic setup
-
Rob Dodson on Octopress: Start off with these instructions from this posting on April 30th, 2012. There are a few differences worth noting:
- You may wish to change the .rvmrc to a .ruby-version file
- Github recommends your deployment repository be named
yourname.github.io
, notyourname.github.com
. - After you run
rake setup_github_pages
and before runningrake generate
, you should runrake install
. If you forget, there's a clear message indicating this omission.
-
Customize
octopress/_config.yml
. The yaml file contains descriptions. -
Update the DNS to use your custom domain if you wish: Github directions on setting up a custom domain
-
At this point, you can create a post:
rake new_post["my post name"]
Create a page:
rake new_page["my page name"]
Generate and deploy:
rake gen_deploy
Watch the site and regenerate when it changes:
rake watch
Preview the site in a web browser:
rake preview
See all the available rake options:
rake -T
Save changes to source branch:
git add . git commit -m "save changes to source" git push origin source
Some Perspectives on how Octopress Works
Posts
Posts are created using the rake task rake new_post["Post Title"]
.
The key things about a post are:
- File is located in =source/_posts.
- File has a header containing the meta-data for the post. The post
URL and date are determined by the by the
title
anddate
fields. If you want to change the date of your post, then you change the meta-data. Changing the file name is useful only for file navigation. Here's a gist for a rake task to update the file names to match the metadata.
Pages
Pages are created using the rake task rake new_page["Page Title"]
.
The key things about a page are:
- Files are located in
source/page-title
- File has a header containing the meta-data for the post.
POW
POW allows you to point your browser to http://octopress.dev
to see
your local, unpublished Octopress website. It's very convenient to not
have to remember to run a local server, and it works great with
LiveReload. Scroll to the bottom of this link for details on
POW. The alternative to running
POW is to run rake preview
and then point your browser at http://0.0.0.0:4000
(or
whatever port you configured).
LiveReload
LiveReload is a Chrome browser extension that will automatically refresh the browser after you publish your file. This works with or without POW.
-
Install the browser extension for your type of browser.
-
Add these two entries to your
Gemfile
, in the :development group:
gem 'guard'
gem 'guard-livereload'
- Create a file called
Guardfile
containing something like:
guard 'livereload' do
watch(%r{public/generated})
watch(%r{public/.+\.(css|js|html)})
end
- Start 2 shell tabs running these commands:
rake generate && rake watch
andguard
> rake generate && rake watch
This screen shot shows watch
updating the deployment files.
start guard LiveReload
> guard
This screen grab shows guard detecting the browser and telling the browser to update.
It's neat to get LiveReload working with Octopress. However, the generation can finish after your page does a reload, so you won't see your latest changes. I'll update this blog post when I figure out a solution to that one. Until then, you may find it more convenient to manually refresh the blog page yourself.
It's worth noting that if you're running any other instance of guard- LiveReload, then one of these two copies will win and one won't work. If you run a rails server this way, then this can bite you. It took me a bit of time to figure out why guard wasn't working.
Org-Mode
You can skip this section if you're not interested in org-mode. However, it's super cool!
Why org-mode for blog publishing?
Org-mode offers quite a bit more than plain markdown. It's quite the hacker's delight for note taking and authoring of blog articles. Down below I list a few reasons why org-mode. Here's a few org-mode features I love (Some are Emacs ones):
- All headers and list items can be reordered with minimal keystrokes (think super powerful outliner).
- Numbered lists.
- Editable tables in text editor, with movable columns, movable rows.
- Ergonomics of insertion of URLs and images.
- Includes the basics of markdown, such as source code blocks and much more.
Org-mode Integration
I found a plugin that automates the process of converting an org-mode
document (.org
file) in source/org_posts
into a .markdown
document
in source/_posts
. Once the markdown document is saved in
_posts, the rake watch
task picks up the change and deploys the file, and LiveReload can
then automatically update your web browser. Neat!
Here are the basic steps:
-
Follow the instructions here: Introducing Octopress Blogging for Org-Mode
-
At the time of this article, April 27, there's a bug with the latest org-mode. I posted a workaround. By the time you read this, you probably won't need that tip.
-
You can embed Markdown (or other Octopress/Jekyll directives) by embedding inside of a
#+begin_html
and#+end_html
block.
-
Images work fine.Well, almost fine. The big gotcha is that the standard inclusion of images in org-mode results in broken paths at deployment. The workaround is to embed the Octopress syntax for an image, and to place the images under source/images. Note, you'll want to be sure to use an absolute path, or else your article might look OK on the home page, but might now work in the postings directory. If I'm creating a document with many images, I'll group the images for that document in a sub-directory of images named like the document. This is how it should look. The trick is to place the octopressimg
directive within a HTML begin/end block. -
Links: Links for relative pages are simple.
[[file:telecommuting.html][Why telecommuting works and how I maximize productivity]]
Links from a page to a post can use a relative link like this:
[[file:../blog/2013/04/27/octopress-setup-with-github-and-org-mode/index.html][here]]
However, links from posts to other posts require an absolute URL. The big gotcha is blog posts due to the nested URL structure that does not map to the where you're putting your org-posts. To avoid trouble, you need to follow a format as this example shows. It's easiest to copy the URL from the browser address bar.
[[http://www.railsonmaui.com/blog/2013/05/08/strategies-for-rails-logging-and-error-handling/][Strategies for Rails Logging and Error Handling]]
I tried using a
file:../blog
syntax, but that either would work on the home page or in the specific blog article, but not both.http:/blog
links would work in Chrome but not mobile Safari. Markdown to get parsed by Jekyll does not work if the link is within a block level html tag (i.e., a paragraph). Hopefully, one day we'll be able to specify relative links from blog article to blog article. -
Bold styling (text inside of stars) was a bit of mystery using the standard theme. I had to add this line to _typography.scss:
b { font-weight: bold; }
Code styling (text inside of equals)
like this
did not work after a code block unless I added thediv
tag to this line around 100 in_syntax.scss
// Sometimes html gen by org-mode misses p or li tags div, p, li { code { @extend .mono;
Useful Scripts
- Just configure
OCTO_HOME
- Emacs tip: Visit the created file by placing cursor over file name
and then hit
Ctrl-x, f
.
export OCTO_HOME=~/octopress ogen () { cd $OCTO_HOME; rake generate; cd - } osave () { cd $OCTO_HOME; git commit -am "Updates" && git push origin source; cd - } odeploy () { cd $OCTO_HOME; osave; rake gen_deploy; cd - } # this one is for orgmode only opost() { cd $OCTO_HOME output=$(rake new_post["${1}"]) new_file=$(echo $output | awk '{print $4}') base=$(basename $new_file) new_location=$OCTO_HOME/source/org_posts/ mv $OCTO_HOME/$new_file $new_location echo created $new_location/$base cd - } opage() { cd $OCTO_HOME rake new_page["${1}"] cd - }
- Just configure
Deploying to Github: Directory Structure of Octopress and the master and source Git Branches
Github offers free hosting of both the blog deployment and source. You're looking at the deployment right now. You can find the source here at my git repo justin808.github.io. I doubt you could beat the price, performance, and convenience. You can look inside of this repo, clone it, etc. and you have everything that it took to make this blog.
I originally was quite confused by the concept of using two separate git branches to make up what gets deployed on the live website versus the git repository of my articles. Plus, there's the issue of Octopress git repository that you clone when starting out. Eventually, I figured out that the two branches simply contain different files, with one containing the original Octopress files. Here's a few screen grabs that might clarify the situation for you.
Don't forget that you never push to the master branch, but rather the
rake deploy
task does it for you. Instead, you run git push origin source
to push the content of your blog to github.
The octopress/public
directory corresponds to what you'll find on the
github site for your deployment (master branch).
The octopress/.gitignore file contains entries like public
, which
essentially keeps the rake generate
files out of the source branch.
Here's the github master branch right after creation. Note the
correspondence with public
. This is what gets deployed as your blog.
Here's the github source branch. This contains the octopress environment, as well as your customizations and blog posts.
Useful Links
- Getting Started with Octopress: Nice overall tutorial. Very current! March 2013.
- Rob Dodson on Octopress: Most of the instructions I show below are from this posting on April 30th, 2012.
- Joel McCracken on Octopress: Use Jekyll? You Really Should Be Using Octopress
- Github directions on setting up a custom domain
- dblock.org Article on Octopress: A good explanation from Jan 17, 2012, especially on the difference of the source and master branches.
- Introducing Octopress Blogging for Org-Mode: For org-mode. See below.
- 18 Months of Octopress: Nice article on why Octopress was worth the switch.
- Shell Aliases for Octopress: Save time with these shortcuts
Parting words…
Thanks in advance for any suggestions on this article. I hope you find it helpful. Check me out on Twitter: @RailsOnMaui.