Henrik
Henrik

Reputation: 4044

Jekyll - access plugin object from Liquid

I have a list of images, on which I run mini_exiftool to extract various properties from images (EXIF & IPTC). I have successfully created a LiquidTag. It accepts the path and the EXIF property I want, and returns that as (what I assume is) a string.

However, mini_exiftool is slow. Currently I insert the tag multiple times per image. I would like to run it once per image and store all the data (array? object?) in a variable. Small disclaimer - I hardly know any Ruby, apart from what I learned trying to understand this issue.

This is how I use the plugin:

{% exif path, title %}
{% exif path, lens %}

This is the plugin, a hodgepodge of guesswork and code found online:

require 'mini_exiftool'

module Jekyll
  class Exif < Liquid::Tag
    def initialize(tag_name, params, token)
      super
      args = params.split(",").map(&:strip)
      @filename = args[0]
      @property = args[1]
    end
    def lookup(context, name)
      lookup = context
      name.split(".").each { |value| lookup = lookup[value] }
      lookup
    end
    def render(context)
      path = lookup(context, @filename)
      exif = MiniExiftool.new(path)
      return exif[@property]
    end
  end
end

Liquid::Template.register_tag('exif', Jekyll::Exif)

Upvotes: 0

Views: 137

Answers (1)

Christian
Christian

Reputation: 7141

From how you described the plugin, I would say it does what you want. The plugin returns a specific property from (a photo?) and returns it as a string.

But it sounds as you want to to it one time only and store it somewhere else. In this case you might want to consider doing it a bit different. Esp when you say the property reading is slow.

You could in example use a generator to create the data you need based on all images before a run. Details on generators: http://jekyllrb.com/docs/plugins/#generators

You could have a similar approach like I have for sorting languages:

class Generator < Jekyll::Generator
    def generate(site)

      site.data['news-en'] = Array.new
      # Do something with exif and push a value object:
      site.data['news-en'].push(p)

The data is then available in your sites data object. It can be accessed like:

{% for post in site.data['news-en'] %}

Please see datafile docs here: http://jekyllrb.com/docs/datafiles/

However, if you really don't add a lot of photos all the time but update your other text posts on regular schedule, you might want to even move out of Jekyll and use Gulp/Grunt or similar tools to generate a data file.

Let me know if I got your question wrong and I will update my answer accordingly.

Upvotes: 1

Related Questions