-
-
Save jgatjens/8925165 to your computer and use it in GitHub Desktop.
#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) |
For now I am using the solution presented here.
I get a
> jekyll serve --trace
Configuration file: /home/skuzzymiglet/ysgol/gwefan-jekyll/_config.yml
Source: /home/skuzzymiglet/ysgol/gwefan-jekyll
Destination: /home/skuzzymiglet/ysgol/gwefan-jekyll/_site
Incremental build: disabled. Enable with --incremental
Generating...
Liquid Exception: undefined method `render_all' for #<Jekyll::LoopDirectoryTag:0x000056284e5f07e0> in index.md
Traceback (most recent call last):
41: from /home/skuzzymiglet/.gem/ruby/2.6.0/bin/jekyll:23:in `<main>'
40: from /home/skuzzymiglet/.gem/ruby/2.6.0/bin/jekyll:23:in `load'
39: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/exe/jekyll:15:in `<top (required)>'
38: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/mercenary-0.3.6/lib/mercenary.rb:19:in `program'
37: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/mercenary-0.3.6/lib/mercenary/program.rb:42:in `go'
36: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in `execute'
35: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in `each'
34: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in `block in execute'
33: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/commands/serve.rb:86:in `block (2 levels) in init_with_program'
32: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/command.rb:89:in `process_with_graceful_fail'
31: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/command.rb:89:in `each'
30: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/command.rb:89:in `block in process_with_graceful_fail'
29: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/commands/build.rb:36:in `process'
28: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/commands/build.rb:65:in `build'
27: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/command.rb:28:in `process_site'
26: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/site.rb:76:in `process'
25: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/site.rb:202:in `render'
24: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/site.rb:515:in `render_pages'
23: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/site.rb:515:in `each'
22: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/site.rb:516:in `block in render_pages'
21: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/site.rb:523:in `render_regenerated'
20: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/renderer.rb:63:in `run'
19: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/renderer.rb:80:in `render_document'
18: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/renderer.rb:127:in `render_liquid'
17: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:32:in `render!'
16: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:60:in `measure_time'
15: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:33:in `block in render!'
14: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:53:in `measure_bytes'
13: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:34:in `block (2 levels) in render!'
12: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:49:in `measure_counts'
11: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:35:in `block (3 levels) in render!'
10: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/liquid-4.0.3/lib/liquid/template.rb:220:in `render!'
9: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/liquid-4.0.3/lib/liquid/template.rb:207:in `render'
8: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/liquid-4.0.3/lib/liquid/template.rb:242:in `with_profiling'
7: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/liquid-4.0.3/lib/liquid/template.rb:208:in `block in render'
6: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/liquid-4.0.3/lib/liquid/block_body.rb:82:in `render'
5: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/liquid-4.0.3/lib/liquid/block_body.rb:103:in `render_node_to_output'
4: from /home/skuzzymiglet/ysgol/gwefan-jekyll/_plugins/loop_dir.rb:52:in `render'
3: from /home/skuzzymiglet/.gem/ruby/2.6.0/gems/liquid-4.0.3/lib/liquid/context.rb:123:in `stack'
2: from /home/skuzzymiglet/ysgol/gwefan-jekyll/_plugins/loop_dir.rb:56:in `block in render'
1: from /home/skuzzymiglet/ysgol/gwefan-jekyll/_plugins/loop_dir.rb:56:in `each'
/home/skuzzymiglet/ysgol/gwefan-jekyll/_plugins/loop_dir.rb:58:in `block (2 levels) in render': undefined method `render_all' for #<Jekyll::LoopDirectoryTag:0x000056284e5f07e0> (NoMethodError)
my index.md:
---
layout: default
title: "Happy Jekylling!"
---
## You're ready to go!
{% loop_directory directory:images iterator:image filter:*.jpg sort:descending %}
<img src="{{ image }}" />
{% endloop_directory %}
Clean, jekyll new --blank
site
@skuzzymiglet do you have some repo with the code to see what's going on there?
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.
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.
I can't seem to get it work.
my directory for the image folder is /images under root directory.
The frontmatter in the post, I have "photos: /images"
and in my layout html, I have:
{% loop_directory directory: {{ page.photos }} iterator:image filter:*.jpg sort:descending %}
<img src="{{ image }}" />
{% endloop_directory %}
but nothing's showing. What did I do wrong?
@meiadvanture this is like 8 years old or more, try this tho:
{% loop_directory directory:images iterator:image filter:*.jpg sort:descending %}
<img src="{{ image }}" />
{% endloop_directory %}
Not sure about your {{ page.photos }}
try it without that first and see.
@planemad, were you able to get this working? This seems like a common use case. I am trying to solve the same problem as well.