Search code examples
rubyjekylljekyll-extensions

Jekyll plugin using FastImage returns error with local images


I'm trying to write a Jekyll plugin which calculates the aspect ratio of an image and wraps it in a container of that size to avoid reflows when loading the page. I'm using fastimage to calculate the ratio, right now it looks like this:

require 'fastimage'

module Jekyll
  class PlaceholderImageTag < Liquid::Tag

    def initialize(tag_name, markup, tokens)
      super
      @image_url = 'image_url'
    end

    def render(context)
      @index = Liquid::Template.parse("{{ forloop.index | minus: 1 }}").render(context)
      @base_url = Liquid::Template.parse("{{ site.#{@image_url} }}").render(context)
      @src = Liquid::Template.parse("{{ page.images[#{@index}].image }}").render(context)

      @size = FastImage.size("http://localhost:4000/public/images/"+@src)
      @ratio = (@size[1]*1.0/@size[0])*100

      placeholder = "<div class='placeholder' style='padding-bottom:#{@ratio}%'>"
      placeholder += "<img src=\"#{@base_url}\/#{@src}\"/>"
      placeholder += "</div>"
    end
  end
end

Liquid::Template.register_tag('placeholder_img', Jekyll::PlaceholderImageTag)

The issue is that when I build my site locally (localhost:4000) FastImage returns and error - If I point FastImage to a different local server (like MAMP) or my production URL it works just fine, however using the jekyll server simply fails.

Is it possible to get FastImage to work without pointing to a separate server?


Solution

  • I find I can run a similar plugin just fine if the placeholder_img tags are not present in the site source code before you start jekyll.

    So the problem is when you start jekyll it tries to build the static files before the server is running, so the images cannot, at that moment, be fetched by FastImage.

    Try starting jekyll like this

    jekyll serve --skip-initial-build
    

    This then as soon as any file is changed jekyll will successfully regenerate it and serve it.

    You might need to touch some files if they have been changed when jekyll was not running in order to trigger the regeneration, or just run jekyll build once the server is already running.