在没有JavaScript的情况下生成维基百科上的目录

时间:2013-03-13 07:46:37

标签: ruby-on-rails ruby-on-rails-3 tableofcontents

我有一个格式如下的页面:

<h1>Header</h1>
<h2>Subheader</h2>    
<h3>Subsubheader</h3>
<h1>Another header</h1>

服务器端是否可以在页面开头生成目录/大纲,就像维基百科在其文章中所做的那样?我使用Ruby on Rails。

编辑:没有JavaScript!

3 个答案:

答案 0 :(得分:1)

我今天为此目的创建了一个类。它取决于http://www.nokogiri.org/,但该宝石已经附带Rails。

将其放入app/models/toc.rb

class Toc
  attr_accessor :html

  TOC_CLASS = "toc".freeze
  TOC_ELEMENT = "p".freeze
  TOC_ITEMS = "h1 | h2 | h3 | h4 | h5".freeze
  UNIQUEABLE_ELEMENTS = "h1 | h2 | h3 | h4 | h5 | p".freeze

  def initialize(content)
    @html = Nokogiri::HTML.fragment content
  end

  def generate
    clear
    set_uniq_ids
    toc = create_container

    html.xpath(TOC_ITEMS).each { |node| toc << toc_item_tag(node) }
    html.prepend_child toc

    return html.to_s
  end

  private

  def clear
    html.search(".#{TOC_CLASS}").remove
  end

  def set_uniq_ids
    html.xpath(UNIQUEABLE_ELEMENTS).
      each { |node| node["id"] = rand_id }
  end

  def rand_id
    (0...8).map { ('a'..'z').to_a[rand(26)] }.join
  end

  def create_container
    toc = Nokogiri::XML::Node.new TOC_ELEMENT, html
    toc["class"] = TOC_CLASS

    return toc
  end

  def toc_item_tag(node)
    "<a data-turbolinks='false' class=\"toc-link toc-link-#{node.name}\" href=\"##{node["id"]}\">#{node.text}</a>"
  end
end

一样使用它
toc = Toc.new article.body
body_with_toc = toc.generate
article.update body: body_with_toc

答案 1 :(得分:0)

您需要从层次结构中生成数据源,使其像这样

 @toc = [ ['header', 0], ['subheader', 1], ['subsubheader', 2],
             ['header2', 0], ['header3', 0], ['subheader2', 1]
        ]

比在模板中渲染它更容易,例如:

<%- @toc.each do |item, distance| %>
    <%= ('&nbsp;' * distance  * 5).html_safe %>
    <%= item %>
    <br/>
<%- end %>

会给你:

header 
      subheader 
           subsubheader 
header2 
header3 
      subheader2 

当然你可以使用'距离'来确定风格大小而不是'深度',但我希望你能得到主要的想法。

答案 2 :(得分:-2)

是的,有可能。你真的不需要铁轨;您还可以使用javascript生成目录。 这是一个可以使用的exmaple库。 http://www.kryogenix.org/code/browser/generated-toc/

您可以在rails erb / haml视图中循环遍历元素时创建锚点链接。