목차를 보기 좋게 Ghost에서 Tocbot을 사용해보자

목차를 보기 좋게 Ghost에서 Tocbot을 사용해보자

Tocbot을 사용하면 제목을 기반으로 목차를 자동으로 생성해준다.

간단한 코드 만으로 구현이 가능해서 손쉽게 사용할 수 있다.


테마 수정하기

자신이 사용 중인 테마를 다운로드 받은 다음에 post.hbs 파일을 수정한다.

{{content}} 바로 위에

<aside class="gh-sidebar"><div class="gh-toc"></div></aside> 를 추가한다.

<section class="gh-content gh-canvas">
  {{! The TOC will be inserted here }}
  <aside class="gh-sidebar"><div class="gh-toc"></div></aside>
  
  {{content}}
</section>

post.hbs

사용 중인 테마의 {{content}}를 감싸고 있는 태그 클래스명를 확인한다.

테마 수정이 끝났으면 테마를 재빌드 해야 한다.

npm install 명령어를 실행하고 완료가 되면 npm run zip을 실행한다.

⚠️
npm error code ERESOLVE
npm error ERESOLVE could not resolve

오류가 뜬다면 --force 옵션을 추가한다.

완료가 되면 dist 폴더에 생긴 테마 압축 파일을 업로드한다.


Code injection 수정하기

Tocbot JS와 CSS를 불러와야 한다.

Site header 설정하기

Settings  Code injection  Site header에 다음을 추가한다.

<!-- Tocbot CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.32.2/tocbot.css">

Site header

추가적인 CSS 스타일 필요하다면 수정한다.

아래는 이 블로그에 적용된 스타일이다.

<!-- Tocbot Additional Styles -->
<style>
  .gh-content {
    position: relative;
    grid-template-columns: [full-start] minmax(4vw,auto) [wide-start] minmax(auto,290px) [main-start] min(720px,calc(100% - 8vw)) [main-end] minmax(auto,290px) [wide-end] minmax(4vw,auto) [full-end];
  }
  
  .gh-toc > .toc-list {
    position: relative;
  }
  
  .toc-list {
    overflow: hidden;
    list-style: none;
    padding-left: 0;
  }
  
  .toc-list > .toc-list-item {
    padding-left: 0;
  }

  .toc-list > .toc-list-item > .toc-list {
    padding-left: 35px;
  }
  
  .toc-list-item > a {
    text-decoration: none;
  }
  
  .toc-link::before {
    content: none;
  }
  
  .is-collapsible {
    overflow: hidden;
    max-height: 1000px;
    transition: all 0.5s cubic-bezier(1, 0, 1, 0);
  }
  
  .is-collapsed {
    max-height: 0;
    transition: all 0.5s cubic-bezier(0, 1, 0, 1);
  }

  @media (min-width: 1300px) {
    .gh-sidebar {
      position: absolute;
      top: 0;
      bottom: 0;
      margin-top: 4vmin;
      grid-column: wide-start / main-start; /* Place the TOC to the left of the content */
    }

    .gh-toc {
      position: sticky; /* On larger screens, TOC will stay in the same spot on the page */
      top: 4vmin;
      font-size: 1.5rem;
    }

    .gh-toc::before {
      content: "On this page";
      display: flex;
      font-weight: bold;
      margin-bottom: 12px;
    }
  }
</style>

Settings  Code injection  Site footer에 다음을 추가한다.

<!-- Tocbot JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.32.2/tocbot.min.js"></script>

<!-- Initialize Tocbot after you load the script -->
<script>
  // Change header IDs to toc-head-
  let id = 1;
  $('.gh-content').children('h1, h2, h3, h4').each(function () {
      let hyphenated = 'toc-head-' + id;
      $(this).attr('id', hyphenated);
      id++;
  });
  
  tocbot.init({
    // Where to render the table of contents.
    tocSelector: '.gh-toc',
    // Where to grab the headings to build the table of contents.
    contentSelector: '.gh-content',
    // Which headings to grab inside of the contentSelector element.
    headingSelector: 'h1, h2, h3, h4',
    // How many heading levels should not be collapsed.
    collapseDepth: 3, // 0~6
    // For headings inside relative or absolute positioned containers within content.
    hasInnerContainers: true,
    // To handle fixed headers with tocbot. For example, the options needed for a 40px
    headingsOffset: 40,
    scrollSmoothOffset: -40
  });
</script>

Site footer

💡
.gh-content 는 테마마다 다를 수 있으므로 자신이 사용 중인 테마에 맞게 수정이 필요하다.

헤더 ID를 변경하는 이유는 영어가 아닌 문자를 사용하면 인코딩을 해서 문제가 발생하기 때문이다.

참조

How to add a table of contents to your Ghost site
Let your readers know what to expect in your posts and give them quick links to navigate content quickly by adding a table of contents with the Tocbot library.

Ghost Tocbot

GitHub - tscanlin/tocbot: Build a table of contents from headings in an HTML document.
Build a table of contents from headings in an HTML document. - tscanlin/tocbot

Tocbot Github

Seems not support non English title? · Issue #81 · tscanlin/tocbot
It’s unable to jump to a element with a Chinese (uft-8) id like <a href=”#第一章”>第一章</a> and <h1 id=”第一章”>第一章<h1> You may see it Here I guess it maybe href to id itself not support utf-8 characters,…

Seems not support non English title?