Advertisement

Getting Started with Octopress

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

Octopress is a static blogging framework built on top of Jekyll. It uses scripts to build static files to be deployed to a server.

octopress-header

Don't Worry…

…we'll explain everything right here. However, if you've never touched the command line, you might want a little primer first. Check out this guide, which explains some basic commands and functions.


Okay, so it's Static

Browsers read HTML, CSS, and JavaScript natively. Every other language is used to generate these three types of files. Static sites are created from hard-coded static files that do not rely on any server processes (unlike PHP or any other server-side-generated sites). Jekyll, the underlying framework, instead relies on the content editor's local environment to generate the static files that will eventually be deployed.

Wait… What?

Say, for example, you have five blog posts in your Wordpress blog. When you visit http://yoursite.com, excerpts from these five posts show up on your home page. You click on a link to take you to the full post page. Each of these pages is served to your browser as HTML, styled by CSS; you may or may not have JavaScript that helps define some interactive behaviors.

The pages on your Wordpress-powered blog are built on the fly; database queries are run to get the different pieces, such as the title, content, or permalink. These are then returned and processed by PHP for each request (assuming you don't have a caching plugin installed).

With Jekyll, things are different.

How are They Different?

Glad you asked. Jekyll does all of this on your computer, before the files go up to the server. It reads some local configurations and templates, then builds all of that HTML, CSS, and JavaScript right on your local machine, so your server doesn't have to. This makes your server administration much easier, safer and faster.

So, Why isn't Everyone Using it?

There are a few answers to that question. Here are three:

  1. It doesn't solve every problem. Sometimes, you need database-driven, ever-changing content.
  2. Not everyone understands how to deploy this kind of site. Generally speaking, static sites are for developers. The average user doesn't have enough know-how to build and deploy this kind of thing.
  3. It is misunderstood. A lot of people don't understand the benefits and power of a statically generated site.

So which problems doesn't this approach solve? Well, for one, if your site is dependent on user-created data, statically generated sites, overall, won't give much space for that. Of course, if you are only relying on a database for comments, you can easily offload that to something like Disqus. If you are relying on live data that can't be pulled on the front-end via JavaScript, then static sites probably aren't suited for your requirements.

When Does it Work Best?

The best case scenario: blogs or content-centric sites that web developers maintain. You might have caught that with the Octopress tagline, "A blogging framework for hackers."

webuild.envato.com

webuild.envato.com - built with Octopress, maintained by the Envato dev team

Because you will be doing some mild work in the terminal, Octopress and Jekyll are generally not suited for a non-tech-oriented content creator. However, if you are willing to spend enough time to read this post, you will be well suited for an Octopress-powered site.


The Real Secret of the Web

Understanding that what all of your users see is HTML, CSS and JavaScript is the real secret of the web. Therefore, testing your Octopress site locally requires no Apache, PHP or MySQL server installations. All you need is a browser which can run local files.

Tricky Part Numer 1: Ruby

Every good thing comes with a price; you must have Ruby version 1.9.3, plus the Jekyll and Bundler Ruby Gems installed, as well as Git. (While Git isn't necessarily required, it might as well be.) Once these pieces are installed, you are ready to jump into development. To install Git, go here.

The instructions that follow are for Mac; similar commands can be found for Windows through a Ruby version manager for windows called pik.

First, check to see what version of Ruby you have installed on your computer by running ruby -v. If the version is not 1.9.3, continue with these instructions. You can skip to "Tricky Part Numer 2: Gems" if you already have 1.9.3.

Installing Ruby version 1.9.3 is relatively easily accomplished using RVM. RVM, or Ruby Version Manager, allows you to install multiple versions of Ruby on your system without having to delete previous versions. The quick install instructions for RVM and Ruby 1.9.3 are as follows:

\curl -L https://get.rvm.io | bash -s stable --ruby=1.9.3

Note: if you have issues related to gcc (or the "gnu compiler collection", which is needed to build Ruby from its source), it may help to run the following commands instead.

\curl -L https://get.rvm.io | bash -s stable
CFLAGS="-Wno-error=shorten-64-to-32" rvm install ruby-1.9.3-p392

Alternatively, installing XCode should help resolve many issues for Mac users related to GCC. Check out this thread on GitHub for some more information about the subject.

To make sure Ruby 1.9.3 has successfully been installed, run rvm list. Once this process is completed, you can run the following to set your system default version of ruby to 1.9.3:

rvm --default use 1.9.3

To check and make sure 1.9.3 has been selected, again you can run ruby -v. This will print out the current Ruby version.

Tricky Part Numer 2: Gems

RubyGems is a code package manager for the Ruby programming language, and one of the primary reasons Ruby's community has gained a reputation of being helpful and unified. It allows users to easily install open-source code packages directly from the command line. These gems are stored at official repository locations.

To install the Ruby gems, run the following commands from the command line. (If you have not yet installed RubyGems, do so by following the instructions here before running these commands. You can check to see if you have RubyGems installed by running which gem from the command line, which will search for the gem executable program that is used to install gems.)

gem install jekyll
gem install bundler

This will pull down the Jekyll and Bundler gems, and store them in a location on your computer that Ruby automatically uses as its library of sorts, called a "gemset". Jekyll is the powerful static site generator behind Octopress; Bundler is a gem installation specification format that makes gem dependencies easier to satisfy. In other words, it lets you list out the gems you need in a simple file called the Gemfile, and run bundle install in the same directory to get all of the gems listed (instead of installing them by hand one at a time).


Let's Roll!

First, you'll want to pull down Octopress into a directory you'll keep your site in. Unlike most database-driven sites, your live site will generally mirror your local site, in content and in presentation. We will copy the remote git repository to a folder named "mysite" inside the Sites directory. (This is a good default, particularly for Mac users.)

cd ~/Sites
git clone git://github.com/imathis/octopress.git mysite

After this is done, you will want to change into the directory and install the bundle.

cd mysite
bundle install

This will install a collection of gems, if you do not currently have them installed on your machine.

octopress-mysite

Your directory contents should look like this, at this point..

Next, you will want to install the default Octopress theme.

rake install
octopress-mysite-theme

Your directory contents, plus the theme files

Worth knowing: Rake is a Ruby script runner. It reads from a "Rakefile", which contains instructions for the rake command.


Setting up Your Configs

The Octopress site has a thorough overview of the blog configurations, which are found in _config.yml. Check it out here. Here's an example:

url:                http://myblog.com
title:              My Super Blog
subtitle:           A blog that is super
author:             Jonathan Cutrell
simple_search:      http://google.com/search
description:        A site dedicated to explaining how Octopress works.
date_format:        "ordinal"
subscribe_rss:      /atom.xml # this is the default
# subscribe_email:    --- we don't have one for now.
category_feeds:     # Enable per category RSS feeds (defaults to false in 2.1)
email:              # Email address for the RSS feed if you want it.

There are also a number of plugins available, and a bunch more configurations for Jekyll that are optional; we aren't going to cover everything, as we're just trying to get off the ground and running.


Third-Party Settings

The third-party settings are available to be filled out in the _config.yml file; these are evaluated at the time the site is compiled and allow for easy integration with external services. For instance, here is a simple GitHub integration:

# Github repositories
github_user: jcutrell
github_repo_count: 14
github_show_profile_link: true
github_skip_forks: true

Note: all of this is already added into the _config.yml file; simply fill it out to take advantage of built in features.


Okay, I'm Ready to Write!

Good! You can get started very quickly writing a post. The syntax for creating a post (per the docs) is simple:

rake new_post["Some Awesome Title"]

Note: if you are using ZSH, you will need to check this fix out on GitHub, and add an alias to your zshrc file.

octopress_mysite-post

mysite/source/_posts/2013-03-27-some-awesome-title.markdown

This creates a file for your post in your source/_posts directory. By default, the post will be created as a markdown file. The name of the post will define the url (this is a good thing for SEO, by the way). If you navigate to the newly-created file, you'll see some default YAML front-matter. Here, you can add one or more categories. For example:

---
layout: post
title: "Some Awesome Title"
date: 2013-03-21 00:11
comments: true
categories: [Awesome, Amazing, Beautiful, Cool]
---

You can then add your content below the front matter.


See it Come Alive!

To see your new blog post, first run rake preview, then point your browser to localhost:4000. This will show your post on the index page!

octopress-mysite-localhost

Click around the interface to get a feel for the interface and its features. Note: the default theme is responsive! In very little time, you've gotten a static blog running.

Make a Page

To make a page (rather than a post), run something like the following.

rake new_page[about]
octopress-mysite-about

mysite/source/about/index.markdown

This creates a page at source/about/index.markdown. You can also run:

rake new_page[about/index.html]

Which will choose the .html filetype instead of markdown. Inside this page, you can make edits in the same manner as posts.

Make an External Link

When you create a post, you can link it directly to an external page, similar to the page links to Wordpress plugin (but much less complicated)! Simply set front matter yaml to include the following:

external-url: http://yourexternallink.com

Okay, it's Working - but how Does all This Wizardry Work, Exactly?

Another great question. You're on a roll.

As we said before, everything that a browser reads is HTML, CSS, and JavaScript (given you aren't using Flash or some other external technology). When relying on a server-oriented implementation, the HTML, CSS, and JavaScript can change at the moment the user loads the page; the request to the server runs some code to create the HTML on the fly based on whatever the code returns.

For instance, with a site like Wordpress, the links to pages and posts point to web layouts that pull the proper information from the MySQL database at the moment the user accesses the site.

Octopress (and more specifically, Jekyll) go through a very similar process, but instead of doing it on request, they do it only once, on your local computer.

Here's how it works. There are three basic parts to a Jekyll site: the configuration, the layouts/includes, and the posts/pages. If you are coming from the Wordpress world, these can be mapped to the options, the theme files, and the database, respectively (with some blurred lines here and there).

octopress-basic-conf

When Jekyll runs through the process of generating the site, it starts at the index file, and builds all linked pages defined by the layouts. Throughout the buildout, Jekyll uses configurations defined by the _config.yml file, as well as the YAML front-matter in posts, pages, and layouts. Jekyll uses the static post and page files as a collection of enumerable objects, and fills content into all associated layouts.

The final result is a maintainable, DRY set of source files in the source directory and uniform generated static content in the public directory.

The Not-so-dry Public Folder

The public folder will be filled with every page of the site. This means that any time you see any page, whether it's a paginated list of posts, a 404, or an about page, it is actually a single HTML page that you can directly view in the public folder.

octopress-mysite-public

A quick look through the public folder will show you quite a few things. First, the directory structure is easily navigable, as a default Apache-powered static server would serve at a url that is equivalent to the directory structure. The second observation is that any given two HTML files largely have very similar content; this is a result of the duplicated header, footer, and sidebar content pulled from layouts and includes, which is completely acceptable. The reason it is completely acceptable is simple: the content in the public directory is not managed directly by you, but rather through programmatic actions, and therefore DRY doesn't apply, as this doesn't affect the maintainability or performance of the site even marginally.


Customizing the Layouts and Design

As a designer, this will be the part you've been waiting for.

Layout Customization

Octopress is certainly built with the blogger in mind; with some very direct information on how you should change the theme, they have explained how to use the files found in the source/custom in this guide. The long and short of it: Octopress is made to suit blog posts and pages, and custom content for the sidebar and footer. However, you can easily extend the sidebar. The supported pattern is to create a new html file inside source/custom/asides/ with content that follows this format:

<section>
    <h1>Some kind of title</h1>
    <div class="aside-widget-content">Foo, bar</div>
</section>

You can also easily change the header and footer in source/custom. This makes it easy to add in more JS/CSS files, change or remove the default Google fonts, etcetera.

Design

Octopress is built with SCSS. The design can be modified/overridden using the sass/custom/_styles.scss file. This file is included last. To really understand how to style Octopress, though, we must first dive into the core templates.

Note: Do not change the core templates unless you are completely sure of what you are doing, or you are ready to break something. These are the files that define the final build of your static site!


Digging into the Core

Octopress comes with the ability to easily switch themes; effectively copies of the source directory. In the .themes directory, we see the "classic" theme, which was installed when we ran rake install. The source files for the theme are copied into the top level directory and used to build the static site.

Inside the source folder, we can see a few obvious theme folders.

octopress-mysite-source

The files inside the folder _layouts defines the common layouts of posts, pages, category indexes, and the "default", which is a fallback template to catch anything that isn't one of the first three. The folder _partials allows for only partial pieces of files, like the navigation or just the article, to be included on their own. These files are liquid-based HTML templates, which allow for data to be passed in. This data comes from the YAML front-matter set in various places across the site. For instance, consider the liquid tag from _partials/article.html below.

{% if site.disqus_short_name and page.comments != false and post.comments != false and site.disqus_show_comment_count == true %}
 | <a href="{% if index %}{{ root_url }}{{ post.url }}{% endif %}#disqus_thread">Comments</a>
{% endif %}

This tag says the following:

If the user has set the disqus short name in the main site config, and comments are enabled for this page or post, and the site is configured to show the disqus comment count, then echo out the link on the next line. The link will point to the root_url plus the post.url if we are on the index page; otherwise, it will point directly to #disqus_thread, a div that holds the comments.

Understanding this, we can understand how to find and restyle or refactor certain pieces of the site. For instance, if we wanted to add a class to posts that are direct external links, we could do something like this.

{% if page.external-link or post.external-link %}
      <div class="entry-content has-link">{{ content | excerpt }}</div>
    {% else %}
      <div class="entry-content">{{ content | excerpt }}</div>
{% endif %}

This simply checks to see if page.external-link or post.external-link exist. If they do, we add an extra div to the div.entry-content element. There's a lot you can take advantage of with simple YAML front-matter configuration. Be sure to experiment and come up with new solutions to new problems!


Learn More, do More!

There's so much more power in Octopress! Check out the fully detailed documentation and don't miss this extensive list of third-party Octopress plugins; with nearly sixty plugins, integrating with third party services can solve many common implementation requests and problems.

Comment below with ideas for what other features you'd like covered, as well! And remember, the best way to learn is to get your hands dirty. Get into the docs and the code; break things, then fix them. Learn as you go!

Ask it Here

Having issues understanding? Needing more guidance, or looking for someone to look at your code and point to where everything went wrong? Tuts+ is a great place to be! We've all been there, so don't be shy. Put your issues in the comments! If you're feeling generous and you see someone having a problem in the comment thread, feel free to help them out!

Useful Resources

Advertisement