2012-03-22 50 views
9

我无法弄清楚如何在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,这对我来说似乎有点难看。另外,由于无法在html中转义{},因此过滤器无法获取像*。{jpg,png}这样的参数。打开关于如何在属性中传递正则表达式字符串的建议...

#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) 

回答

-4

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

你可能更喜欢使用像Sinatra这样的东西,你可以做一些非常简单的事情来获取文件列表并在模板中迭代它们。

+1

我猜所有的反对票都是因为这是一个评论,而不是对问题的回答。 – jbranchaud 2013-03-15 20:56:28

0

在Github主分支上有一个等待合并到Jekyll 1.0.0beta中的功能的请求;他们只是在等待创作者TPW的最终批准。

您可以查看代码并将其复制以供自己使用,并留意合并时间。然后,你可以用这个功能下载合并后的化身,并使用它无需插件,这样做:

gem install jekyll --pre

这将让你从GitHub的边缘版本。

这里的PR - 新液标签上市文件:目录:

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

相关问题