2
votes

I have been using Jekyll for a month or two now, I am also new to Ruby so learning every day.

In my site I want to add the reading time of blog posts, I have found this ruby gem which will let me do it

https://github.com/garethrees/readingtime

I install it in the normal way into my sites root and add the code needed and nothing happens. This isn't a shock because I have no actually link to it in my sites root?

So it my site looks like this html wise

---
layout: default
---

 <div class="twelve columns">
        <h3>{{ page.title }}</h3>
        <span class="date">Wrote by Josh Hornby</span> 
 <span class="date">Estimated reading time – <%= @article.body.reading_time %> </span>
        <br /> <br />
         <%= @article.body %>
        {{ content }}
         </article>

        <a href="https://twitter.com/intent/tweet?text=Check out this blog by @joshua_hornby - www.joshhornby.co.uk"> <div class="twitter_button"> <img src="/images/twitter.png" alt="twitter-logo" width="50" height="50" /> </div> </a> 
  </div>

    <div class="four columns">
        <h3>Recent Posts</h3>
        <p>Find out what else I've been talking about:</p>
           {% for post in site.related_posts limit: 10 %}
        <ul class="square">
            <li><a class="title" style="text-decoration:none;" href="{{post.url}}"><strong>{{ post.title }}</strong></a>
            {% endfor %}
        </ul>
    </div>

Now I'm not shocked that its not working but my question is how to a install the gem so I can access it in my Jekyll file? Do I need to create a _plugin directory and call it from there? Or won't it work as its not a jekyll plugin? In that case I may have a little project writing my own Ruby Jekyll plugin.

1

1 Answers

5
votes

As you have surmised, you cannot call arbitrary ruby commands in your html using <%. Instead, you want to write a plugin which defines a Liquid filter. In your html above, you would use the liquid tag to grab the content of the page. You might want to brush up on liquid-for-designers and liquid-for-programmers as well as the Jekyll notes on writing liquid extensions before we dive in, but I'll try to explain.

First, we need to use a Jekyll filter to grab the content of the page, which we will pass to our plugin for analysis. Above you have an @article.body which probably means something to a ruby on rails site, but doesn't mean anything to Jekyll. As you see in the center of your layout file, the content for the page is simply called content. It is pulled in through a Liquid output, indicated by the {{ }}.

In place of the line

<span class="date">Estimated reading time – <%= @article.body.reading_time %> </span>

We want a line that grabs the content and passes it to our plugin:

<span class="date">Estimated reading time – {{ content | readingtime }} </span>

The vertical bar is a filter, meaning pipe content to the function readingtime and include the output. Now we need to write the plugin itself. In the _plugins directory, we create a ruby script following the standard template for a Liquid filter:

require 'readingtime'
module TextFilter
  def readingtime(input)
    input.reading_time
  end
end
Liquid::Template.register_filter(TextFilter)

And save the above as something like readingtime.rb in _plugins. It's kinda self explanatory, but you see this tells ruby to load the gem, and define a filter that takes its input and applies the reading_time function to that string.

A little note: content will pull in the HTML version of the content, not a plain text string. I don't know if the readingtime gem needs a plain text string, but you can of course convert between them using a little extra ruby code. If necessary, that's left as an exercise to the reader (though this might help).