Octopress Setup with Github, Org Mode, and LiveReload

otherApril 27, 2013Dotby Justin Gordon

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 add some 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:

  1. Any interest in using org-mode to publish to Octopress including some reasons I use Org Mode (with Emacs).
  2. Some explanation of what Octopress and git are doing.
  3. How to use LiveReload with Octopress and Org Mode.
  4. Anybody curious about how using free github pages works to host Octopress.

Basic setup

  1. Rob Dodson on Octopress: Start off with these instructions from this posting on April 30th, 2012. There are a few differences worth noting:

    1. You may wish to change the .rvmrc to a .ruby-version file
    2. Github recommends your deployment repository be named yourname.github.io, not yourname.github.com.
    3. After you run rake setup_github_pages and before running rake generate, you should run rake install. If you forget, there's a clear message indicating this omission.
  2. Customize octopress/_config.yml. The yaml file contains descriptions.

  3. Update the DNS to use your custom domain if you wish: Github directions on setting up a custom domain

  4. 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:

  1. File is located in =source/_posts.
  2. File has a header containing the meta-data for the post. The post URL and date are determined by the by the title and date 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:

  1. Files are located in source/page-title
  2. 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.

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 and guard
> rake generate && rake watch

This screen shot shows watch updating the deployment files.

image1

start guard LiveReload

> guard

This screen grab shows guard detecting the browser and telling the browser to update.

image2

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):

  1. All headers and list items can be reordered with minimal keystrokes (think super powerful outliner).
  2. Numbered lists.
  3. Editable tables in text editor, with movable columns, movable rows.
  4. Ergonomics of insertion of URLs and images.
  5. 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:

  1. Follow the instructions here: Introducing Octopress Blogging for Org-Mode

  2. 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.

  3. You can embed Markdown (or other Octopress/Jekyll directives) by embedding inside of a #+begin_html and #+end_html block.

    image3
  1. 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 octopress img directive within a HTML begin/end block.

    image8
  2. 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.

  3. 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 the div 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 -
    }
    

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).

image5

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.

image6

Here's the github source branch. This contains the octopress environment, as well as your customizations and blog posts.

image7

Useful Links

  1. Getting Started with Octopress: Nice overall tutorial. Very current! March 2013.
  2. Rob Dodson on Octopress: Most of the instructions I show below are from this posting on April 30th, 2012.
  3. Joel McCracken on Octopress: Use Jekyll? You Really Should Be Using Octopress
  4. Github directions on setting up a custom domain
  5. dblock.org Article on Octopress: A good explanation from Jan 17, 2012, especially on the difference of the source and master branches.
  6. Introducing Octopress Blogging for Org-Mode: For org-mode. See below.
  7. 18 Months of Octopress: Nice article on why Octopress was worth the switch.
  8. 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.

Closing Remark

Could your team use some help with topics like this and others covered by ShakaCode's blog and open source? We specialize in optimizing Rails applications, especially those with advanced JavaScript frontends, like React. We can also help you optimize your CI processes with lower costs and faster, more reliable tests. Scraping web data and lowering infrastructure costs are two other areas of specialization. Feel free to reach out to ShakaCode's CEO, Justin Gordon, at [email protected] or schedule an appointment to discuss how ShakaCode can help your project!
Are you looking for a software development partner who can
develop modern, high-performance web apps and sites?
See what we've doneArrow right