Table of Contents (TOC) v2 for your blog - Ghost

Table of Contents (TOC) v2 for your blog - Ghost
Photo by Clément Hélardot / Unsplash
UPD 05/25/2024: The gist was updated an now it fully supports multi-level h2...h6 tags
UPD 08/15/2024: Fixed the issue which you may saw in the browser console: TypeError: Cannot read properties of null (reading 'appendChild') at TOC.onLoad

Introduction

Hello. Using the previous version, I decided that creating a duplicate of such a script for each publication would be too much. So today, let's simplify the previous script a bit more and use it slightly differently.

The previous version explained the process of automating content creation itself. You can familiarize yourself with the idea and compare existing options here.

Automatic Table of Contents (TOC) for your blog - Ghost
🤟The table of contents of this publication was automatically generated using the solution described below Introduction As I added more and more posts to my blog, I began to realize just how much I was missing something as simple as a table of contents. The Ghost blogging platform doesn’t have

Update

The previous script consisted of three things:

  • Tag <toc> - it marked the place for adding the table of contents
  • Styles
  • JavaScript

Overall, the changes will be minor. And the first thing I started with was moving the title and making it a separate parameter of the tag itself, and now it should look like this:

<toc title="Table of Contents"></toc>

Accordingly, I removed a small settings object from the code, which improved the readability of the JavaScript code. Consequently, the addTitle method has changed.

Additionally, I completely moved the creation of styles to the script side. This is handled by the new addStyles method.

Support for multiple languages

And now I can solve my problem even more easily because previously I had to prepare either two different templates for each language - Ukrainian and English - or constantly change the title name in JavaScript, which I did.

Having the title attribute in the updated version allowed me to separate the <toc> tag itself and the styles from the script - both logically and physically.

Script deduplication

Fighting script duplication was a significant concern for me. With each new template insertion, the script and style were repeated, cluttering up the codebase. Regardless of where a new publication was stored in the database, it inevitably contained a copy of the script. This issue weighed heavily on my mind, as I foresaw it worsening over time.

I was aware that the script relied on document.addEventListener('DOMContentLoaded', () => {...}), which meant that if it were added to the footer of the blog, it would execute every time the page loaded. Since the Ghost blog reloads everything from scratch when switching to another page, it's not a Single Page Application (SPA), which actually worked to my advantage.

So, the solution I came up with was to include both the styles and the script in the footer of the blog. Having full control over the title using the title attribute, I saw no reason not to separate them.

It's worth emphasizing that consolidating the script in one location and only placing the <toc> tag in publications offers a significant advantage. Any subsequent changes to the script or styles will automatically apply to all publications, eliminating the need to manually update each one. Even after writing 20 articles, I found myself needing to revisit older posts to make modifications.

🤟
I want to emphasize and highlight that a significant advantage of having the script described in one place and only placing the <toc> tag in publications is that any changes to the script or styles will subsequently affect all your publications. You won't have to go back to old posts to update each one. Even after writing 20 articles, I've already encountered the need to go back to older ones and make changes.

Now I'll tell you what you need to do next.

Connection

To understand, I've sketched a diagram.

On the left, we see that in each publication, HTML code will now be added in the same way. However, unlike the previous version, we only need to add the <toc> tag itself as a container for the table of contents component. Here's an example.

<toc title="Table of Contents"></toc>

On the right side, I attempted to illustrate that using Code Injection, we need to add a script. Yes, it will be quite a bit of text in your footer section, but everything will always be located locally for you, ensuring stability under any circumstances.

Code Injection

By the way, read about Code Injection itself in the official documentation.

How to use Code Injection in Ghost
Code Injection is a powerful, convenient tool to add CSS, JS, and more to your Ghost site. Learn how to get the most out of it in this tutorial.

We've also used it before, here it is:

Code Snippets Style - Ghost
Introduction Hello. There have been pieces of code in several of my posts that appear quite dull against the background of other content, and unattractive compared to any other site where there is at least some code highlighting. Today we will fix that. The Ghost blog supports code, but I

I simplified everything to just adding the script to the footer section. Copy the entire content of the script along with the <script> tag and paste it at the very bottom of the footer section.

Save the changes and return to editing your posts. Now, for convenience, you need to create a template.

How to Use?

I highly recommend creating templates for all the languages you use. You can learn more about snippets in Ghost here:

Creating reusable snippets
Snippets allow any staff user to reuse content and cards across posts and pages. To save a snippet, highlight the content you’d like to transform into a template, then click the snippet icon in the toolbar to save your selection with a name. To insert a snippet into a new

Step 1. Creating a Template

As the author of your blog, in any post, add an HTML element and copy the <toc> tag into it.

Click outside the HTML element

And save it by adding a name like TOC (Table of Contents).

Step 2. Usage

With the template named TOC, all we need to do is open the post where we need the table of contents and insert it just like we added the HTML element, but now we need to look for TOC at the bottom of the list.

Everything is ready! Now, after publishing or previewing, you will see the table of contents generated based on your content. The main thing is not to forget to add your snippet each time at the beginning or wherever it is convenient for you.

For my own needs, I created snippets for different languages.

If you were curious (like me) about what magic happens after the script is executed, I specifically want to show you that styles were added to the <toc> tag using the addStyles method, and after that comes the .toc-container itself, which contains the title and links to the sections in the <nav> block. Each <li> tag represents a separate item. I didn't open them because there is a lot of text; take a look for yourself.


Conclusions

The updated version has several advantages compared to its predecessor:

  • Changing the style and the script itself can be done in one place, which is convenient and affects all previous publications at once.
  • The content of publications is not cluttered with a large script, and the template is now significantly smaller - we are talking exclusively about the size necessary to store the publication in the database.
  • Changing the title of the table of contents is now easier - in fact, we deal with only one line.
  • Styles were added as part of the script - without changing the functionality of adding the script to your blog, it has become simpler.

If I haven't convinced you yet, I don't know what you're looking for. Meanwhile, while you are considering options, I am already successfully using all this in my blog.

Read more