Adding Related Post to Octopress

octopress
This post is too old to be of any use. It has been archived.

These are the simple steps I followed to add a "related posts" block to posts in my Octopress blog.

Changing the template

Jekyll has 'related posts' functionality already, all I needed to do was to use it in the template. The code below, adapted from the blog index, displays the block if there are at least two related posts. I added it to post.html.

{% if site.related_posts.size > 1 %}
<article class="archives">
  <div class="related-posts">
    <h2>Related Posts</h2>
    {% for post in site.related_posts limit:site.recent_posts %}
      <article>
        <h3 class="title"><a href="{{ root_url }}{{ post.url }}">{{post.title}}</a></h3>
        <div class="meta">
          <span class="tags">{% include post/categories.html %}</span>
            {% if site.disqus_short_name and post.comments == true and site.disqus_show_comment_count == true %}
          <time datetime="{{ date | datetime | date_to_xmlschema }}" pubdate{% if post.updated %} data-updated="true"{% endif %}>{{ date | date: "%F" }}</time>
            {% endif %}
        </div>
      </article>
    {% endfor %}
  </div>
</article>
{% endif %}

Did the necessary SASS amends, generated the blog, and it was all there. Except that the related posts where simply the latest posts. For a better list, I needed to run jekyll with lsi.

The --lsi option performs a proper statistical analysis of the posts to determine the best related posts. Turns out Octopress can already tell Jekyll to turn lsi on - it's just a matter of adding a new property somewhere in the _config.yml file

...
lsi: true
...

I regenerated the blog and... after an hour it still hadn't generated the site. Not good. Time to try and install gsl.

Install GSL

GSL is a scientific maths library which Ruby can use to speed up the calculations. Hopefully that will save the day.

> brew install gsl
==> Downloading http://ftpmirror.gnu.org/gsl/gsl-1.15.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/gsl/1.15
==> make
==> make install
Warning: m4 macros were installed to "share/aclocal".
Homebrew does not append "/usr/local/share/aclocal"
to "/usr/share/aclocal/dirlist". If an autoconf script you use
requires these m4 macros, you'll need to add this path manually.
Warning: Could not link gsl. Unlinking...
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
You can try again using `brew link gsl'
==> Summary
/usr/local/Cellar/gsl/1.15: 237 files, 7.1M, built in 88 seconds

So homebrew wasn't happy - well, it never is. A bit of tweaking and googling produced the following

> sudo chmod 775 /usr/local/include
> brew link gsl
Linking /usr/local/Cellar/gsl/1.15... 18 symlinks created
> sudo gem install gsl
Building native extensions.  This could take a while...
ERROR:  Error installing gsl:
    ERROR: Failed to build gem native extension.
    ....(more stuf)

Now gsl is installed, but the gem is not happy. A bit of research revealed the problem is that the ruby gem is not compatible with the latest version of gsl, which is what homebrew installs. To downgrade it, I followed the instructions on this post and it seemd to work (kinda)

> brew uninstall gsl
> brew update
> brew edit gsl
# pasted code in
> brew install gsl
> sudo gem install gsl -v '1.14.7'
Password:
Building native extensions.  This could take a while...
Successfully installed gsl-1.14.7
1 gem installed
Installing ri documentation for gsl-1.14.7...
unable to convert "\x81" from ASCII-8BIT to UTF-8 for rdoc/fit.rdoc, skipping
unable to convert "\x81" from ASCII-8BIT to UTF-8 for rdoc/ndlinear.rdoc, skipping
Installing RDoc documentation for gsl-1.14.7...
unable to convert "\x81" from ASCII-8BIT to UTF-8 for rdoc/fit.rdoc, skipping
unable to convert "\x81" from ASCII-8BIT to UTF-8 for rdoc/ndlinear.rdoc, skipping

Well, look reasonable enough (who cares about manuals, right). Typing gsl-config on the command line also returned a a command, showing gsl was installed correctly. But then when generating the site...

rake generate
## Generating Site with Jekyll
unchanged sass/screen.scss
/Users/ME/.rvm/gems/ruby-1.9.3-p194/gems/maruku-0.6.0/lib/maruku/input/parse_doc.rb:22:in `<top (required)>': iconv will be deprecated in the future, use String#encode instead.
Configuration from /Users/ME/work/octopress/_config.yml
Notice: for 10x faster LSI support, please install http://rb-gsl.rubyforge.org/

So that was a waste of time. I filed a bug report and left it at that.

Lawrence Woodman has created a simpler related_posts plugin which looks at tags instead of doing complex analysis. I downloaded that simple file to my plugin directory, regenerated the site, and that was that. A lot of the posts do not have tags at all, but the template doesn't print any "related posts" HTML at all unless there are at least two of them, so that's alright. I actually like this system better than lsi, because I can control what's related to what by creating tags.