从Jekyll插件返回目录中的文件列表?

时间:2012-03-22 19:38:24

标签: ruby arrays plugins hash jekyll

我无法弄清楚如何在jekyll插件中创建过滤器或标记,以便我可以返回一个目录并循环其内容。我找到了这些:

http://pastebin.com/LRfMVN5Y

http://snippets.dzone.com/posts/show/302

到目前为止,我有:

module Jekyll
  class FilesTag < Liquid::Tag

    def initialize(tag_name, text, tokens)
      super
      @text = text
    end

    def render(context)
        #"#{@text} #{Time.now}"
        Dir.glob("images/*").each { |i| "#{i}" }
        #Dir.glob("images/*")
        #Hash[*Dir.glob("images/*").collect { |v| [v, v*2] }.flatten]
    end
  end
end

Liquid::Template.register_tag('files', Jekyll::FilesTag)

我可以成功地将图像列表作为字符串返回并使用以下命令打印:

{% files test_string %}

但是对于我的生活,无论我如何从Dir.glob返回数组/哈希,我都无法遍历数组。我只是希望能够做到:

{% for image in files %}
    image
{% endfor %}

我将需要能够为我将在网站上使用的各种集合不断返回数组。我只需要一个准系统插件来构建。

谢谢!


更新:我部分解决了它。这个方法有效,但需要使用endloop_directory而不是endfor,这对我来说似乎有点难看。此外,过滤器无法采用像*。{jpg,png}这样的参数,因为无法逃脱html中的{}。打开有关如何在属性中传递正则表达式字符串的建议...

#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

            length = images.length
            result = []

            context.stack do
                images.each_with_index do |item, index|
                    context[@attributes['iterator']] = item
                    context['forloop'] =
                    {
                        'name' => @attributes['iterator'],
                        'length' => length,
                        'index' => index + 1,
                        'index0' => index,
                        'rindex' => length - index,
                        'rindex0' => length - index - 1,
                        'first' => (index == 0),
                        'last' => (index == length - 1) 
                    }

                    result << render_all(@nodelist, context)
                end
            end

            result
        end
    end
end

Liquid::Template.register_tag('loop_directory', Jekyll::LoopDirectoryTag)

3 个答案:

答案 0 :(得分:1)

我在这里找到了一个插件:How to list files in a directory with Liquid?可以解决这个问题:

<强>化身:: DirectoryTag 此标记允许您迭代特定路径上的文件。目录标记产生文件对象和forloop对象。如果文件符合标准的Jekyll格式,YYYY-MM-DD-file-title,那么这些属性将填充在该文件对象上。

https://github.com/sillylogger/jekyll-directory

答案 1 :(得分:0)

Github Master Branch上有一个拉取请求,等待合并到Jekyll 1.0.0beta;他们只是在等待创作者TPW的最终批准。

您现在可以查看代码并将其复制以供自己使用,并留意何时合并。然后你可以下载合并的Jekyll与该功能,并在没有插件的情况下使用它,通过:

gem install jekyll --pre

这将从Github获得优势版。

这是PR - 用于列出文件的新Liquid标签:directory:

https://github.com/mojombo/jekyll/pull/585

答案 2 :(得分:-5)

您使用Jekyll的具体原因是什么?看起来你想要更动态的东西,而Jekyll则设计用于生成平面HTML文件。

您可能会更喜欢使用像Sinatra这样的东西,在那里您可以非常直接地抓取文件列表并在模板中迭代它们。