Reputation: 71
So I generate conditional layouts with this code:
exports.onCreatePage = ({ page, actions }) => {
const { createPage } = actions;
if (page.path.match(/about/)) {
page.context.layout = "special";
createPage(page);
}
if (page.path.match(/projects/)) {
page.context.layout = "projectsPage";
createPage(page);
}
};
I want to change the page.path.mathch(/projects/TO ALL PROJECT SLUGS/) but I can't write the correct syntax for the path.
Does anyone know how to get all the paths after the /projects/ ?
This is the full gatsby.node.js
const path = require("path");
const { createFilePath } = require(`gatsby-source-filesystem`);
exports.onCreatePage = ({ page, actions }) => {
const { createPage } = actions;
if (page.path.match(/about/)) {
page.context.layout = "special";
createPage(page);
}
if (page.path.match(/projects\/([^\/]+$)/)) {
page.context.layout = "projectsPage";
createPage(page);
}
};
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions;
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` });
createNodeField({
node,
name: `slug`,
value: slug,
});
}
};
exports.createPages = async function ({ graphql, actions }) {
const { data } = await graphql(`
query Projects {
allMarkdownRemark {
nodes {
frontmatter {
slug
}
}
}
}
`);
data.allMarkdownRemark.nodes.forEach((node) => {
const slug = node.frontmatter.slug;
actions.createPage({
path: "/projects/" + slug,
component: path.resolve("./src/templates/project-details.js"),
context: { slug: slug },
});
});
};
And this is my template:
import React from "react";
import { AnimatePresence, motion } from "framer-motion";
import Navbar from "../components/Navbar/Navbar";
import Footer from "../components/Footer/Footer";
import FooterAbout from "../components/Footer/FooterAbout";
const duration = 0.5;
const variants = {
initial: {
opacity: 0,
},
enter: {
opacity: 1,
transition: {
duration: duration,
delay: duration,
when: "beforeChildren",
},
},
exit: {
opacity: 0,
transition: { duration: duration },
},
};
export const Layout = ({ children, location, pageContext }) => {
if (pageContext.layout === "projectsPage") {
return (
<main className="bg-black ">
<AnimatePresence>
<motion.main
key={location.pathname}
variants={variants}
initial="initial"
animate="enter"
exit="exit"
className="opacity-loader"
>
{children}
</motion.main>
</AnimatePresence>
</main>
);
}
if (pageContext.layout === "special") {
return (
<main className="bg-black ">
<Navbar />
<AnimatePresence>
<motion.main
key={location.pathname}
variants={variants}
initial="initial"
animate="enter"
exit="exit"
className="opacity-loader"
>
{children}
</motion.main>
</AnimatePresence>
<FooterAbout />
</main>
);
}
return (
<main className="bg-black ">
<Navbar />
<AnimatePresence>
<motion.main
key={location.pathname}
variants={variants}
initial="initial"
animate="enter"
exit="exit"
className="opacity-loader"
>
{children}
</motion.main>
</AnimatePresence>
<Footer />
</main>
);
};
export default Layout;
It seems like I am missing something, it accepts the (/projects/) path but not (/projects/([^/]+$)/).
To make it more clear I only want to disable the layout in the subdirectory pages of projects not in the /projects/ page.
Upvotes: 1
Views: 458
Reputation: 29320
You can use the following regular expression:
projects\/([^\/]+$)
This will match everything after /projects/
. So:
if (page.path.match(/projects\/([^\/]+$)/)) {
page.context.layout = "projectsPage";
createPage(page);
}
I've added a sandbox to test all scenarios: https://regex101.com/r/eQRJb4/1
Alternatively, you can try gatsby-plugin-create-client-paths
what makes exactly the same job automatically. In your case:
{
resolve: `gatsby-plugin-create-client-paths`,
options: { prefixes: [`/projects/*`] },
},
You can achieve the same result more easily like:
data.allMarkdownRemark.nodes.forEach((node) => {
const slug = node.frontmatter.slug;
actions.createPage({
path: "/projects/" + slug,
component: path.resolve("./src/templates/project-details.js"),
context: { slug: slug, layout: "projectsPage" },
});
});
Upvotes: 1