Advertisement
Guest User

Untitled

a guest
Feb 20th, 2020
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.50 KB | None | 0 0
  1. const path = require('path');
  2. const { createFilePath } = require('gatsby-source-filesystem');
  3.  
  4. const {
  5. getPathnameForMdxNode,
  6. getContentByCategory,
  7. } = require('./build-helpers/gatsby-node.helpers');
  8.  
  9.  
  10. const LEGACY_POST_SLUGS = [
  11. 'animating-the-unanimatable',
  12. 'dynamic-bezier-curves',
  13. 'effective-collaboration',
  14. 'folding-the-dom',
  15. 'rainbow-button',
  16. 'remote-work',
  17. 'remote-work-2',
  18. ];
  19.  
  20. const createPaginatedPage = ({
  21. content,
  22. rootPath,
  23. component,
  24. createPage,
  25. context = {},
  26. }) => {
  27. // Pagination!
  28. const numPages = Math.ceil(content.length / PAGE_SIZE);
  29.  
  30. Array.from({ length: numPages }).forEach((_, page) => {
  31. let pathname = rootPath;
  32.  
  33. if (page > 0) {
  34. pathname = `${pathname}/${page + 1}`;
  35. }
  36.  
  37. createPage({
  38. path: pathname,
  39. component,
  40. context: {
  41. limit: PAGE_SIZE,
  42. skip: page * PAGE_SIZE,
  43. numPages,
  44. currentPage: page + 1,
  45. ...context,
  46. },
  47. });
  48. });
  49. };
  50.  
  51.  
  52. /**
  53. * Many pages are created programmatically, including:
  54. * - Articles and tutorials themselves
  55. * - The "latest" page ('/latest', chronologically sorted list of all content)
  56. * - Category pages (eg. '/tutorials/react', including pagination)
  57. * - Root "tutorials" page ('/tutorials', shows top content from each
  58. * category)
  59. *
  60. * This is done so that I can have complete control over the pathnames (plus
  61. * you kinda have to do it this way for pagination).
  62. *
  63. * Also, I need to create redirects for all my legacy posts, so that links
  64. * don't break.
  65. */
  66. exports.createPages = async function({ actions, graphql }) {
  67. const { createPage, createRedirect } = actions;
  68.  
  69. const { data } = await graphql(`
  70. query {
  71. allMdx(
  72. sort: { fields: [frontmatter___publishedOn], order: DESC }
  73. limit: 1000
  74. ) {
  75. edges {
  76. node {
  77. id
  78. fields {
  79. slug
  80. }
  81. frontmatter {
  82. title
  83. isPublished
  84. publishedOn
  85. type
  86. abstract
  87. level
  88. categories
  89. interactive
  90. alwaysShowDate
  91. }
  92. }
  93. }
  94. }
  95. }
  96. `);
  97.  
  98. // Create individual pages, one for each category.
  99. const content = data.allMdx.edges.map(edge => edge.node);
  100.  
  101. content.forEach(item => {
  102. const { slug } = item.fields;
  103. const { categories } = item.frontmatter;
  104.  
  105. const firstCategory = categories[0];
  106.  
  107. categories.forEach(category => {
  108. const pathname = getPathnameForMdxNode(category, slug);
  109. const componentPath =
  110. item.frontmatter.type === 'tutorial'
  111. ? './src/components/TemplateTutorial/TemplateTutorial.js'
  112. : './src/components/TemplateArticle/TemplateArticle.js';
  113.  
  114. createPage({
  115. path: pathname,
  116. component: path.resolve(componentPath),
  117. context: {
  118. id: item.id,
  119. category,
  120. canonicalCategory: firstCategory,
  121. },
  122. });
  123. });
  124.  
  125. // If this is a legacy post, create a redirect at the old URL (/posts/:slug)
  126. const isLegacy = LEGACY_POST_SLUGS.includes(slug);
  127. if (isLegacy) {
  128. const [primaryCategory] = categories;
  129. const pathname = getPathnameForMdxNode(primaryCategory, slug);
  130.  
  131. createRedirect({
  132. fromPath: `/posts/${slug}`,
  133. isPermanent: true,
  134. redirectInBrowser: true, // TODO: try false?
  135. toPath: '/' + pathname,
  136. });
  137. }
  138. });
  139.  
  140. // Create the `/latest` page:
  141. // ALL CONTENT
  142. //
  143. // FUTURE: If I get >25 articles, should paginate this:
  144. // createPaginatedPage({
  145. // content,
  146. // rootPath: '/latest',
  147. // component: path.resolve(
  148. // './src/components/TemplateLatest/TemplateLatest.js'
  149. // ),
  150. // createPage,
  151. // });
  152. //
  153. createPage({
  154. path: '/latest',
  155. component: path.resolve(
  156. './src/components/TemplateLatest/TemplateLatest.js'
  157. ),
  158. context: {
  159. limit: 1000,
  160. skip: 0,
  161. },
  162. });
  163.  
  164. // Create the root '/tutorials' page:
  165. // (Tutorials and articles grouped by category)
  166. createPaginatedPage({
  167. content,
  168. rootPath: '/tutorials',
  169. component: path.resolve(
  170. './src/components/TemplateContentGrouped/TemplateContentGrouped.js'
  171. ),
  172. createPage,
  173. });
  174.  
  175. const contentByCategory = getContentByCategory(content);
  176.  
  177. // Create all the category pages
  178. // /category/:category
  179. Object.entries(contentByCategory).forEach(([category, childContent]) => {
  180. // Pagination!
  181. let rootPath = `/tutorials/${category}`;
  182.  
  183. createPaginatedPage({
  184. content: childContent,
  185. rootPath,
  186. component: path.resolve(
  187. './src/components/TemplateCategoryList/TemplateCategoryList.js'
  188. ),
  189. createPage,
  190. context: {
  191. category,
  192. },
  193. });
  194. });
  195. };
  196.  
  197. exports.onCreateNode = ({ node, actions, getNode }) => {
  198. const { createNodeField } = actions;
  199.  
  200. if (node.internal.type === `Mdx`) {
  201. // If we've manually specified a slug, use that.
  202. // Otherwise, generate one from the file path.
  203. const slug =
  204. node.frontmatter.slug ||
  205. createFilePath({ node, getNode })
  206. .replace(/^\//, '')
  207. .replace(/\/$/, '');
  208.  
  209. createNodeField({
  210. name: `slug`,
  211. node,
  212. value: slug,
  213. });
  214.  
  215. createNodeField({
  216. name: `pathname`,
  217. node,
  218. value: '/' + getPathnameForMdxNode(node.frontmatter.categories[0], slug),
  219. });
  220. }
  221. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement