使用 Nokogiri 在 Slate/Middleman 中生成静态 header 列表

Using Nokogiri to generate static header list in Slate/Middleman

我对中间人和 ruby 没有经验,但我一直在努力让 Slate 工作,所以它在构建过程中生成 navigation/list 的 header时间而不是客户端使用 javascript。我 运行 遇到的问题是让代码包含来自部分的 headers。

目录结构示例:

Source
+--config.rb
+--includes
  +--file.md
  +--otherfile.md
+--index.html
+--layouts
  +--layout.erb

Gist of layout and config.rb

Config.rb 片段:

require 'nokogiri'

helpers do   
def toc_data(page_content)
    html_doc = Nokogiri::HTML::DocumentFragment.parse(page_content)

    # get a flat list of headers
    headers = []
    html_doc.css('h1, h2, h3').each do |header|
      headers.push({
        id: header.attribute('id').to_s,
        content: header.content,
        level: header.name[1].to_i,
        children: []
      })
    end

    [3,2].each do |header_level|
      header_to_nest = nil
      headers = headers.reject do |header|
        if header[:level] == header_level
          header_to_nest[:children].push header if header_to_nest
          true
        else
          header_to_nest = header if header[:level] == (header_level - 1)
          false
        end
      end
    end
    headers   
  end
end

此布局片段:

<ul id="toc" class="toc">
    <% toc_data(page_content).each do |h1| %>
      <li>
        <a href="#<%= h1[:id] %>" class="toc-h1"><%= h1[:content] %></a>
          <ul class="toc-section">
            <% h1[:children].each do |h2| %>
              <li>
                <a href="#<%= h2[:id] %>" class="toc-h2"><%= h2[:content] %></a>
                <ul class="toc-submenu">
                  <% h2[:children].each do |h3| %>
                    <li>
                      <a href="#<%= h3[:id] %>" class="toc-h3"><%= h3[:content] %></a>
                    </li>
                  <% end %>
                </ul>
              </li>
            <% end %>
          </ul>
      </li>
    <% end %>
  </ul>
...
    <div class="page-wrapper">
  <div class="content">
    <%= page_content %>
    <% current_page.data.includes && current_page.data.includes.each do |include| %>
      <%= partial "includes/#{include}" %>
    <% end %>
  </div>
</div>

目前,只有 index.html 文件中的 header 被填充,包含的部分中没有任何内容。我相信我可能需要现有的助手来使用 ready 助手来 post 构建 similar to what is described in the Middleman docs for sitemaps。我相信我必须对配置代码进行另一次更改,以便它捕获 page_content 之外的其他内容,但由于不熟悉,我不确定那是什么。任何指针将不胜感激。

编辑:查看中间人基础文档后,我可以使用来自 Padrino 框架的两个助手:capture_htmlconcat_content。我试图找到帮助程序 page_content 的定义位置,以便为我所做的特定更改获取额外的上下文。

不熟悉该框架,但看起来 toc_data(page_content) 只看主要内容,不看 current_page.data.includes 部分内容。

所以我猜你也需要将部分传递给你的 toc_data 函数。

也许这行得通?

<%
  full_content = page_content
  current_page.data.includes && current_page.data.includes.each do |include|  
    full_content += partial("includes/#{include}")
  end 
  toc_data(full_content).each do |h1| 
%>
  ...
<% end %>

希望对您有所帮助。

为了将当前页面数据与 page_content 的部分内容连接起来,请使用以下代码。这也改变了生成完整页面所需的一切。

<%
  if current_page.data.includes
    current_page.data.includes.each do |include|
      page_content += partial("includes/#{include}")
    end
  end
%>
...
<%= page_content %>