Skip to content

Commit 433578d

Browse files
committed
feat: be more flexible with wildcard pages
1 parent cd98c96 commit 433578d

File tree

10 files changed

+553
-355
lines changed

10 files changed

+553
-355
lines changed

examples/wordpress/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
"dev": "WP_HOME=http://localhost:3000 smooth dev"
55
},
66
"dependencies": {
7+
"@loadable/babel-plugin": "^5.7.1",
78
"graphql-tag": "^2.10.1",
89
"react": "^16.8.2",
910
"react-dom": "^16.8.2",
11+
"smooth": "latest",
1012
"smooth-backend-wordpress": "latest",
11-
"smooth-plugin-head-meta": "latest",
12-
"smooth": "latest"
13+
"smooth-plugin-head-meta": "latest"
1314
},
1415
"resolutions": {
1516
"apollo-link-dedup": "1.0.15"

examples/wordpress/src/pages/foo$.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const PAGE = gql`
1313

1414
export default function Page() {
1515
const lang = useLang()
16-
throw new Error('kk')
1716
return (
1817
<>
1918
<div>Lang: {lang}</div>

examples/wordpress/src/pages/test$.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react'
2+
import gql from 'graphql-tag'
3+
4+
export const contentFragment = gql`
5+
fragment PageProps on Page {
6+
title
7+
}
8+
`
9+
10+
export default function Page({ title }) {
11+
return (
12+
<div>
13+
<h2>Title</h2>
14+
<div>{title}</div>
15+
</div>
16+
)
17+
}

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,25 @@
1515
},
1616
"devDependencies": {
1717
"@babel/cli": "^7.2.3",
18-
"@babel/core": "^7.3.4",
19-
"@babel/plugin-proposal-class-properties": "^7.3.4",
20-
"@babel/preset-env": "^7.3.4",
18+
"@babel/core": "^7.4.0",
19+
"@babel/plugin-proposal-class-properties": "^7.4.0",
20+
"@babel/preset-env": "^7.4.1",
2121
"@babel/preset-react": "^7.0.0",
22-
"@loadable/babel-plugin": "^5.7.0",
22+
"@loadable/babel-plugin": "^5.7.2",
2323
"babel-core": "^7.0.0-bridge.0",
2424
"babel-eslint": "^10.0.1",
2525
"babel-jest": "^24.5.0",
2626
"conventional-github-releaser": "^3.1.2",
2727
"cross-env": "^5.2.0",
2828
"doctoc": "^1.4.0",
29-
"eslint": "^5.15.1",
29+
"eslint": "^5.15.3",
3030
"eslint-config-airbnb": "^17.1.0",
3131
"eslint-config-prettier": "^4.1.0",
3232
"eslint-config-smooth": "^2.0.0",
3333
"eslint-plugin-import": "^2.16.0",
3434
"eslint-plugin-jsx-a11y": "^6.2.1",
3535
"eslint-plugin-react": "^7.12.4",
36-
"eslint-plugin-react-hooks": "^1.5.0",
36+
"eslint-plugin-react-hooks": "^1.5.1",
3737
"jest": "^24.5.0",
3838
"lerna": "^3.13.1",
3939
"prettier": "^1.16.4",

packages/smooth-dev-cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"react-dom": ">=16.3.0"
3333
},
3434
"dependencies": {
35-
"@babel/runtime": "^7.3.4",
35+
"@babel/runtime": "^7.4.0",
3636
"chokidar": "^2.1.2",
3737
"configstore": "^4.0.0",
3838
"fs-extra": "^7.0.1",

packages/smooth/package.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,24 @@
3333
"react-dom": ">=16.8.0"
3434
},
3535
"dependencies": {
36-
"@babel/core": "^7.3.4",
37-
"@babel/plugin-proposal-class-properties": "^7.3.4",
38-
"@babel/plugin-transform-runtime": "^7.3.4",
39-
"@babel/polyfill": "^7.2.5",
40-
"@babel/preset-env": "^7.3.4",
36+
"@babel/core": "^7.4.0",
37+
"@babel/plugin-proposal-class-properties": "^7.4.0",
38+
"@babel/plugin-transform-runtime": "^7.4.0",
39+
"@babel/polyfill": "^7.4.0",
40+
"@babel/preset-env": "^7.4.1",
4141
"@babel/preset-react": "^7.0.0",
42-
"@babel/register": "^7.0.0",
43-
"@babel/runtime": "^7.3.4",
42+
"@babel/register": "^7.4.0",
43+
"@babel/runtime": "^7.4.0",
4444
"@emotion/core": "^10.0.9",
45-
"@loadable/babel-plugin": "^5.7.0",
45+
"@loadable/babel-plugin": "^5.7.2",
4646
"@loadable/component": "^5.7.0",
4747
"@loadable/server": "^5.7.0",
48-
"@loadable/webpack-plugin": "^5.7.0",
48+
"@loadable/webpack-plugin": "^5.7.1",
4949
"apollo-cache-inmemory": "^1.5.1",
5050
"apollo-client": "^2.5.1",
51-
"apollo-link": "^1.2.10",
52-
"apollo-link-http": "^1.5.13",
53-
"apollo-link-schema": "^1.2.1",
51+
"apollo-link": "^1.2.11",
52+
"apollo-link-http": "^1.5.14",
53+
"apollo-link-schema": "^1.2.2",
5454
"apollo-server-express": "^2.4.8",
5555
"axios": "^0.18.0",
5656
"babel-loader": "^8.0.5",
@@ -65,15 +65,15 @@
6565
"graphql-iso-date": "^3.6.1",
6666
"graphql-tag": "^2.10.1",
6767
"graphql-tools": "^4.0.4",
68-
"history": "^4.7.2",
68+
"history": "^4.9.0",
6969
"humanize-string": "^2.0.0",
7070
"merge-deep": "^3.0.2",
7171
"pluralize": "^7.0.0",
7272
"progress-estimator": "^0.2.2",
73-
"query-string": "^6.3.0",
73+
"query-string": "^6.4.0",
7474
"react-apollo": "^2.5.2",
7575
"react-helmet": "^5.2.0",
76-
"react-router-dom": "^4.3.1",
76+
"react-router-dom": "^5.0.0",
7777
"slugify": "^1.3.4",
7878
"tiny-glob": "^0.2.6",
7979
"webpack": "^4.29.6",

packages/smooth/src/babel/preset.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const nodeConfig = opts => ({
1515
{
1616
loose: true,
1717
useBuiltIns: 'entry',
18+
corejs: 'core-js@2',
1819
targets: {
1920
node: 'current',
2021
},
@@ -34,6 +35,7 @@ const webConfig = opts => ({
3435
modules: false,
3536
loose: true,
3637
useBuiltIns: 'entry',
38+
corejs: 'core-js@2',
3739
...opts['preset-env'],
3840
},
3941
],

packages/smooth/src/content/Query.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,17 @@ function Handler({ children, ...props }) {
5656
}
5757

5858
export function Query({ children }) {
59-
const {
60-
page,
61-
match: {
62-
params: { slug },
63-
},
64-
} = usePageContext()
59+
const { page } = usePageContext()
6560

66-
if (slug === 'index') {
61+
if (page.slug === 'index') {
6762
return <Redirect to={page.indexUrl} />
6863
}
6964

7065
return (
71-
<BaseQuery query={getQuery(page)} variables={{ slug: slug || 'index' }}>
66+
<BaseQuery
67+
query={getQuery(page)}
68+
variables={{ slug: page.slug || 'index' }}
69+
>
7270
{apolloProps => <Handler {...apolloProps}>{children}</Handler>}
7371
</BaseQuery>
7472
)

packages/smooth/src/page/Page.js

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,24 @@ function getIndexPath(isIndex, name) {
1313
return isIndex ? '/' : `/${name}`
1414
}
1515

16-
function getRoutePath(isIndex, isContent, name) {
17-
if (isContent) return isIndex ? '/:slug*' : `/${name}/:slug+`
16+
function getRoutePath(isIndex, isWildCard, name) {
17+
if (isWildCard) return isIndex ? '/:slug*' : `/${name}/:slug+`
1818
return getIndexPath(isIndex, name)
1919
}
2020

2121
function getPage(filePath) {
2222
const rawName = getFileName(filePath)
23-
const isContent = !rawName.endsWith('$')
23+
const isWildCard = !rawName.endsWith('$')
2424
const name = rawName.replace('$', '')
2525
const isIndex = name === 'index'
2626
const indexPath = getIndexPath(isIndex, name)
27-
const routePath = getRoutePath(isIndex, isContent, name)
27+
const routePath = getRoutePath(isIndex, isWildCard, name)
2828
const LoadableComponent = loadable.lib(() =>
2929
import(`__smooth_pages/${rawName}`),
3030
)
3131
return {
3232
isIndex,
33-
isContent,
33+
isWildCard,
3434
indexPath,
3535
routePath,
3636
filePath,
@@ -40,11 +40,11 @@ function getPage(filePath) {
4040

4141
// First content, then indexes
4242
function sortPages(a, b) {
43-
if (a.isContent === b.isContent) {
43+
if (a.isWildCard === b.isWildCard) {
4444
if (a.isIndex === b.isIndex) return 0
4545
return a.isIndex < b.isIndex ? -1 : 1
4646
}
47-
return a.isContent < b.isContent ? -1 : 1
47+
return a.isWildCard < b.isWildCard ? -1 : 1
4848
}
4949

5050
export function getPages() {
@@ -55,6 +55,56 @@ export function getPages() {
5555
.sort(sortPages)
5656
}
5757

58+
function getContentSlug({ match, history, location, pageRef }) {
59+
const { module: pageModule } = pageRef.current
60+
61+
if (match.params.slug === undefined) {
62+
if (!pageModule.contentSlug) {
63+
return pageRef.current.routePath.replace(/^\//, '')
64+
}
65+
return typeof pageModule.contentSlug === 'function'
66+
? pageModule.contentSlug({ history, location })
67+
: pageModule.contentSlug
68+
}
69+
70+
return match.params.slug
71+
}
72+
73+
function enrichPageRef(
74+
pageRef,
75+
{ module: pageModule, indexUrl, match, history, location },
76+
) {
77+
const isContent = Boolean(pageModule.contentFragment)
78+
pageRef.current.module = pageModule
79+
pageRef.current.isContent = isContent
80+
pageRef.current.indexUrl = indexUrl
81+
82+
if (isContent) {
83+
pageRef.current.slug = getContentSlug({ match, history, location, pageRef })
84+
}
85+
86+
if (
87+
isContent &&
88+
!pageRef.current.ContentComponent &&
89+
!pageRef.current.PageComponent
90+
) {
91+
const ContentComponent = props => {
92+
const Component = pageRef.current.module.default
93+
const element = <Component {...props} />
94+
return applyHook('wrapContentElement', { element, props }, 'element')
95+
}
96+
const PageComponent = () => <Content Component={ContentComponent} />
97+
pageRef.current.ContentComponent = ContentComponent
98+
pageRef.current.PageComponent = PageComponent
99+
} else {
100+
pageRef.current.PageComponent = pageModule.default
101+
}
102+
}
103+
104+
function usePageRef(page) {
105+
return useRef({ ...page })
106+
}
107+
58108
export default function Page({
59109
page,
60110
lang,
@@ -63,42 +113,29 @@ export default function Page({
63113
match,
64114
location,
65115
}) {
66-
const PageComponent = useRef()
67-
const ContentComponent = useRef()
116+
const pageRef = usePageRef(page)
68117
return (
69118
<page.LoadableComponent>
70119
{pageModule => {
71-
if (page.isContent) {
72-
ContentComponent.current =
73-
ContentComponent.current ||
74-
(props => {
75-
const Component = pageModule.default
76-
const element = <Component {...props} />
77-
return applyHook(
78-
'wrapContentElement',
79-
{ element, props },
80-
'element',
81-
)
82-
})
83-
84-
PageComponent.current =
85-
PageComponent.current ||
86-
(() => <Content Component={ContentComponent.current} />)
87-
} else {
88-
PageComponent.current = pageModule.default
89-
}
120+
enrichPageRef(pageRef, {
121+
module: pageModule,
122+
indexUrl,
123+
match,
124+
history,
125+
location,
126+
})
90127

91128
const pageContext = {
92129
lang,
93-
page: { ...page, module: pageModule, indexUrl },
130+
page: pageRef.current,
94131
history,
95132
match,
96133
location,
97134
}
98135

99136
return (
100137
<PageContextProvider context={pageContext}>
101-
<App {...pageContext} Component={PageComponent.current} />
138+
<App {...pageContext} Component={pageRef.current.PageComponent} />
102139
</PageContextProvider>
103140
)
104141
}}

0 commit comments

Comments
 (0)