Search code examples
rubyjekylljekyll-extensions

Jekyll: How to pass a Ruby object to a template?


For example, say I'd like to generate this array:

random_numbers = []
1000.times { random_numbers << rand(2) }

And pass it to a template, so that I can access it from Liquid:

{% for num in random_numbers %} 
  ... here I'd use logic around the number to generate something.
{% endfor %}

Note: I want to generate the array dynamically in Ruby. And inside the template, I want an array that I can iterate with, I don't want a string.

How can this be done in Jekyll?


Solution

  • Well, you'd need a plugin: https://github.com/mojombo/jekyll/wiki/Plugins

    If you were happy to put the logic in your plugin, you could do it in a custom Liquid::Tag, but your requirements sound like they'd need a generator, which is OK. I just threw this together and it seems to work as you'd like:

    module Jekyll
    
    class RandomNumberGenerator < Generator
    
      def generate(site)
        site.pages.each do |page|
          a = Array.new
          1000.times { a << rand(2) }
          page.data['random_numbers'] = a
        end
      end
    
    end
    
    end
    

    that should go in your _plugins/ directory (as rand.rb or something). In your templates, you can then do

    <ul>
        {% for number in page.random_numbers %}
            <li>{{ number }}</li>
        {% endfor %}
    </ul>
    

    Or whatever you'd like. I've assumed that you want a different set of numbers for each page - but if you want one set for the whole site, you could easily produce the array once and then either attach it to the site object or to every page.

    This won't work with the automatic generation on Github Pages (they don't allow custom plugins, for obvious reasons), but that shouldn't be a problem - even if you're using Github Pages there are plenty of workarounds.