Skip to content

Instantly share code, notes, and snippets.

@jgatjens
Created February 10, 2014 22:03
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jgatjens/8925165 to your computer and use it in GitHub Desktop.
Save jgatjens/8925165 to your computer and use it in GitHub Desktop.
jekyll-plugin loop_directory
#usage:
#{% loop_directory directory:images iterator:image filter:*.jpg sort:descending %}
# <img src="{{ image }}" />
#{% endloop_directory %}
module Jekyll
class LoopDirectoryTag < Liquid::Block
include Liquid::StandardFilters
Syntax = /(#{Liquid::QuotedFragment}+)?/
def initialize(tag_name, markup, tokens)
@attributes = {}
@attributes['directory'] = '';
@attributes['iterator'] = 'item';
@attributes['filter'] = 'item';
@attributes['sort'] = 'ascending';
# Parse parameters
if markup =~ Syntax
markup.scan(Liquid::TagAttributes) do |key, value|
@attributes[key] = value
end
else
raise SyntaxError.new("Bad options given to 'loop_directory' plugin.")
end
#if @attributes['directory'].nil?
# raise SyntaxError.new("You did not specify a directory for loop_directory.")
#end
super
end
def render(context)
context.registers[:loop_directory] ||= Hash.new(0)
images = Dir.glob(File.join(@attributes['directory'], @attributes['filter']))
if @attributes['sort'].casecmp( "descending" ) == 0
# Find files and sort them reverse-lexically. This means
# that files whose names begin with YYYYMMDD are sorted newest first.
images.sort! {|x,y| y <=> x }
else
# sort normally in ascending order
images.sort!
end
result = []
context.stack do
# remove filename extension
images.each { |pathname|
context[@attributes['iterator']] = File.basename(pathname, @attributes['filter'].sub('*', ''))
result << render_all(@nodelist, context)
}
# return pathname
# images.each_with_index do |item, index|
# context[@attributes['iterator']] = item
# result << render_all(@nodelist, context)
# end
end
result
end
end
end
Liquid::Template.register_tag('loop_directory', Jekyll::LoopDirectoryTag)
@miko007
Copy link

miko007 commented Feb 24, 2020

i have come across the same problem. seems like Liquid::Block does not provide the render_all method anymore. Even the regular Liquid::Block::render() method is marked "For backwards compatibility". Likewise, the whole API for liquid blocks has changed.

I will have a more in-depth look into the problem, but never having wrote a liquid/jekyll module myself, it will not be very successful, i fear.

@photm5
Copy link

photm5 commented May 14, 2021

For a simpler version that works well with the built-in for block and works with current versions of liquid, see https://gitlab.com/baldrian/klimacamp-augsburg/-/blob/91244ae327380714e6d62778598a4bc69917c557/_plugins/list_files.rb. It creates a Page object for each of the files that were found, so if you don't want that, remove the .map do ... end part (you can also remove the site = ... and source = ... lines as well as the comment in that case) – without the map call, you'll get a list of filenames instead of a list of pages. See https://gitlab.com/baldrian/klimacamp-augsburg/-/blob/91244ae327380714e6d62778598a4bc69917c557/feeds/pressemitteilungen.xml#L14-15 for an example usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment