用于生成布局的 Gatsby 动态路由 URL
Gatsby Dynamic Routing URL for Generating Layouts
所以我用这段代码生成条件布局:
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);
}
};
我想更改 page.path.mathch(/projects/TO ALL PROJECT SLUGS/) 但我不能'没有写出正确的路径语法。
有谁知道如何获取 /projects/ 之后的所有路径?
这是完整的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 },
});
});
};
这是我的模板:
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;
我好像遗漏了什么,它接受 (/projects/) 路径但不接受 (/projects/([^/]+$)/)。
为了更清楚,我只想禁用不在 /projects/ 页面中的项目的子目录页面中的布局。
您可以使用以下正则表达式:
projects\/([^\/]+$)
这将匹配 /projects/
之后的所有内容。所以:
if (page.path.match(/projects\/([^\/]+$)/)) {
page.context.layout = "projectsPage";
createPage(page);
}
我添加了一个沙箱来测试所有场景:https://regex101.com/r/eQRJb4/1
或者,您可以尝试 gatsby-plugin-create-client-paths
自动完成完全相同的工作。在你的情况下:
{
resolve: `gatsby-plugin-create-client-paths`,
options: { prefixes: [`/projects/*`] },
},
您可以像这样更轻松地获得相同的结果:
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" },
});
});
所以我用这段代码生成条件布局:
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);
}
};
我想更改 page.path.mathch(/projects/TO ALL PROJECT SLUGS/) 但我不能'没有写出正确的路径语法。
有谁知道如何获取 /projects/ 之后的所有路径?
这是完整的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 },
});
});
};
这是我的模板:
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;
我好像遗漏了什么,它接受 (/projects/) 路径但不接受 (/projects/([^/]+$)/)。
为了更清楚,我只想禁用不在 /projects/ 页面中的项目的子目录页面中的布局。
您可以使用以下正则表达式:
projects\/([^\/]+$)
这将匹配 /projects/
之后的所有内容。所以:
if (page.path.match(/projects\/([^\/]+$)/)) {
page.context.layout = "projectsPage";
createPage(page);
}
我添加了一个沙箱来测试所有场景:https://regex101.com/r/eQRJb4/1
或者,您可以尝试 gatsby-plugin-create-client-paths
自动完成完全相同的工作。在你的情况下:
{
resolve: `gatsby-plugin-create-client-paths`,
options: { prefixes: [`/projects/*`] },
},
您可以像这样更轻松地获得相同的结果:
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" },
});
});