diff --git a/gatsby-node.js b/gatsby-node.js
index af61f75..3aeeef5 100644
--- a/gatsby-node.js
+++ b/gatsby-node.js
@@ -12,7 +12,7 @@ const createSlug = (filePath, version) => {
.toLowerCase()
};
-exports.onCreateNode = async ({ node, getNode, getNodesByType, actions, createNodeId, createContentDigest }) => {
+exports.onCreateNode = async ({ node, getNode, getNodesByType, actions, createNodeId, createContentDigest }) => {
if (node.internal.type !== 'MarkdownRemark') {
return;
}
@@ -29,14 +29,14 @@ exports.onCreateNode = async ({ node, getNode, getNodesByType, actions, createNo
if (version.match(/^watcher--/)) {
const existing = getNodesByType('SilverstripeDocument')
.find(n => n.fileAbsolutePath === node.fileAbsolutePath);
-
+
if (existing) {
// Pair the document with its watched file so we can inject it into the template
// as a dependency.
existing.watchFile___NODE = node.id;
return;
- }
- }
+ }
+ }
const filePath = createFilePath({
node,
@@ -51,6 +51,7 @@ exports.onCreateNode = async ({ node, getNode, getNodesByType, actions, createNo
const docTitle = fileToTitle(fileTitle);
const slug = createSlug(filePath, version);
const parentSlug = `${path.resolve(slug, '../')}/`;
+ const unhideSelf = false;
const docData = {
isIndex,
@@ -58,7 +59,8 @@ exports.onCreateNode = async ({ node, getNode, getNodesByType, actions, createNo
fileTitle,
slug,
parentSlug,
- ...node.frontmatter,
+ unhideSelf,
+ ...node.frontmatter,
};
if (!docData.title || docData.title === '') {
@@ -72,7 +74,7 @@ exports.onCreateNode = async ({ node, getNode, getNodesByType, actions, createNo
rawMarkdownBody: node.rawMarkdownBody,
}),
};
- const nodeData = {
+ const nodeData = {
...node,
id: createNodeId(`SilverstripeDocument${node.id}`),
...docData,
@@ -95,7 +97,7 @@ exports.createPages = async ({ actions, graphql }) => {
slug
}
}
- }`);
+ }`);
if (result.errors) {
@@ -111,6 +113,6 @@ exports.createPages = async ({ actions, graphql }) => {
slug: node.slug,
}
});
- })
+ })
-};
+};
diff --git a/src/components/ChildrenOf.tsx b/src/components/ChildrenOf.tsx
index c0eccc6..e712342 100644
--- a/src/components/ChildrenOf.tsx
+++ b/src/components/ChildrenOf.tsx
@@ -11,7 +11,7 @@ const createCards = (children: SilverstripeDocument[]): ReactElement[] => {
-
+
{title}
@@ -28,7 +28,7 @@ const createCards = (children: SilverstripeDocument[]): ReactElement[] => {
};
const createList = (children: SilverstripeDocument[]): ReactElement[] => {
- return children.map(({ summary, slug, title }) => {
+ return children.map(({ summary, slug, title }) => {
return (
{title}
@@ -38,33 +38,40 @@ const createList = (children: SilverstripeDocument[]): ReactElement[] => {
});
};
-const ChildrenOf: StatelessComponent = ({ folderName, exclude, currentNode, asList }) => {
+const ChildrenOf: StatelessComponent = ({ folderName, exclude, only, currentNode, asList, includeFolders, reverse }) => {
if (!currentNode) {
return null;
}
- let children: ReactElement[] = [];
- if (!folderName && !exclude) {
- const sourceNodes = currentNode.isIndex ? getChildren(currentNode, false) : getSiblings(currentNode)
- children = asList ? createList(sourceNodes) : createCards(sourceNodes);
+
+ var nodes: SilverstripeDocument[] = [];
+
+ if (!folderName && !exclude && !only) {
+ nodes = currentNode.isIndex ? getChildren(currentNode, false) : getSiblings(currentNode)
+
} else if (folderName) {
const targetFolder = getChildren(currentNode, true).find(
child => child.isIndex && child.fileTitle.toLowerCase() === folderName.toLowerCase()
);
if (targetFolder) {
- children = asList
- ? createList(getChildren(targetFolder, false))
- : createCards(getChildren(targetFolder, false));
- } else {
- children = [];
+ nodes = getChildren(targetFolder, false);
}
} else if (exclude) {
const exclusions = exclude.split(',').map(e => e.toLowerCase());
- const nodes = getChildren(currentNode, false).filter(
+ nodes = getChildren(currentNode, includeFolders).filter(
child => !exclusions.includes(child.fileTitle.toLowerCase())
);
- children = asList ? createList(nodes) : createCards(nodes);
+ } else if (only) {
+ const inclusions = only.split(',').map(e => e.toLowerCase());
+ nodes = getChildren(currentNode, includeFolders).filter(
+ child => inclusions.includes(child.fileTitle.toLowerCase())
+ );
}
+ if (reverse) {
+ nodes.reverse();
+ }
+ let children: ReactElement[] = asList ? createList(nodes) : createCards(nodes);
+
return (
{asList &&
diff --git a/src/types/index.ts b/src/types/index.ts
index 1e0881a..7e9e02e 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -19,7 +19,7 @@ export interface SinglePage {
webLink: string;
}
}
- }
+ }
};
@@ -33,6 +33,7 @@ export interface SilverstripeDocument {
iconBrand?: string;
hideChildren?: boolean;
hideSelf?: boolean;
+ unhideSelf?: boolean;
parentSlug: string;
summary: string;
fileTitle: string;
@@ -48,6 +49,9 @@ export interface HierarchyQuery {
export interface ChildrenOfProps {
folderName?: string;
exclude?: string;
+ only?: string;
currentNode: SilverstripeDocument | null;
asList?: boolean;
+ includeFolders?: boolean;
+ reverse?: boolean;
};
diff --git a/src/utils/nodes.ts b/src/utils/nodes.ts
index 83d8208..45a8912 100644
--- a/src/utils/nodes.ts
+++ b/src/utils/nodes.ts
@@ -31,6 +31,7 @@ const getNodes = (): SilverstripeDocument[] => {
icon
iconBrand
hideChildren
+ unhideSelf
slug
parentSlug
fileTitle
@@ -49,9 +50,9 @@ const getNodes = (): SilverstripeDocument[] => {
/**
* Get the children of a given node
- *
+ *
* @param node
- * @param includeFolders
+ * @param includeFolders
*/
const getChildren = (
node: SilverstripeDocument,
@@ -75,8 +76,8 @@ const getChildren = (
/**
* Get children of a given node that should be shown in navigation
- *
- * @param node
+ *
+ * @param node
*/
const getNavChildren = (node: SilverstripeDocument): SilverstripeDocument[] => {
if (navChildrenMap.has(node.slug)) {
@@ -87,6 +88,8 @@ const getNavChildren = (node: SilverstripeDocument): SilverstripeDocument[] => {
children = getChildren(node, true).filter(n => !n.hideSelf);
}
+ getChildren(node, true).filter(n => n.unhideSelf).forEach(c => children.push(c));
+
navChildrenMap.set(node.slug, children);
return navChildrenMap.get(node.slug);
@@ -94,10 +97,10 @@ const getNavChildren = (node: SilverstripeDocument): SilverstripeDocument[] => {
/**
* Get the siblings of a given node
- *
- * @param node
+ *
+ * @param node
*/
-const getSiblings = (node: SilverstripeDocument): SilverstripeDocument[] => {
+const getSiblings = (node: SilverstripeDocument): SilverstripeDocument[] => {
if (siblingMap.has(node.slug)) {
return siblingMap.get(node.slug);
}
@@ -111,7 +114,7 @@ const getSiblings = (node: SilverstripeDocument): SilverstripeDocument[] => {
/**
* Get the parent of a given node
- * @param node
+ * @param node
*/
const getParent = (node: SilverstripeDocument): SilverstripeDocument | null => {
if (parentMap.has(node.slug)) {
@@ -154,7 +157,7 @@ const getCurrentVersion = (): string => __currentVersion || '4';
/**
* Set the current node by its slug.
- * @param slug
+ * @param slug
*/
const setCurrentNode = (slug: string): void => {
const currentNode = getNodes().find(n => n.slug === slug) || null;
diff --git a/src/utils/parseChildrenOf.ts b/src/utils/parseChildrenOf.ts
index bbb02e7..9800426 100644
--- a/src/utils/parseChildrenOf.ts
+++ b/src/utils/parseChildrenOf.ts
@@ -9,23 +9,38 @@ import { getCurrentNode } from '../utils/nodes';
const parseChildrenOf = (data: any): ReactElement|false => {
const currentNode = getCurrentNode();
let matches;
- matches = data.match(/\[CHILDREN(\sasList)?\]/);
- if (matches) {
- const asList = !!matches[1];
- return createElement(ChildrenOf, { currentNode, asList })
- }
matches = data.match(/\[CHILDREN Folder="?([A-Za-z0-9_<>\/]+)"?.*?\]/);
if (matches) {
const folderName = matches[1].replace(/<\/?em>/g, '_');
const asList = matches[0].match(' asList');
- return createElement(ChildrenOf, { folderName, currentNode, asList })
+ const includeFolders = matches[0].match(' includeFolders');
+ const reverse = matches[0].match(' reverse');
+ return createElement(ChildrenOf, { folderName, currentNode, asList, includeFolders, reverse })
}
matches = data.match(/\[CHILDREN Exclude="?([A-Za-z0-9_,]+)"?.*?\]/);
if (matches) {
const asList = matches[0].match(' asList');
+ const includeFolders = matches[0].match(' includeFolders');
+ const reverse = matches[0].match(' reverse');
const exclude = matches[1].replace(/<\/?em>/g, '_');
- return createElement(ChildrenOf, { exclude, currentNode, asList })
+ return createElement(ChildrenOf, { exclude, currentNode, asList, includeFolders, reverse })
+ }
+ matches = data.match(/\[CHILDREN Only="?([A-Za-z0-9_,]+)"?.*?\]/);
+ if (matches) {
+ const asList = matches[0].match(' asList');
+ const includeFolders = matches[0].match(' includeFolders');
+ const reverse = matches[0].match(' reverse');
+ const only = matches[1].replace(/<\/?em>/g, '_');
+ return createElement(ChildrenOf, { only, currentNode, asList, includeFolders, reverse })
+ }
+ matches = data.match(/\[CHILDREN(\sasList)?.*?\]/);
+ if (matches) {
+ const asList = !!matches[1];
+ const includeFolders = matches[0].match(' includeFolders');
+ const reverse = matches[0].match(' reverse');
+
+ return createElement(ChildrenOf, { currentNode, asList, includeFolders, reverse })
}
return false;