【问题标题】:Extending Octopress to use automatic partials扩展 Octopress 以使用自动分部
【发布时间】:2012-04-19 00:04:58
【问题描述】:

所以在 Octopress 中,我希望有一个充满部分的文件夹,我可以轻松地在网站上以不同的方式显示。我想要一个链接到包含所有部分的文档中的部分标题列表。

这是我想使用的逻辑,但我不知道如何在 Octopress 中实际实现它。

class Collection
  attr_accessor :directory, :files

  def new(dir)
    self.files = []
    self.directory = dir
    load_files
  end

  def list(options={})
    # Handle options here
    files
  end

private

  def load_files
    files_in(@directory).each do |file| # Psuedo-code
      f = Jekyll::FileObject.new(file.read) # Also fictional, but I imagine something similar exists
      f.text # Would return the actual content
      f.yaml # Would return a hash of options from the YAML front matter

      files << f
    end
  end
end

然后我想加载partials的集合:

api_methods = Collection.new("api_methods").list(:alphabetical => true, :method_type => "public")

在液体中,列出目录:

<ul>
{% for partial in api_methods %}
  <li><a href="{% partial.yaml.url %}">{% partial.yaml.name %}</a></li>
{% endfor %}
</ul>

在液体中,列出全文:

{% for partial in api_methods %}
  <h2>{% partial.yaml.name %}</h2>

  {% partial.text %}
{% endfor %}

所以这应该可以让您对我正在尝试做的事情有一个基本的了解,但是我不知道如何实际实现它。

【问题讨论】:

    标签: ruby jekyll liquid


    【解决方案1】:

    好的,这就是我完成我打算做的事情的方式。

    首先,我必须认真阅读 Jekyll 的源代码。一旦我对它的工作原理有了一个基本的了解,我就可以进去修补某些东西。

    基本上,Liquid 是一个非常简单的模板系统,您无法使用它转换任何数据。您必须以“有效负载”的形式将数据发送到 Liquid,这只是一个大哈希。因此,如果我想转换一些数据,我必须在将其发送到 Liquid 之前在 Ruby 中完成。

    所以我做了一个叫PayloadExtension的东西:

    plugins/site.rb

    module Jekyll
      class Site
        alias :old_site_payload :site_payload
    
        def site_payload
          PayloadExtension.payload(old_site_payload)
        end
      end
    end
    

    plugins/payload_extension.rb

    module Jekyll
      class PayloadExtension
        extend OctopressFilters
    
        def self.payload(payload)
          pages = payload['site']['pages']
    
          # Filter pages by Public API methods category and sort by title
    
          public_api_methods = category_filter(pages, "Public API methods")
          public_api_methods.sort! {|a, b| a.data['title'] <=> b.data['title'] }
          public_api_methods = pre_render(public_api_methods)
    
          payload['site']['public_api_methods'] = public_api_methods
    
          payload
        end
    
      private
    
        def self.category_filter(pages, category)
          pages.reject do |page|
            cat = page.data['category']
    
            !cat || cat.empty? || cat != category || ( cat.is_a?(Array) && !cat.include?(category) )
          end
        end
    
        def self.pre_render(pages)
          pages.collect do |page|
            content = pre_filter(page.content)
            page.data['rendered'] = Liquid::Template.parse(content).render
            page
          end
        end
    
      end
    end
    

    很遗憾,我没能搞定Convertible#do_layout,所以我在这个阶段可以访问的数据并不是最终的东西,但这没关系,因为它很容易解决。

    我还必须自己手动渲染页面的内容,因为只输入{{ page.content }} 会吐出尚未完全解析的文本。

    现在在实际的 Liquid 模板中,我可以这样做:

    {% for page in site.public_api_methods %}
      <h2>{{ page.title }} / {{ page.http_method | upcase }}</h2>
      {{ page.rendered }}
    {% endfor %}
    
    <h3>Public methods</h3>
    <ul>
      {% for page in site.public_api_methods %}
        <li><a href="/api/public-methods/#{{ page.title | slugify }}-{{ page.http_method }}">{{ page.title }}</a></li>
      {% endfor %}
    </ul>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多