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

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

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


테마 수정하기

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

<aside class="gh-sidebar"><div class="gh-toc"></div></aside> 코드를

{{content}} 바로 위에 삽입한다.

<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

테마 수정 후에는 테마를 빌드해야 한다.

npm install 명령어를 실행하고 npm run zip을 실행한다.

dist 폴더에 생긴 테마 압축 파일을 업로드한다.

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

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


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

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

<!-- Tocbot Additional Styles -->
<style>
  .gh-sidebar {
    display: none;
  }
  
  .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);
  }

  /* 화면 넓이가 1300px 이상일 때만 목차 표시 */
  @media (min-width: 1300px) {
    .gh-sidebar {
      display: block;
      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>

Tocbot Additional Styles

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는 테마마다 다를 수 있으므로 자신이 사용 중인 테마에 맞게 수정이 필요하다.


참조

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?