Skip to content

Commit

Permalink
Merge pull request #34 from hlxsites/developers-toc
Browse files Browse the repository at this point in the history
docs.raqn.io: adding basic table of content for developers content
  • Loading branch information
nc-andreashaller authored Sep 6, 2024
2 parents 77da2bb + 61abdf4 commit 14008a5
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 0 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tools/importer/helix-importer-ui/*
6 changes: 6 additions & 0 deletions blocks/developers-content/developers-content.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
raqn-developers-toc h2,
raqn-developers-toc h3 {
margin: 10px;
color: var(--scope-color);
font-size: var(--scope-font-size, 1.3em);
}
150 changes: 150 additions & 0 deletions blocks/developers-content/developers-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import ComponentBase from '../../scripts/component-base.js';

const sitePathPrefix = 'developers';

export default class DeveloperToc extends ComponentBase {
static loaderConfig = {
...ComponentBase.loaderConfig,
targetsSelectors: 'main > div:first-child',
targetsSelectorsLimit: 1,
};

extendConfig() {
return [
...super.extendConfig(),
{
contentFromTargets: false,
addToTargetMethod: 'replaceWith',
targetsAsContainers: {
addToTargetMethod: 'prepend',
contentFromTargets: false,
},
},
];
}

ready() {
this.generateTablesOfContent();
}

isIndex(node) {
return node.page && (node.segment === 'README' || node.segment === 'readme');
}

toLink(path) {
if(window.location.host.startsWith('localhost') || window.location.host.search(/\.aem\.(page|live)/) > 0) {
return path;
}
return `/${sitePathPrefix}${path}`;
}

async loadPageHierarchy() {
const response = await fetch(`/${sitePathPrefix}/query-index.json`);
if(!response.ok) return [];
const json = await response.json();

const pageHierarchy = [];
const pageHierarchyObject = { children:pageHierarchy };
let currentNode;
json.data.forEach(page => {
const segments = page.path.split('/').slice(1);
let currentParent = pageHierarchyObject;
let nodePath = '';
segments.forEach((segment) => {
nodePath += `/${segment}`;
let node = currentParent.children.find((child) => child.segment === segment);
if (!node) {
node = {
nodePath,
segment,
active: window.location.pathname.startsWith(nodePath),
children: [],
};
if(nodePath === page.path) {
node.page = page;
if(this.isIndex(node)) {
currentParent.link = page.path;
}
if(!currentNode && node.active) {
currentNode = node;
}
}
currentParent.children.push(node);
}
currentParent = node;
});
});

const postProcessHierarchy = (node) => {
node.children.sort((a, b) => a.segment.localeCompare(b.segment));
if(!node.page && !node.link) {
const firstChildPage = node.children.find((child) => child.page);
if(firstChildPage) {
node.link = firstChildPage.page.path;
}
}
node.children.forEach((child) => postProcessHierarchy(child));
};
postProcessHierarchy(pageHierarchyObject);

return [pageHierarchy, currentNode];
}

generateRepository(repository) {
const a = document.createElement('a');
a.href = this.toLink(repository.link);
a.innerText = repository.segment;
return `<li class=${repository.active ? 'active' : ''}><h3>${a.outerHTML}</h3>`;
}

generateProjects(org) {
return org.children.map((project) => {
const h2 = document.createElement('h2');
h2.innerText = `${org.segment} - ${project.segment}`;
return `<li class=${project.active ? 'active' : ''}>${h2.outerHTML}
<ul>${ project.children.map((repository) => this.generateRepository(repository)).join('')}</ul></li>`;
}).join('');
}

generatePages(node) {
if(this.isIndex(node)) return '';

const link = node.link || node.page?.path;
const li = document.createElement('li');
if(link) {
const a = document.createElement('a');
a.href = this.toLink(link);
a.innerText = node.segment;
li.innerHTML = a.outerHTML;
} else {
li.innerText = node.segment;
}

const childrenHTML = node.children.map((child) => this.generatePages(child)).join('');
if(childrenHTML) {
const ul = document.createElement('ul');
ul.innerHTML = childrenHTML;
li.appendChild(ul);
}

return li.outerHTML;
}

async generateTablesOfContent() {
const [pageHierarchy, currentNode] = await this.loadPageHierarchy();
const currentOrg = pageHierarchy.find((org) => org.active);
const currentProject = currentOrg?.children.find((project) => project.active);
const currentRepository = currentProject?.children.find((repository) => repository.active);

let tocs = `<ul class="main">${pageHierarchy.map((project) => this.generateProjects(project)).join('')}</ul>`;

if(currentRepository && currentNode) {
const h2 = document.createElement('h2');
h2.innerText = `${currentOrg.segment} - ${currentProject.segment} - ${currentRepository.segment}`;
tocs += `<hr><div class="active">${h2.outerHTML}
<ul>${currentRepository.children.map((child) => this.generatePages(child)).join('')}</ul></div>`;
}

this.innerHTML = tocs;
}
}
6 changes: 6 additions & 0 deletions scripts/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ export const onLoadComponents = {
componentName: name.trim(),
};
});
const template = getMeta(metaTags.template.metaName);
if(template) {
this.structureComponents = [...this.structureComponents, {
componentName: template,
}];
}
},

setLcpBlocks() {
Expand Down
4 changes: 4 additions & 0 deletions scripts/libs.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export const metaTags = {
metaNamePrefix: 'structure',
// contentType: 'boolean string',
},
template: {
metaName: 'structure',
// contentType: 'boolean string',
},
lcp: {
metaName: 'lcp',
fallbackContent: ['theming', 'header', 'breadcrumbs'],
Expand Down

0 comments on commit 14008a5

Please sign in to comment.