Skip to content

Instantly share code, notes, and snippets.

@cloudfrl
Last active January 14, 2024 01:07
Show Gist options
  • Save cloudfrl/a26f384e05506395d02246c90f62f7ee to your computer and use it in GitHub Desktop.
Save cloudfrl/a26f384e05506395d02246c90f62f7ee to your computer and use it in GitHub Desktop.
Ghost Table of Contents
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.25.0/tocbot.min.js" integrity="sha512-P4MxNnVYFHmkj6ZlNusCPMjrqfYF7/AWRM0m7vEHkzTITuiW/6LaXk/Ah/mheuPI1xI80it2dP/8Nz+FLJT9MQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
const parent = document.querySelector(".gh-content.gh-canvas");
// Create the <aside> element
const asideElement = document.createElement("aside");
asideElement.setAttribute("class", "gh-sidebar");
//asideElement.style.zIndex = 0; // sent to back so it doesn't show on top of images
// Create the container div for title and TOC
const containerElement = document.createElement("div");
containerElement.setAttribute("class", "gh-toc-container");
// Create the title element
const titleElement = document.createElement("div");
titleElement.textContent = "Table of Contents";
titleElement.style.fontWeight = "bold";
containerElement.appendChild(titleElement);
// Create the <div> element for TOC
const divElement = document.createElement("div");
divElement.setAttribute("class", "gh-toc");
containerElement.appendChild(divElement);
// Append the <div> element to the <aside> element
asideElement.appendChild(containerElement);
parent.insertBefore(asideElement, parent.firstChild);
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',
// Ensure correct positioning
hasInnerContainers: true,
});
// Get the table of contents element
const toc = document.querySelector(".gh-toc");
const sidebar = document.querySelector(".gh-sidebar");
// Check the number of items in the table of contents
const tocItems = toc.querySelectorAll('li').length;
// Only show the table of contents if it has more than 5 items
if (tocItems > 2) {
sidebar.style.display = 'block';
} else {
sidebar.style.display = 'none';
}
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.25.0/tocbot.css" integrity="sha512-Di7Va5KC5NtXyMi+aEyVe2pUnniyhFoxfCrdCAOj8aSA42Te/bWKTz0iumaj5v1sN1nZdsaX8QTCn0k1nN4aLA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
.gh-content {
position: relative;
}
.gh-toc > .toc-list {
position: relative;
}
.toc-list {
overflow: hidden;
list-style: none;
}
@media (min-width: 1300px) {
.gh-sidebar {
position: absolute;
top: 0;
bottom: 0;
margin-top: 4vmin;
margin-left: 20px;
grid-column: wide-end / main-end; /* Place the TOC to the right of the content */
width: inline-block;
white-space: nowrap;
}
.gh-toc-container {
position: sticky; /* On larger screens, TOC will stay in the same spot on the page */
top: 4vmin;
}
}
.gh-toc .is-active-link::before {
background-color: var(--ghost-accent-color); /* Defines TOC accent color based on Accent color set in Ghost Admin */
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment