Skip to content

Commit

Permalink
feat(gatsby): Extend support for file system pages to build client-on…
Browse files Browse the repository at this point in the history
…ly and collections of pages! (#25204)

* Implement unified routes

* Implement unified routes

* Unified Routes MVP!

* Unified Routes MVP!

* More progress deriving path

* rm

* fix relative imports in collection builder files

* A working implementation of showcase details

* Add support for client only routes

* Add support for client only routes

* change data to come on props.data

* Support params in collection routes

* Make gatsby build work

* bumping versions

* temp disable some stuff for navigation

* convert blog to use collection builder

* migrate theme-blog-core to collection builder

* pring program.directory

* fix root resolution

* ignore

* fix relative imports in themes

* rm

* update post.js from theme

* change data

* Support fragments in collection builder

* Support fragments in collection builder

* rm

* Changing functionality to support the external query approach

* revert a bunch of unneeded changes

* change www pages to new api

* progress

* some progress

* fix usage of nested queries and update the www example

* more typescript

* fix lint

* rm

* Change the dynamic keys to support [] and {}

* support renaming dynamic files and not crashing

* get-params to ts

* collection-query-builder to ts

* support mixing collection and dynamic routing

* rm

* clean up

* rm

* Support full queries

* ignore gatsby-admin for now, its broken

* Add e2e development tests

* add production tests

* a lot of clean up

* major cleanup for PR

* fix types

* fix more types

* fix test

* fix tests

* fix more tests

* fix windows test

* add babel/types

* fix more types

* fix production test

* fix development test

* fix production test

* windows compatibility!

* fix all tests (hopefully)

* fix tests

* fix latest windows test

* fix cypress test

* revert some unneccessary files

* undo mode change on gatsby-cli/cli.js

* revert file

* revert more

* fix windows support for collection params

* Improve props.params support

* fix lint issue

* remvoe unnecassary propType

* Add support for querying union values

* Move API to be marked as `unstable_`

* gatsby node to TS

* rm

* Add support for auto-slugified routes and query node paths

* fix an issue with services not working for me :(

* remove unstable_ prefix from e2e test files

* revert machine changes

* remove micromatch

* rename flag to GATSBY_EXPERIMENTAL_ROUTING_APIS

* fix lint
;

* fix tests

* add experimental flag to e2e tests

* -A

* Change API to use model in filepaths and unstable_collectionGraphql

* Change Model delmiter to period

* fix tests

* fix lint

* support slugs in slugify

* fix test

* clean up deps

* fix bug with prams for collection routes

* fix e2e test

* fix e2e dev test

* get rid of e2e test legacy usage of createPagesForData

* Fix tests

* fix test again for windows

* fix dev tets

* fix lint

* better error messaging for query issues

* fix test

* fix test

* Validate path query

* fix tests and lint

* fix lint

* Fix bug preventing usage of different file extensions

* dont crash on null fields

* Add features to telemetry

* update telemetry usage to proper api

* Several cleanups and minor fixes

* remove unused files

* Update packages/gatsby-plugin-page-creator/package.json

Co-authored-by: Ward Peeters <[email protected]>

* Update packages/gatsby-plugin-page-creator/src/gatsby-node.ts

Co-authored-by: Ward Peeters <[email protected]>

* Update packages/gatsby-plugin-page-creator/src/create-pages-from-collection-builder.ts

Co-authored-by: Ward Peeters <[email protected]>

* Address most of the feedback

* drop bluebird and switch to globby

* Extract regex uses into a common file

* fix lint

* fix tests

* Update packages/gatsby-plugin-page-creator/src/validate-path-query.ts

Co-authored-by: Ward Peeters <[email protected]>

* Update packages/gatsby-plugin-page-creator/src/path-utils.ts

Co-authored-by: Ward Peeters <[email protected]>

* Update packages/gatsby-plugin-page-creator/src/path-utils.ts

Co-authored-by: Ward Peeters <[email protected]>

* Add e2e test for union support and collectionGraphql usage

* fix breaking code from path.parse change

* fix snapshot

* use a stable method to only render 1 gatsby image collection route

Co-authored-by: Ward Peeters <[email protected]>
  • Loading branch information
blainekasten and wardpeet authored Aug 10, 2020
1 parent 04e71c6 commit 61d8849
Show file tree
Hide file tree
Showing 55 changed files with 1,885 additions and 150 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
describe(`client-side-routing`, () => {
beforeEach(() => {
cy.visit(`/`).waitForRouteChange()
})

it(`supports dynamic url segments`, () => {
cy.visit(`/client-dynamic-route/foo`).waitForRouteChange()

cy.getTestElement(`params`).invoke(`text`).should(`equal`, `foo`)
})

it(`supports splats`, () => {
cy.visit(`/client-dynamic-route/splat/blah/blah/blah`).waitForRouteChange()

cy.getTestElement(`splat`).invoke(`text`).should(`equal`, `blah/blah/blah`)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
describe(`collection-routing`, () => {
beforeEach(() => {
cy.visit(`/`).waitForRouteChange()
})

it(`can navigate to a collection route and see its content rendered`, () => {
cy.visit(`/collection-routing/root`).waitForRouteChange()

cy.getTestElement(`collection-routing-blog`)
.invoke(`attr`, `data-testslug`)
.then(slug => {
// should navigate us to an actual collection builder route.
cy.getTestElement(`collection-routing-blog`)
.first()
.click()
.waitForRouteChange()
.getTestElement(`slug`)
.invoke(`text`)
.should(`equal`, slug)
})
})

it(`can navigate to a collection route that uses unions and collectionGraphql query and see its content rendered`, () => {
cy.visit(`/collection-routing/root`).waitForRouteChange()

cy.getTestElement(`collection-routing-image`)
.invoke(`attr`, `data-testimagename`)
.then(name => {
// should navigate us to an actual collection builder route.
cy.getTestElement(`collection-routing-image`)
.first()
.click()
.waitForRouteChange()
.getTestElement(`name`)
.invoke(`text`)
.should(`equal`, name)
})
})
})
6 changes: 3 additions & 3 deletions e2e-tests/development-runtime/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ exports.onCreateNode = function onCreateNode({

createNodeField({
name: `slug`,
value: slug,
value: slug.replace("/", ""),
node,
})
break
Expand Down Expand Up @@ -59,10 +59,10 @@ exports.createPages = async function createPages({
data.posts.edges.forEach(({ node }) => {
const { slug } = node.fields
createPage({
path: slug,
path: `/${slug}`,
component: blogPostTemplate,
context: {
slug,
slug: slug,
},
})
})
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/development-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"license": "MIT",
"scripts": {
"build": "gatsby build",
"develop": "cross-env CYPRESS_SUPPORT=y ENABLE_GATSBY_REFRESH_ENDPOINT=true gatsby develop",
"develop": "cross-env GATSBY_EXPERIMENTAL_ROUTING_APIS=1 CYPRESS_SUPPORT=y ENABLE_GATSBY_REFRESH_ENDPOINT=true gatsby develop",
"serve": "gatsby serve",
"start": "npm run develop",
"format": "prettier --write \"src/**/*.js\"",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react"
import Layout from "../../components/layout"

export default props => (
<Layout>
<h1 data-testid="title">Client Dynamic Route</h1>
<h2 data-testid="params">{props.params.id}</h2>
</Layout>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react"
import Layout from "../../../components/layout"

export default props => (
<Layout>
<h1 data-testid="title">SPLAT!</h1>
<h2 data-testid="splat">{props.params["*"]}</h2>
</Layout>
)
65 changes: 65 additions & 0 deletions e2e-tests/development-runtime/src/pages/collection-routing/root.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from "react"
import { Link, graphql } from "gatsby"
import Layout from "../../components/layout"

export default function Root(props) {
return (
<Layout>
{props.data.markdown.nodes.map(node => {
return (
<Link
key={node.gatsbyPath}
to={node.gatsbyPath}
data-testid="collection-routing-blog"
data-testslug={node.fields.slug}
>
{node.frontmatter.title}
</Link>
)
})}
{props.data.images.nodes.map(node => {
return (
<Link
key={node.gatsbyPath}
to={node.gatsbyPath}
data-testid="collection-routing-image"
data-testimagename={node.parent.name}
>
{node.parent.name}
</Link>
)
})}
</Layout>
)
}

export const query = graphql`
query AllMarkdown {
markdown: allMarkdownRemark {
nodes {
frontmatter {
title
}
fields {
slug
}
gatsbyPath(
filePath: "/collection-routing/{MarkdownRemark.fields__slug}"
)
}
}
images: allImageSharp(limit: 1, skip: 1) {
nodes {
parent {
... on File {
name
}
}
gatsbyPath(
filePath: "/collection-routing/{ImageSharp.parent__(File)__name}"
)
}
}
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react"
import { Link, graphql, unstable_collectionGraphql } from "gatsby"
import Image from "gatsby-image"

import Layout from "../../components/layout"
import SEO from "../../components/seo"

export default function BlogPost({ data: { image } }) {
return (
<Layout>
<SEO title={image.parent.name} />
<h2 data-testid="name">{image.parent.name}</h2>
<Image fixed={image.fixed} />
<Link to="/">Back to home</Link>
</Layout>
)
}

export const blogPostQuery = graphql`
query BlogPostBySlugCollection($id: String!) {
image: imageSharp(id: { eq: $id }) {
fixed(width: 125, height: 125) {
...GatsbyImageSharpFixed
}
parent {
... on File {
name
}
}
}
}
`

// This should filter it down to just a single instance
export const collectionQuery = unstable_collectionGraphql`
{
allImageSharp(limit: 1, skip: 1) {
...CollectionPagesQueryFragment
}
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from "react"
import { Link, graphql } from "gatsby"

import Layout from "../../components/layout"
import SEO from "../../components/seo"

export default function BlogPost({ data: { post } }) {
return (
<Layout>
<SEO title={post.frontmatter.title} description={post.excerpt} />
<h1>{post.frontmatter.title}</h1>
<h2 data-testid="slug">{post.fields.slug}</h2>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
<Link to="/">Back to home</Link>
</Layout>
)
}

export const blogPostQuery = graphql`
query GetBlogPostBySlugCollection($id: String!) {
post: markdownRemark(id: { eq: $id }) {
fields {
slug
}
html
excerpt(pruneLength: 160)
frontmatter {
title
}
}
}
`
12 changes: 12 additions & 0 deletions e2e-tests/development-runtime/src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ const IndexPage = ({ data }) => (
<Link to="subdirectory/page-1" data-testid="subdir-link">
Go to subdirectory
</Link>
<Link to="collection-routing/root" data-testid="collection-link">
Go to collection routing
</Link>
<Link to="client-dynamic-route/foo" data-testid="client-dynamic-route-foo">
Go to dynamic route (id: foo)
</Link>
<Link
to="client-dynamic-route/splat/blah/blah/blah"
data-testid="client-dynamic-route-splat"
>
Go to client route splat (splat: blah/blah/blah)
</Link>
<h2>Blog posts</h2>
<ul>
{data.posts.edges.map(({ node }) => (
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/production-runtime/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# to use in frontend and don't leak if not used (secrets used in Node).
# You should NOT commit `.env` files to your repository for production sites.
EXISTING_VAR=foo bar
VERY_SECRET_VAR=it's a secret
VERY_SECRET_VAR=it's a secret
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
describe(`client-side-routing`, () => {
beforeEach(() => {
cy.visit(`/`).waitForRouteChange()
})

it(`supports dynamic url segments`, () => {
cy.visit(`/client-dynamic-route/foo`).waitForRouteChange()

cy.getTestElement(`params`).invoke(`text`).should(`equal`, `foo`)
})

it(`supports splats`, () => {
cy.visit(`/client-dynamic-route/splat/blah/blah/blah`).waitForRouteChange()

cy.getTestElement(`splat`).invoke(`text`).should(`equal`, `blah/blah/blah`)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
describe(`collection-routing`, () => {
beforeEach(() => {
cy.visit(`/`).waitForRouteChange()
})

it(`can navigate to a collection route and see its content rendered`, () => {
cy.visit(`/collection-routing/root`).waitForRouteChange()

cy.getTestElement(`collection-routing-blog`)
.invoke(`attr`, `data-testproductname`)
.then(name => {
// should navigate us to an actual collection builder route.
cy.getTestElement(`collection-routing-blog`)
.first()
.click()
.waitForRouteChange()

cy.getTestElement(`name`).invoke(`text`).should(`equal`, name)
})
})
})
28 changes: 28 additions & 0 deletions e2e-tests/production-runtime/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const path = require(`path`)
const fs = require(`fs-extra`)
const { createContentDigest } = require(`gatsby-core-utils`)

exports.onPreBootstrap = () => {
fs.copyFileSync(
Expand All @@ -8,6 +9,33 @@ exports.onPreBootstrap = () => {
)
}

exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions
const typeDefs = `
type Product implements Node {
name: String
}
`
createTypes(typeDefs)
}

const products = ["Burger", "Chicken"]

exports.sourceNodes = ({ actions, createNodeId }) => {
products.forEach((product, i) => {
actions.createNode({
id: createNodeId(i),
children: [],
parent: null,
internal: {
type: `Product`,
contentDigest: createContentDigest(product),
},
name: product,
})
})
}

exports.createPages = ({ actions: { createPage } }) => {
createPage({
path: `/안녕`,
Expand Down
4 changes: 2 additions & 2 deletions e2e-tests/production-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
],
"license": "MIT",
"scripts": {
"build": "cross-env CYPRESS_SUPPORT=y gatsby build",
"build:offline": "cross-env TEST_PLUGIN_OFFLINE=y CYPRESS_SUPPORT=y gatsby build",
"build": "cross-env GATSBY_EXPERIMENTAL_ROUTING_APIS=1 CYPRESS_SUPPORT=y gatsby build",
"build:offline": "cross-env GATSBY_EXPERIMENTAL_ROUTING_APIS=1 TEST_PLUGIN_OFFLINE=y CYPRESS_SUPPORT=y gatsby build",
"develop": "gatsby develop",
"format": "prettier --write '**/*.js'",
"serve": "gatsby serve",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react"
import Layout from "../../components/layout"

export default props => (
<Layout>
<h1 data-testid="title">Client Dynamic Route</h1>
<h2 data-testid="params">{props.params.id}</h2>
</Layout>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react"
import Layout from "../../../components/layout"

export default props => (
<Layout>
<h1 data-testid="title">SPLAT!</h1>
<h2 data-testid="splat">{props.params["*"]}</h2>
</Layout>
)
Loading

0 comments on commit 61d8849

Please sign in to comment.