Computer >> Máy Tính >  >> Lập trình >> Ruby

Tự động tạo điều hướng phụ từ H2s trong Jekyll

Tự động tạo điều hướng phụ từ H2s trong Jekyll

Tôi đang xây dựng lại trang web tài liệu của chúng tôi bằng cách sử dụng Jekyll. Vì các trang tài liệu của chúng tôi khá lớn, chúng tôi phải có một số loại điều hướng phụ ngoài điều hướng cấp cao nhất.

Trong bài đăng này, chúng tôi sẽ giới thiệu cách tạo một trình cắm Jekyll đơn giản có thể tạo liên kết phụ từ các tiêu đề trong bài đăng hoặc trang của bạn.

Tổng quan

Tôi đã chia nhỏ dự án này thành các nhiệm vụ sau:

  1. Tạo trình tạo Jekyll chạy trên mọi trang trên trang web.
  2. Hướng dẫn trình tạo cách hiển thị trước các trang để nó có thể trích xuất thông tin tiêu đề.
  3. Sử dụng nokogiri để phân tích cú pháp các trang HTML trích xuất các tiêu đề và nội dung có liên quan.
  4. Hiển thị điều khoản phụ.

Trong các ví dụ bên dưới, tất cả các liên kết phụ là liên kết cố định. Để cách tiếp cận này hoạt động, bạn sẽ cần đảm bảo bộ xử lý đánh dấu của mình tạo ID cho các tiêu đề. RedCarpet với with_toc_data tùy chọn hoạt động tốt.

Trình tạo Jekyll cơ bản

có một số loại plugin khác nhau mà bạn có thể tạo cho Jekyll. Chúng tôi sẽ tạo một trình tạo.

Trình tạo chỉ đơn giản là các lớp kế thừa từ Jekyll::Generator và cung cấp một phương thức được gọi là generate .

Trình tạo được chạy sau khi Jekyll tải tất cả các tệp đánh dấu nhưng trước khi các tệp đó được chuyển đổi sang HTML. Một site đối tượng được chuyển vào phương thức create. Và bạn có thể sử dụng đối tượng site để truy cập tất cả các trang, bài đăng và các tài nguyên khác của bạn.

Trong ví dụ dưới đây, chúng tôi tạo một trình tạo lặp qua tất cả các trang và in ra tiêu đề của chúng.

class MySubnavGenerator < Jekyll::Generator
  def generate(site)
    site.pages.each do |page|
      puts page.data["title"]
    end
  end
end

Chúng tôi cũng có thể sửa đổi dữ liệu trang và trang web bên trong trình tạo - dữ liệu được tải từ vật chất phía trước và từ tệp cấu hình trang web.

   page.data["title"] += " - modified!"
   site.data["tagline"]

Đánh dấu hiển thị trước cho HTML

Chúng tôi muốn trích xuất các tiêu đề từ các tài liệu đánh dấu của chúng tôi. Cách đơn giản nhất để làm điều này là chuyển đổi đánh dấu sang HTML sau đó phân tích cú pháp HTML bằng một công cụ như nokogiri.

Điều này có làm cho tôi cảm thấy một chút bẩn? Chuẩn rồi. Nó sẽ hơi chậm? Chắc chắn rồi. Nhưng vì Jekyll là một trình tạo trang web tĩnh, tôi không phải lo lắng về hiệu suất thời gian thực. Vì vậy, tôi sẽ chỉ giữ mũi của mình và hoàn thành nó.

Ở đây, chúng tôi sử dụng trình bao bọc đánh dấu tích hợp sẵn của Jekyll để chuyển đổi mọi trang đánh dấu sang HTML.

class MySubnavGenerator < Jekyll::Generator
  def generate(site)
    parser = Jekyll::Converters::Markdown.new(site.config)

    site.pages.each do |page|
      if page.ext == ".md"
        html = parser.convert(page['content'])
        # Do something with the html here
      end
    end
  end
end

Trích xuất các tiêu đề

Đối với trang web tài liệu mới của chúng tôi, tôi quyết định rằng mọi thẻ H2 phải có một liên kết điều hướng phụ tương ứng. Vì vậy, tôi sẽ sử dụng nokogiri để phân tích cú pháp HTML của mỗi trang, sau đó tôi sẽ tách từng thẻ H2 khỏi trang.

Hiện tại, chúng tôi sẽ chỉ in nội dung và ID của H2 ra màn hình:

require "nokogiri"

class MySubnavGenerator < Jekyll::Generator
  def generate(site)
    parser = Jekyll::Converters::Markdown.new(site.config)

    site.pages.each do |page|
      if page.ext == ".md"
        doc = Nokogiri::HTML(parser.convert(page['content']))
        doc.css('h2').each do |heading|
          puts "#{ heading.text }: #{ heading['id'] }"
        end
      end
    end
  end
end

Tạo menu Subnavigation

Bây giờ chúng ta đã có văn bản tiêu đề và ID, chúng ta có thể tạo danh sách các liên kết điều hướng phụ.

Chúng tôi sẽ lưu trữ danh sách các liên kết này như một thuộc tính dữ liệu của chính trang đó. Bằng cách đó, chúng tôi có thể truy cập các liên kết từ mẫu trang của chúng tôi.

require "nokogiri"

class MySubnavGenerator < Jekyll::Generator
  def generate(site)
    parser = Jekyll::Converters::Markdown.new(site.config)

    site.pages.each do |page|
      if page.ext == ".md"
        doc = Nokogiri::HTML(parser.convert(page['content']))
        page.data["subnav"] = []
        doc.css('h2').each do |heading|
          page.data["subnav"] << { "title" => heading.text, "url" => [page.url, heading['id']].join("#") }
        end
      end
    end
  end
end

Bây giờ, trong mẫu của bạn, bạn có thể lặp qua subnav và hiển thị từng liên kết:

{% for item in page.subnav %}
  <a href="{{ item.url }}">{{ item.title }}</a>
{% endfor %}

Khắc phục sự cố

Giống như tôi đã đề cập trước đây, tất cả điều này phụ thuộc vào bộ xử lý đánh dấu của bạn tạo ID duy nhất cho mỗi tiêu đề. Đây là cài đặt đánh dấu của tôi từ _config.yml :

# Use the redcarpet Markdown renderer
markdown: redcarpet
redcarpet:
    extensions: [
        'no_intra_emphasis',
        'fenced_code_blocks',
        'autolink',
        'strikethrough',
        'superscript',
        'with_toc_data',
        'tables',
        'hardwrap'
    ]

Tiếp theo ...

Cách tiếp cận trên hoạt động tốt nếu bạn chỉ cần một cấp độ phụ. Nhưng nếu bạn cần nhiều hơn? tức là nếu bạn muốn tất cả các thẻ H3 "bên trong" của H2 để tạo các liên kết điều hướng phụ trong menu của mình?

Chúng tôi sẽ đề cập đến vấn đề đó và hơn thế nữa trong một bài đăng trên blog trong tương lai. Vì vậy, hãy chú ý theo dõi!