Skip to content

Commit 48a92c5

Browse files
committedApr 13, 2018
Moved versions control into versions.yml and Gatsby plug-in
1 parent 8e45c4b commit 48a92c5

File tree

7 files changed

+122
-20
lines changed

7 files changed

+122
-20
lines changed
 

‎content/versions.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
- title: '16.2.0'
2+
path: /version/16.2
3+
url: https://5abc31d8be40f1556f06c4be--reactjs.netlify.com
4+
- title: '16.1.1'
5+
path: /version/16.1
6+
url: https://5a1dbcf14c4b93299e65b9a9--reactjs.netlify.com
7+
- title: '16.0.0'
8+
path: /version/16.0
9+
url: https://5a046bf5a6188f4b8fa4938a--reactjs.netlify.com

‎gatsby-config.js

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module.exports = {
2020
'gatsby-source-react-error-codes',
2121
'gatsby-transformer-authors-yaml',
2222
'gatsby-transformer-home-example-code',
23+
'gatsby-transformer-versions-yaml',
2324
'gatsby-plugin-netlify',
2425
'gatsby-plugin-glamor',
2526
'gatsby-plugin-react-next',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
const {appendFile, exists, readFile, writeFile} = require('fs-extra');
2+
3+
const HEADER_COMMENT = `## Created with gatsby-transformer-versions-yaml`;
4+
5+
module.exports = async function writeRedirectsFile(redirects, publicFolder) {
6+
if (!redirects.length) {
7+
return null;
8+
}
9+
10+
const FILE_PATH = publicFolder(`_redirects`);
11+
12+
// Map redirect data to the format Netlify expects
13+
// https://www.netlify.com/docs/redirects/
14+
redirects = redirects.map(redirect => {
15+
const {
16+
fromPath,
17+
isPermanent,
18+
redirectInBrowser, // eslint-disable-line no-unused-vars
19+
toPath,
20+
...rest
21+
} = redirect;
22+
23+
// The order of the first 3 parameters is significant.
24+
// The order for rest params (key-value pairs) is arbitrary.
25+
const pieces = [
26+
fromPath,
27+
toPath,
28+
isPermanent ? 301 : 302, // Status
29+
];
30+
31+
for (let key in rest) {
32+
const value = rest[key];
33+
34+
if (typeof value === `string` && value.indexOf(` `) >= 0) {
35+
console.warn(
36+
`Invalid redirect value "${value}" specified for key "${key}". ` +
37+
`Values should not contain spaces.`,
38+
);
39+
} else {
40+
pieces.push(`${key}=${value}`);
41+
}
42+
}
43+
44+
return pieces.join(` `);
45+
});
46+
47+
let appendToFile = false;
48+
49+
// Websites may also have statically defined redirects
50+
// In that case we should append to them (not overwrite)
51+
// Make sure we aren't just looking at previous build results though
52+
const fileExists = await exists(FILE_PATH);
53+
if (fileExists) {
54+
const fileContents = await readFile(FILE_PATH);
55+
if (fileContents.indexOf(HEADER_COMMENT) < 0) {
56+
appendToFile = true;
57+
}
58+
}
59+
60+
const data = `${HEADER_COMMENT}\n\n${redirects.join(`\n`)}`;
61+
62+
return appendToFile
63+
? appendFile(FILE_PATH, `\n\n${data}`)
64+
: writeFile(FILE_PATH, data);
65+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const readFileSync = require('fs').readFileSync;
2+
const resolve = require('path').resolve;
3+
const safeLoad = require('js-yaml').safeLoad;
4+
const createRedirects = require('./create-redirects');
5+
const path = require('path');
6+
7+
// Reads versions.yml data into GraphQL.
8+
// This is used to generate redirect rules for older documentation versions.
9+
exports.onPostBuild = async ({store}) => {
10+
const path = resolve(__dirname, '../../content/versions.yml');
11+
const file = readFileSync(path, 'utf8');
12+
const versions = safeLoad(file);
13+
14+
// versions.yml structure is [{title: string, path: string, url: string}, ...]
15+
createRedirects(
16+
versions.map(version => ({
17+
fromPath: version.path,
18+
toPath: version.url,
19+
})),
20+
getPublicFolder(store),
21+
);
22+
};
23+
24+
function buildPrefixer(prefix, ...paths) {
25+
return (...subpaths) => path.join(prefix, ...paths, ...subpaths);
26+
}
27+
28+
function getPublicFolder(store) {
29+
const {program} = store.getState();
30+
31+
return buildPrefixer(program.directory, `public`);
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "gatsby-transformer-versions-yaml",
3+
"version": "0.0.1"
4+
}

‎src/pages/versions.js

+10-15
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import TitleAndMetaTags from 'components/TitleAndMetaTags';
1111
import React from 'react';
1212
import {sharedStyles} from 'theme';
1313

14+
// $FlowFixMe This is a valid path
15+
import versions from '../../content/versions.yml';
16+
1417
const Versions = () => (
1518
<Container>
1619
<div css={sharedStyles.articleLayout.container}>
@@ -29,21 +32,13 @@ const Versions = () => (
2932
</p>
3033
<p>Documentation for recent releases can also be accessed below:</p>
3134
<ul>
32-
<li>
33-
<a href="/version/16.2" rel="nofollow">
34-
16.2.0
35-
</a>
36-
</li>
37-
<li>
38-
<a href="/version/16.1" rel="nofollow">
39-
16.1.1
40-
</a>
41-
</li>
42-
<li>
43-
<a href="/version/16.0" rel="nofollow">
44-
16.0.0
45-
</a>
46-
</li>
35+
{versions.map(version => (
36+
<li key={version.title}>
37+
<a href={version.path} rel="nofollow">
38+
{version.title}
39+
</a>
40+
</li>
41+
))}
4742
</ul>
4843
</div>
4944
</div>

‎static/_redirects

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
11
/html-jsx.html http://magic.reactjs.net/htmltojsx.htm 301
2-
/tips/controlled-input-null-value.html /docs/forms.html#controlled-input-null-value
3-
4-
/version/16.2 https://5abc31d8be40f1556f06c4be--reactjs.netlify.com/ 301
5-
/version/16.1 https://5a1dbcf14c4b93299e65b9a9--reactjs.netlify.com/ 301
6-
/version/16.0 https://5a046bf5a6188f4b8fa4938a--reactjs.netlify.com/ 301
2+
/tips/controlled-input-null-value.html /docs/forms.html#controlled-input-null-value

0 commit comments

Comments
 (0)
Please sign in to comment.