Skip to content

Commit

Permalink
Refactor Navigation for modification within a content/ directory. (#165)
Browse files Browse the repository at this point in the history
* Refactor Navigation for modification within a content/ directory.

* Add filter to weed out non-mdx files.

* Pare down content pages for easy duplication.
  • Loading branch information
mathewjordan authored Nov 28, 2023
1 parent 61630de commit e670c4c
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 170 deletions.
2 changes: 0 additions & 2 deletions canopy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const args = process.argv;

const config = buildConfig.getConfig(path);
const options = buildConfig.getOptions();
const navigation = buildConfig.getNavigation();
const { prod, dev } = config;

config.environment = args.includes("dev") ? dev : prod;
Expand All @@ -27,7 +26,6 @@ const args = process.argv;
const env = {
CANOPY_CONFIG: {
...config.environment,
navigation: navigation,
...config.options,
url,
basePath,
Expand Down
42 changes: 0 additions & 42 deletions config/.default/navigation.default.json

This file was deleted.

38 changes: 0 additions & 38 deletions config/navigation.sample.json

This file was deleted.

14 changes: 14 additions & 0 deletions content/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"path": "/works",
"text": "Works"
},
{
"path": "/metadata",
"text": "Metadata"
},
{
"path": "/about",
"text": "About"
}
]
22 changes: 22 additions & 0 deletions content/about/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"path": "/about",
"text": "About"
},
{
"path": "/about/documentation",
"text": "Documentation"
},
{
"path": "/about/example",
"text": "Markdown Example"
},
{
"path": "/about/another-example",
"text": "Another Example"
},
{
"path": "/about/history",
"text": "Project History"
}
]
17 changes: 1 addition & 16 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,14 @@ const {
PHASE_PRODUCTION_BUILD,
} = require("next/constants");

const {
getConfig,
getOptions,
getNavigation,
} = require("./src/lib/build/config.ts");
const { getConfig, getOptions } = require("./src/lib/build/config.ts");

module.exports = (phase) => {
const isDev = phase === PHASE_DEVELOPMENT_SERVER;
const isProd = phase === PHASE_PRODUCTION_BUILD;

const config = getConfig();
const options = getOptions();
const navigation = getNavigation();

navigation.primary = navigation.primary.filter((item) => {
switch (item.path) {
case "/map":
return options.map.enabled;
default:
return true;
}
});

const { prod, dev } = config;

Expand All @@ -42,7 +28,6 @@ module.exports = (phase) => {
const env = {
CANOPY_CONFIG: {
...config.environment,
navigation: navigation,
...config.options,
url,
basePath,
Expand Down
12 changes: 7 additions & 5 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ import Nav from "@components/Nav/Nav";
import Search from "@components/Search/Search";
import collections from "@.canopy/collections.json";
import { useCanopyState } from "@context/canopy";
import useNavigation from "@src/hooks/useNavigation";
import { useRouter } from "next/router";

// @ts-ignore
const navItems = process.env.CANOPY_CONFIG.navigation.primary;

const Header = () => {
const [showNav, setShowNav] = useState(false);
const router = useRouter();
const { pathname, query } = router;
const { canopyState } = useCanopyState();
const { headerVisible } = canopyState;

useEffect(() => setShowNav(false), [pathname, query]);
const { navigation } = useNavigation({ relativePath: "" });

useEffect(() => {
setShowNav(false);
}, [pathname, query]);

const handleShowNav = () => setShowNav(!showNav);

Expand All @@ -41,7 +43,7 @@ const Header = () => {
</ResponsiveActions>
<Actions showNav={showNav}>
<Search />
<Nav items={navItems} />
{navigation && <Nav items={navigation} />}
<Locale />
</Actions>
</Content>
Expand Down
27 changes: 17 additions & 10 deletions src/components/Layouts/Basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ import Nav from "@components/Nav/Nav";
import { NavigationItem } from "@customTypes/navigation";
import { getSlug } from "@lib/build/slug";
import { renderToStaticMarkup } from "react-dom/server";
import useNavigation from "@src/hooks/useNavigation";

const LayoutsBasic = ({ content, frontMatter }: LayoutFrontMatter) => {
// @ts-ignore
const navItems = process.env.CANOPY_CONFIG.navigation[
frontMatter.navigation
] as NavigationItem[];
// path relative to the `content/` directory
const navigationPath = frontMatter.navigation
? `${frontMatter.navigation}/`
: undefined;

const { navigation } = useNavigation({
relativePath: navigationPath,
});
const [subNavigation, setSubNavigation] = useState<NavigationItem[]>();

useEffect(() => {
Expand All @@ -39,15 +44,17 @@ const LayoutsBasic = ({ content, frontMatter }: LayoutFrontMatter) => {
<Layout>
<FrontMatterContext.Provider value={frontMatter}>
<Container containerType="wide">
<ContentWrapper aside={true}>
<ContentWrapper aside={Boolean(navigation)}>
{frontMatter.navigation && (
<AsideStyled>
<AsideFixedContent>
<Nav
items={navItems}
subNavigation={subNavigation}
orientation="vertical"
/>
{navigation && (
<Nav
items={navigation}
subNavigation={subNavigation}
orientation="vertical"
/>
)}
</AsideFixedContent>
</AsideStyled>
)}
Expand Down
7 changes: 5 additions & 2 deletions src/components/Nav/Nav.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ const Items = styled("div", {
vertical: {
flexDirection: "column",
alignItems: "flex-start",
padding: "0",
padding: "0 0 $gr4",

a: {
color: "$slate10",
padding: "$gr1 0 $gr2",
marginBottom: "0",

[`&.active`]: {
fontWeight: "800",
color: "$slate12 !important",
},

Expand Down Expand Up @@ -85,6 +84,10 @@ const Wrapper = styled("nav", {
padding: "0 $gr3",
borderLeft: "2px solid $slate4",

[`& ${Items}`]: {
paddingBottom: "0",
},

"a:first-child": {
paddingTop: 0,
},
Expand Down
56 changes: 56 additions & 0 deletions src/hooks/useNavigation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useEffect, useState } from "react";

import { NavigationItem } from "@src/customTypes/navigation";

const useNavigation = ({ relativePath }: { relativePath?: string }) => {
const [navigation, setNavigation] = useState<NavigationItem[]>();

useEffect(() => {
(async () => {
try {
if (typeof relativePath === "undefined") return;

const contentDirectory = "content/";
const directory = relativePath
? `${contentDirectory}${relativePath}`
: contentDirectory;

const data = await import(`../../${directory}_meta.json`);
const json: NavigationItem[] = transformObjectWithGetters(
data?.default
);

setNavigation(json);
} catch (error) {
console.warn(error);
console.warn("The relative _meta.json file could not be found.");
}
})();
}, []);

return { navigation };
};

function transformObjectWithGetters(obj: any) {
const result = Array.isArray(obj) ? [] : {};

for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const desc = Object.getOwnPropertyDescriptor(obj, key);
if (desc?.get) {
// @ts-ignore
result[key] = desc.get.call(obj);
} else {
// @ts-ignore
result[key] =
typeof obj[key] === "object" && obj[key] !== null
? transformObjectWithGetters(obj[key])
: obj[key];
}
}
}

return result as NavigationItem[];
}

export default useNavigation;
16 changes: 0 additions & 16 deletions src/lib/build/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,6 @@ const getConfig = (path = `./config/.default/canopy.default.json`) => {
return JSON.parse(config);
};

function getNavigation(path = `./config/.default/navigation.default.json`) {
const defaultNavigation = fs.readFileSync(path, {});

let data;
try {
data = fs.readFileSync(`./config/navigation.json`, {});
} catch (err) {
("Using default navigation for demonstration, please follow documentation for creating custom navigation.");
}

const navigation = data ? data : defaultNavigation;

return JSON.parse(navigation);
}

function getOptions(path = `./config/.default/options.default.json`) {
const defaultOptions = fs.readFileSync(path, {});

Expand All @@ -53,6 +38,5 @@ function getOptions(path = `./config/.default/options.default.json`) {

module.exports = {
getConfig,
getNavigation,
getOptions,
};
19 changes: 17 additions & 2 deletions src/lib/contentHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ async function getMarkdownContent({
`${slug}.mdx`
);
const fileContents = fs.readFileSync(filePath, "utf8");

const { content, data }: GrayMatterFile<string> = matter(fileContents);

// Prepare the source for MDXRemote
Expand All @@ -36,4 +35,20 @@ function getSlugFromFileName(fileName: string) {
return fileName.replace(/\.mdx$/, "");
}

export { getMarkdownContent, getSlugFromFileName };
function getMarkdownPaths(directory: string) {
const contentDirectoryPath = path.join(process.cwd(), `content/${directory}`);
const fileNames = fs.readdirSync(contentDirectoryPath);
return fileNames
.filter((filename: string) => {
return path.extname(filename).toLowerCase() === ".mdx";
})
.map((fileName: string) => {
return {
params: {
slug: getSlugFromFileName(fileName),
},
};
});
}

export { getMarkdownContent, getMarkdownPaths, getSlugFromFileName };
Loading

0 comments on commit e670c4c

Please sign in to comment.