Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Jekyll의 H2에서 자동으로 하위 탐색 생성

Jekyll의 H2에서 자동으로 하위 탐색 생성

저는 Jekyll을 사용하여 문서 사이트를 재구축했습니다. 문서 페이지가 꽤 크기 때문에 최상위 탐색 외에도 일종의 하위 탐색이 필요합니다.

이 게시물에서는 게시물 또는 페이지의 제목에서 하위 탐색 링크를 생성할 수 있는 간단한 Jekyll 플러그인을 만드는 방법을 다룹니다.

개요

이 프로젝트를 다음 작업으로 분류했습니다.

  1. 사이트의 모든 페이지에 대해 실행되는 Jekyll 생성기를 만듭니다.
  2. 제너레이터가 제목 정보를 추출할 수 있도록 페이지를 미리 렌더링하는 방법을 알려줍니다.
  3. nokogiri를 사용하여 페이지 HTML을 구문 분석하여 관련 제목과 콘텐츠를 추출합니다.
  4. 하위 탐색을 렌더링합니다.

아래 예에서 모든 subnav 링크는 앵커 링크입니다. 이 접근 방식이 작동하려면 마크다운 프로세서가 제목에 대한 ID를 생성하는지 확인해야 합니다. with_toc_data가 있는 RedCarpet 옵션이 잘 작동합니다.

기본 지킬 생성기

Jekyll용으로 만들 수 있는 몇 가지 다른 유형의 플러그인이 있습니다. 생성기를 만들 것입니다.

제너레이터는 단순히 Jekyll::Generator에서 상속되는 클래스입니다. generate라는 메소드를 제공합니다. .

제너레이터는 Jekyll이 모든 마크다운 파일을 로드한 후 그러나 해당 파일이 HTML로 변환되기 전에 실행됩니다. site 객체는 생성 메소드로 전달됩니다. 또한 사이트 개체를 사용하여 모든 사이트 페이지, 게시물 및 기타 리소스에 액세스할 수 있습니다.

아래 예에서는 모든 페이지를 순환하고 제목을 출력하는 생성기를 만듭니다.

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

또한 생성기 내부에서 페이지 및 사이트 데이터를 수정할 수 있습니다. 즉, 앞부분과 사이트 구성 파일에서 로드된 데이터입니다.

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

마크다운을 HTML로 사전 렌더링

마크다운 문서에서 제목을 추출하려고 합니다. 이를 수행하는 가장 간단한 방법은 마크다운을 HTML로 변환한 다음 nokogiri와 같은 도구를 사용하여 HTML을 구문 분석하는 것입니다.

이렇게 하면 약간 더러워지는 느낌이 들까요? 네. 좀 느릴까요? 전적으로. 하지만 Jekyll은 정적 사이트 생성기이므로 실시간 성능에 대해 걱정할 필요가 없습니다. 그래서 저는 그냥 코를 막고 끝내겠습니다.

여기에서는 Jekyll의 내장 마크다운 래퍼를 사용하여 모든 마크다운 페이지를 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

제목 추출

새 문서 사이트의 경우 모든 H2 태그에 해당하는 하위 탐색 링크가 있어야 한다고 결정했습니다. 따라서 nokogiri를 사용하여 각 페이지의 HTML을 구문 분석한 다음 페이지에서 각 H2 태그를 제거하겠습니다.

지금은 H2의 콘텐츠와 ID를 화면에 출력하겠습니다.

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

하위 탐색 메뉴 만들기

이제 제목 텍스트와 ID가 있으므로 하위 탐색 링크 목록을 만들 수 있습니다.

이 링크 목록을 페이지 자체의 데이터 속성으로 저장합니다. 그렇게 하면 페이지 템플릿의 링크에 액세스할 수 있습니다.

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

이제 템플릿에서 하위 탐색을 반복하고 각 링크를 표시할 수 있습니다.

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

문제 해결

앞서 언급했듯이 이것은 모두 각 제목에 대해 고유한 ID를 생성하는 마크다운 프로세서에 따라 다릅니다. 다음은 _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'
    ]

다음으로...

위의 접근 방식은 하위 탐색 수준이 하나만 필요한 경우 잘 작동합니다. 하지만 더 필요하다면? 즉, 메뉴에 하위 탐색 링크를 생성하기 위해 H2의 "내부"에 있는 모든 H3 태그를 원했다면?

향후 블로그 게시물에서 이에 대해 자세히 다루겠습니다. 그러니 계속 지켜봐 주세요!