the candler blog

Make a Linked List With Octopress

Blogging

Here’s a Twitter exchange that I woke up to this morning:

Fair warning: this is going to be one of those “how to code” type posts. I’ll return to the regularly scheduled film-related nonsense shortly.

Okay, so, “Daring Fireball-style Linked List posts,” for the uninitiated, refers to the publishing style of John Gruber’s Daring Fireball. For the most thorough explanation of how this works, see Shawn Blanc’s excellent 2009 article, “The Link Post,” in which he calls this kind of link “The Out and About”:

What especially sets The Out and About apart is its feed format. Because not only do the Link Post titles point directly to the linked-to content, but so do those in the RSS feed.

That’s basically how I implement link posts here on the candler blog. Regular posts feature unadorned headlines while link posts are denoted by an additional glyph at the end of the headline. I use the double arrow, ⇒ (⇒ in HTML).1 The headlines of all link posts go to another site, both in your web browser and in your RSS application. They also feature a permalink at the bottom of the post so you can always find a way to get back to my site, which usually features commentary of some lasting value (I hope).

But how is it done in Octopress? It’s actually very simple. I got a great deal of help, when I was first setting up the site, from Connor Montgomery, who posted his own link post tutorial a few weeks ago. I have since refined the code on my site beyond what we worked out together.

The first thing to know is that Octopress will read anything you put into the YAML front matter of a post.2 Just add a new line with a colon and then that content is readable by the rest of your theme. Here’s my YAML front matter on a link post:

Sample YAML Front Matter
1
2
3
4
5
6
7
8
9
---
layout: post
title: "Extremely Smart and Incredibly Handsome"
date: 2012-01-30 05:00
comments: true
categories:
- Nerdfest
external-url: http://www.somewhereelse.com/whatever
---

Notice the last line that says external-url. Now throughout the theme I can use post.external-url to let Octopress know what to do with any post that has that line in it. If you called that line foo then you would simply place post.foo throughout your theme.

Now we need to dig into the theme to make use of that fancy new external URL line. First up is /source/_includes/article.html. This is the file that determines what your posts look like. Let’s change the header so that it links out to the external-url we just set and add a glyph to the end of it.

Top of article.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<header>
{% if index %}
	{% if post.external-url %}<!-- This defines how Octopress will use posts with external-url. -->
		<h1 class="entry-title"><a href="{{ post.external-url }}">{% if site.titlecase %}{{ post.title | titlecase }} YOUR GLYPH HERE{% else %}{{ post.title }}{% endif %}</a></h1>
	 	{% else %}<!-- Now we're back to normal posts. Note the links used under href in both headers.-->
	 	<h1 class="entry-title"><a href="{{ root_url }}{{ post.url }}">{% if site.titlecase %}{{ post.title | titlecase }}{% else %}{{ post.title }}{% endif %}</a></h1>
		{% endif %}
  	{% else %}
	{% if page.external-url %}
    <h1 class="entry-title"><a href="{{ page.external-url }}">{% if site.titlecase %}{{ page.title | titlecase }} YOUR GLYPH HERE{% else %}{{ page.title }}{% endif %}</a></h1>
		{% else %}
    <h1 class="entry-title">{% if site.titlecase %}{{ page.title | titlecase }}{% else %}{{ page.title }}{% endif %}</h1>
	{% endif %}
{% endif %}

Octopress, which is based on Jekyll and the Liquid templating engine, makes quick work of turning just about anything from your YAML front matter into part of the theme. Once you tell the theme to treat links posts differently with {% if post.external-url %}, then all you have to do is define your link out with <a href="{{ post.external-url }}">. That’s it. No scripting, no plugins. Just old-fashioned HTML. Neat.

We still need to add a permalink to the end of the post. Again, easy as pie. Let’s just head back into article.html only this time we’ll focus on the bottom portion. The following should be the last lines in your code. 3

Bottom of Article.html
1
2
3
4
5
6
7
8
{% if post.external-url %}
	<div class="entry-content"></div>
	<footer><a rel="full-article" href="{{ root_url }}{{ post.url }}">Permalink</a></footer>
{% endif %}
{% if page.external-url %}
<footer><a rel="full-article" href="{{ root_url }}{{ post.url }}">Permalink</a>
</div></footer>
{% endif %}

Same idea, only now we’re adding the permalink back to your site. This permalink appears both on the main list of posts and in the specific post page. I find this makes it easy for readers to find the direct URL no matter how they came to the page.

Finally, we need to get the RSS feed to link out and have permalinks back to the original posts. To do this, we need to make a few edits to /source/atom.xml. This certainly freaked me out more than editing plain old HTML, but it’s actually just as simple. Thanks to Octopress’s handy rake preview command, it’s easy enough to test your changes locally, even for the RSS feed. I test my site in Safari on a Mac, so I’m able to initiate the RSS feed in-browser.4

Changes to Atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{% for post in site.posts limit: 20 %}
<entry>
  {% if post.external-url %}
	<title type="html"><![CDATA[{{ post.title | cdata_escape }} GLYPH GOES HERE]]></title><!-- add in a glyph or [link-post] here so people know where they're ending up -->
	<link href="{{ post.external-url }}"/>
	{% else %}
	<title type="html"><![CDATA[{{ post.title | cdata_escape }}]]></title>
	<link href="{{ site.url }}{{ post.url }}"/>
	{% endif%}
  <updated>{{ post.date | date_to_xmlschema }}</updated>
  <id>{{ site.url }}{{ post.id }}</id>
  {% if post.external-url %}
  <content type="html"><![CDATA[{{ post.content | expand_urls: site.url | cdata_escape }}<a rel="full-article" href="{{ site.url }}{{ post.url }}">Permalink</a>]]></content><!-- add in a glyph or some way to denote that the permalink goes back to your site -->
	{% else %}
  <content type="html"><![CDATA[{{ post.content | expand_urls: site.url | cdata_escape }}]]></content>
	{% endif%}
</entry>
{% endfor %}

Again, it’s just a matter of placing that post.external-url in the right place. I’ve been deploying this site like this for weeks without incident.

I’m not really a coder, but I find that Octopress makes it pretty simple to implement any kind of customization. When I implemented a similar system on Wordpress it required installing a plugin (the excellent DFLL Plugin) and fiddling around with the site’s theme. I found the process on Octopress decidedly more enjoyable. Instead of being at the mercy of plugins (which add bloat and an extra layer of management to your site) I was able to get this running with a basic understanding of HTML. Better, the ability to test the site locally allowed me to screw up over and over again until I got it right. And I think I finally did.

So, did I leave any details out? Anything else you want to know about how this works? Ask me in the comments.

  1. This is actually the opposite format that Gruber uses on his site, where link posts are the norm and original writing features an added glyph before the title, in his case a ★.

  2. YAML front matter is just computer-nerd way of saying Metadata. All of the non-post information, like author, publish date, tags, etc. goes into the top of every posts. Octopress then parses that data when you publish.

  3. These lines actually need to be followed by the code version of basically else > content > endif, but for some reason I’m having trouble embedding it here. This Gist should fill in the blanks. (Gist embedding actually isn’t working either. I guess there are a few things to fix around here.)

  4. If you use a feed re-broadcasting service such as Feedburner (like I do) don’t worry, if the feed your site generates locally is spot on then it will get to Feedburner without issue.

Comments