Github Pages for Fun and Win

sinatra-gen

Stop what you’re doing and make your project a github page. For the love of god, your project has no documentation. RDoc is cool, READMEs are decent, but descriptive websites with examples? Oh, they RULE.

At first, I was skeptical. Pages looked cool, but it seemed like a lot of effort to create a page especially one for each project. Then two things happened:

  1. Tom yelled at me/us
  2. I discovered the power of jekyll

The main problem that jekyll solves for github pages is the ability to have a general ‘layout’ that eliminates the HTML copy and paste you would have to do if you were managing pages for more then one project. Having a unified layout also allows you’re project pages to have a unified brand and feel – something I believe is important.

There other things that are truly great about using jekyll.

Easy code highlighting.

Highlighting a block of code is as easy as:

{% highlight ruby %}
def awesome
  "for real. I know."
end
{% endhighlight %}

Then all you have to do is grab a syntax stylesheet. You can grab mine here

Ability to write pages in textile or markdown.

I’ve been doing all my blogging in textile for a long time now, and being able to write an easy to read page that I can easily find and edit text in makes it more likely that I’ll continue to update the pages with new releases.

Ability to pass variables from individual pages into your layout to make your layout even more reusable.

This is underused, but because jekyll interprets the layout file after its read the variables from the top of your document it means you can stick variables in your YAML head that the layout can use.

For example: In my github project pages, the YAML head looks something like:

---
layout: quirkey_code
title: sinatra-gen
github_name: sinatra-gen
current_version: 0.3.0
nav:
  - name: What
    link: "#what"
  - name: Why
    link: "#why"
  - name: Usage
    link: "#usage"
  - name: Options
    link: "#options"
  - name: Dependencies
    link: "#dependencies"
---

Beyond passing the page title, I’m also passing a ton of other variables. The github_name is used to link to the downloads of the project on github – a reusable piece of code that exists at the foot of every page. In the layout it looks like:

<h3 id="installing">Installing</h3>
        <div class="highlight"><pre>sudo gem install {{ page.github_name }}
        </pre></div>
        <p>Or directly from github:</p>
        <div class="highlight"><pre>sudo gem install quirkey-{{ page.github_name }} -s http://gems.github.com
        </pre></div>
        <p>Github in thier infinite awesomeness also lets you download the source in multiple formats.</p>
        <div class="download">
          <a href="http://github.com/quirkey/{{ page.github_name }}/zipball/master">
            <img border="0" width="90" src="http://github.com/images/modules/download/zip.png" />
          </a>
          <a href="http://github.com/quirkey/{{ page.github_name }}/tarball/master">
            <img border="0" width="90" src="http://github.com/images/modules/download/tar.png" />
          </a>
        </div>

current_version and nav work the same way. nav uses a little more liquid magic to get the job done:

{% if page.nav %}
<ul id="pagenav">
  {% for nav in page.nav %}
  <li><a href="{{ nav['link'] }}">{{ nav['name'] }}</a></li>
  {% endfor %}
  <li><a href="#installing">Installing</a></li>
  <li><a href="#requests">Bugs/Feature<br />Requests</a></li>
  <li><a href="#contact">Contact</a></li>
</ul>
{% endif %}

This way I can have a super flexible nav menu, changing what I need and what I don’t in the page instead of in the layout. You can see the full code for the sinatra-gen page or the full quirkey_code layout.

Submodules for the ultimate stoke factor.

After building a couple of these project pages, I thought “Hey! I can just put my layout in its own repo and when I start a new project page, I can just submodule it!”. Great idea, unfortunately at the time, github didn’t support it. However,after nagging PJ a bit now they do!

My workflow, is I’ve set up a jekyll_layouts repository and when I first create my gh-pages branch (described in detail here), I just run:

git submodule add git://github.com/quirkey/jekyll_layouts.git _layouts

Then, the next time I push, github graciously pulls my submodule before building my page with jekyll. Sweet. Some things to note:

  • You have to have a public repository for the layouts and you have to submodule with a globally accessible URL (as in the ‘public’ clone url instead of ‘your’ clone URL).
  • When you switch back to your master branch, the _layouts directory wont disappear automatically. You can add it to your .gitignore OR just delete it and it will reappear when you switch back to gh-pages.

Using the power of git, there is also a way to continue editing your submodule’d layouts while in a pages branch. The trick is that while you use the public clone URL for the ‘origin’ server of the submodule, you can add your private URL as another remote for the cloned repository.

For example: If I’m in my sinatra-gen repository at the gh-pages branch, I can cd into the _layouts submodule:

[10:47 AM:sinatra-gen(gh-pages)] $ cd _layouts
[11:23 AM:_layouts(master)] $ 

If I inspect the branches I see:

[11:23 AM:_layouts(master)] $ git branch -a
* master
  origin/HEAD
  origin/master

From here I can add another remote, which is actually the same repository – just the private clone URL.

[11:24 AM:_layouts(master)] $ git remote add upstream git@github.com:quirkey/jekyll_layouts.git
[11:26 AM:_layouts(master)] $ git fetch upstream
From git@github.com:quirkey/jekyll_layouts
 * [new branch]      master     -> upstream/master
[11:26 AM:_layouts(master)] $ git branch -a
* master
  origin/HEAD
  origin/master
  upstream/master

Now If I make a change in the _layouts directory, its as easy as:

[11:28 AM:_layouts(master)] $ git commit -am "Moved around title" 
Created commit 5726d5e: Moved around title
 1 files changed, 1 insertions(+), 1 deletions(-)
[11:28 AM:_layouts(master)] $ git push upstream master
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 314 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To git@github.com:quirkey/jekyll_layouts.git
   5013157..5726d5e  master -> master

All of my pages code is under the MIT license so feel free to use and manipulate. If your nice and or grateful, you can link back to this site in your footer.

7 Responses to “Github Pages for Fun and Win”

gabriel Says: #

Thanks for explaining the submodules. I was thinking of writing a post much like this about my github pages tasks: http://github.com/cldwalker/thor-tasks/blob/master/gh_pages.thor/main.thor

AQ Says: #

gabriel –
neat tasks!

This post inspired me to write my next tutorial as a github page using jekyll since I was gonna post the source on github anyway.

The syntax highlighting worked fine on github: http://ultrasaurus.github.com/example_nestedmodels/ but locally it doesn’t show up: http://img.skitch.com/20090503-xdytu5wrfwmbn7359m7itg24mk.jpg

The (very simple) site is here: http://github.com/ultrasaurus/example_nestedmodels/tree/gh-pages

I’m probably missing something basic. I understand if you are too busy, but if you have some spare time to take a peek I’d appreciate some pointers.

Thanks,
Sarah

Never mind. I just figured it out. When running locally I need to:
jekyll –server –pygments

AQ Says: #

Sarah

Glad you figured it out. I actually skip the server part and instead do:
jekyll –auto –pygments

Randy J. Ray Says: #

This is a great guide for the Jekyll side of things, thanks!

I actually whipped together a basic bash script a while back, to automake creating a gh-pages branch. It was only a few days ago that it occurred to me to make it a gist on github (D’oh!): http://gist.github.com/105977

AQ Says: #

Thanks Randy! That script is awesome and useful.

About

QuirkeyBlog is Aaron Quint's perspective on the ongoing adventure of Code, Life, Work and the Web.

twitter/@aq.

instagram/@quirkey.

github/quirkey.

QuirkeyBlog is proudly powered by WordPress

Categories