matthias
matthias

Reputation: 2181

How to generate files from Liquid blocks in Jekyll?

I am writing a plugin that defines a new Jekyll block ditaa. Any content in the block should be converted from Ditaa markup to an image file and that image inserted into the post instead of the block. Generating the file works but when copying into or generating in the _site directory, the file is apparently deleted.

Is there a proper/better way to implement a block plugin that generates custom assets?

Upvotes: 2

Views: 952

Answers (3)

felixgaal
felixgaal

Reputation: 2423

I've found the proper solution: use the Jekyll::StaticFile class.

When you add one object of this class to the site.static_files array, you are marking this file as pending for copy after the render process is completed. In fact, the copy of such files is done in the site.write process. Take a look at the site_process.rb file in your Jekyll installation.

The usage of this class is easy. When you need to mark a file for future copy, you simply execute a code like this:

site.static_files << Jekyll::StaticFile.new(site, site.source, path, filename)

Where path and filename depends on the location of your file in the src folder.

I had a similar issue developing a LaTeX -> PNG liquid tag. You can take a look at my code at GitLab: https://gitlab.com/felix.galindo/jekyll-liquid-latex-plugin

Upvotes: 2

joegyoung
joegyoung

Reputation: 85

I have found the answer.

Replace this

site.static_files << Jekyll::StaticFile.new(site, site.source, path, filename)

with

gnufile = GNUplotFile.new(site, site.source, "_site/media/", "#{@file}")
gnufile.givemethecommands commands
site.static_files << gnufile 

and create a GNUplotFile class that inherits Jekyll::StaticFile

class GNUplotFile < Jekyll::StaticFile
  def write(dest)
    puts "WRITE---->>>>>>>>>>>"
    #File.write('_site/media/BTTTTT.svg', DateTime.now)
    gnuplot(@commands)
    # do nothing
  end
  def gnuplot(commands)
    IO.popen("gnuplot", "w") { |io| io.puts commands }
  end
  def givemethecommands(commands)
    @commands = commands
  end
end 

The write command runs after the cleanup process. I just have a Liquid block and the above code.

Upvotes: 1

matthias
matthias

Reputation: 2181

I haven't found the proper way to do it, but one that works. The solution can be found on GitHub and uses Jekylls ability to copy anything that is not prefixed with an underscore to the _site directory. However, this approach has also two drawbacks:

  1. The "source" directory gets polluted with auto-generated files
  2. Deploying without auto-regeneration is a bit awkward because the images are generated after Jekyll already copied all files. So a second Jekyll run is necessary.

Upvotes: 1

Related Questions