Simo 2020/4/1
updated 2020/4/2
Nel mio caso specifico volevo inserire i pulsanti precedente e successivo negli articoli per facilitarne la consultazione.
Gatsbyjs ha un suo context specifico al quale è possibile accedervi tramite GraphQL.
Per chi non lo sapesse, il context sono delle informazioni personalizzate che un framework si porta dietro per essere usato nei vari componenti che ne hanno necessità.
Nello specifico, Gatsby ha un context interno, accessibile tramite le props (props.pageContext.tuocontext), che bisognerà valorizzare nella procedura onCreatePage dentro gatsby-node.js e sarà disponibile in tutte le pagine.
Fate riferimento a questa pagina del blog ufficiale per ulteriori dettagli, che dice tra le altre cose:
Siccome il context di Gatsby è serializzato prima di essere passato alle pagine, non si potranno passare delle funzioni ai componenti.
Nel file gatsby-node.js avevo già pronta la seguente procedura
1module.exports.createPages = async ({ graphql, actions }) => {
2 const { createPage } = actions
3 const blogTemplate = path.resolve("./src/templates/blog.js")
4 const res = await graphql(`
5 query {
6 allMarkdownRemark{
7 edges {
8 node {
9 fields {
10 slug
11 }
12 }
13 }
14 }
15 }
16 `)
17
18 const posts = res.data.allMarkdownRemark.edges
19
20 posts.forEach((edge, index) => {
21 createPage({
22 component: blogTemplate,
23 path: `/${edge.node.fields.slug}`,
24 context: {
25 slug: edge.node.fields.slug,
26 },
27 })
28 })
29}
Che ho modificato in
1module.exports.createPages = async ({ graphql, actions }) => {
2 const { createPage } = actions
3 const blogTemplate = path.resolve("./src/templates/blog.js")
4 const res = await graphql(`
5 query {
6 allMarkdownRemark(filter: {frontmatter: {update: {ne: null}, published: {eq: true}}}, sort: {fields: [frontmatter___update, frontmatter___date], order: ASC}) {
7 edges {
8 node {
9 fields {
10 slug
11 }
12 }
13 }
14 }
15 }
16 `)
17
18 const posts = res.data.allMarkdownRemark.edges
19
20 posts.forEach((edge, index) => {
21 const previous = index === 0 ? null : posts[index - 1].node
22 const next = index === posts.length - 1 ? null : posts[index + 1].node
23
24 createPage({
25 component: blogTemplate,
26 path: `/${edge.node.fields.slug}`,
27 context: {
28 slug: edge.node.fields.slug,
29 next,
30 previous,
31 },
32 })
33 })
34}
Ho dato un ordinamento per data ai post in allMarkdownRemark, controllando che next e previous non vadano fuori dal numero delle pagine e aggiungendo sempre le variabili next e previous con assegnati gli oggetti node al context nella procedura createPage.
Nel template delle pagine del blog ho aggiunto i pulsanti html valorizzati tramite props.pageContext
ho eliminato il codice dal file './src/templates/blog.js' che non è pertinente con l'articolo
1const Blog = props => {
2 var page_context = props.pageContext
3 ...
4 return (
5 ...
6 <div className="blog-post-nav">
7 <Link to={`/$page_context.previous == null ? "" : page_context.previous.fields.slug}`} className={page_context.previous || "hideme"}>
8 ‹ prev
9 </Link>
10 <Link to={`/$page_context.next == null ? "" : page_context.next.fields.slug}`} className={page_context.next || "hideme"}>
11 next ›
12 </Link>
13 </div>
14 ...
15 )
16}
-- Buona vita --