Created
February 8, 2024 09:05
-
-
Save CemraJC/8438a616740162661a9958c46c95315d to your computer and use it in GitHub Desktop.
Wiki.JS Version 2 - Dynamic Page Structure / TOC Generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
// ^^^ | |
// Keep the <script> tags when copying into Wiki.JS page editor | |
async function fetchAllPages() { | |
const graphqlEndpoint = "/graphql"; | |
const query = ` | |
query GetAllPages { | |
pages{ | |
list(limit: 1000, orderBy: PATH, orderByDirection: ASC) { | |
id | |
path | |
locale | |
title | |
createdAt | |
updatedAt | |
} | |
} | |
} | |
`; | |
try { | |
const response = await fetch(graphqlEndpoint, { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ query }) | |
}); | |
if (!response.ok) { | |
throw new Error(`Network error: ${response.statusText}`); | |
} | |
const jsonResponse = await response.json(); | |
console.log(jsonResponse.data) | |
return jsonResponse.data.pages.list; | |
} catch (error) { | |
console.error('Fetching all pages failed:', error); | |
return []; // Return an empty array on failure | |
} | |
} | |
function generateTree(pages) { | |
const root = { children: [] }; | |
pages.forEach(page => { | |
const parts = page.path.split('/').filter(Boolean); // Split path and remove empty parts | |
let current = root; | |
parts.forEach((part, index) => { | |
let child = current.children.find(child => child.name === part); | |
if (!child) { | |
child = { name: part, children: [], page: null }; | |
current.children.push(child); | |
} | |
current = child; | |
}); | |
current.page = page; // Assign the page to the last node | |
}); | |
return root; | |
} | |
function buildHtmlFromTree(node) { | |
if (node.children.length === 0) { | |
return ''; | |
} | |
let html = '<ul>'; | |
node.children.forEach(child => { | |
const pageLink = child.page ? ` <a href="/en/${child.page.path}">${child.page.title}</a>` : child.name; | |
html += `<li>${pageLink}${buildHtmlFromTree(child)}</li>`; | |
}); | |
html += '</ul>'; | |
return html; | |
} | |
function removeElement(id) { | |
var elem = document.getElementById(id); | |
return elem.parentNode.removeChild(elem); | |
} | |
async function displayPageTree() { | |
try { | |
const pages = await fetchAllPages(); | |
// Check if the pages array is empty right after fetching | |
if (pages.length === 0) { | |
document.getElementById('loadingMessage').innerHTML = '<p>No pages found.</p>'; | |
return; | |
} | |
const treeRoot = generateTree(pages); | |
// Check if the generated tree has no children | |
// (i.e., is effectively empty - this may happen on algorithmic error | |
// with the tree generator, even if the pages list has pages in it) | |
if (treeRoot.children.length === 0) { | |
document.getElementById('loadingMessage').innerHTML = '<p>The tree could not be built.</p>'; | |
return; | |
} | |
const treeHtml = buildHtmlFromTree(treeRoot); | |
document.getElementById('pageTree').innerHTML = treeHtml; | |
removeElement('loadingMessage'); | |
} catch (error) { | |
console.error('Error displaying page tree:', error); | |
document.getElementById('loadingMessage').innerHTML = '<p>Failed to load the page tree. Please try again later.</p>'; | |
} | |
} | |
window.boot.register('page-ready', () => { | |
displayPageTree(); | |
}); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- This file should be the main page content (you need to use the Raw HTML editor) --> | |
<h1>Site Structure</h1> | |
<p>The following section shows the entire heirarchy of this wiki.</p> | |
<hr/> | |
<div id="pageTree">Loading pages...</div> | |
<br/> | |
<br/> | |
<br/> | |
<br/> | |
<br/> | |
<i id="loadingMessage">If you are reading this, it probably should have loaded by now...</i> | |
<hr/> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for sharing!
I've based on this gist to generate virtual folders index dynamically 🎉
I've made a few changes to how HTML is structured, using h2 tags and sections. I've also limited the displayed results to those that start with the same path as the current one