From d255c1afc6603202fcee12daa586d7376fc8d7e0 Mon Sep 17 00:00:00 2001 From: Eric Simons Date: Sun, 15 Oct 2017 11:36:37 -0700 Subject: [PATCH] sync js files to codepen --- .eslintignore | 5 ++- content/docs/hello-world.md | 2 +- content/docs/introducing-jsx.md | 2 +- examples/hello-world.js | 4 ++ examples/index.html | 3 ++ examples/introducing-jsx.js | 19 ++++++++++ gatsby-node.js | 42 ++++++++++++++++----- package.json | 2 +- src/templates/codepen-example.js | 64 ++++++++++++++++++++++++++++++++ 9 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 examples/hello-world.js create mode 100644 examples/index.html create mode 100644 examples/introducing-jsx.js create mode 100644 src/templates/codepen-example.js diff --git a/.eslintignore b/.eslintignore index ff8a5577..94254171 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,4 +4,7 @@ node_modules/* content/* # Ignore built files -public/* \ No newline at end of file +public/* + +# Ignore examples +examples/* \ No newline at end of file diff --git a/content/docs/hello-world.md b/content/docs/hello-world.md index f9be3bde..06087d7b 100644 --- a/content/docs/hello-world.md +++ b/content/docs/hello-world.md @@ -11,7 +11,7 @@ redirect_from: - "docs/getting-started-zh-CN.html" --- -The easiest way to get started with React is to use [this Hello World example code on CodePen](http://codepen.io/gaearon/pen/ZpvBNJ?editors=0010). You don't need to install anything; you can just open it in another tab and follow along as we go through examples. If you'd rather use a local development environment, check out the [Installation](/docs/installation.html) page. +The easiest way to get started with React is to use this Hello World example code on CodePen. You don't need to install anything; you can just open it in another tab and follow along as we go through examples. If you'd rather use a local development environment, check out the [Installation](/docs/installation.html) page. The smallest React example looks like this: diff --git a/content/docs/introducing-jsx.md b/content/docs/introducing-jsx.md index 9830ddc9..e1e4d64d 100644 --- a/content/docs/introducing-jsx.md +++ b/content/docs/introducing-jsx.md @@ -46,7 +46,7 @@ ReactDOM.render( ); ``` -[Try it on CodePen.](http://codepen.io/gaearon/pen/PGEjdG?editors=0010) +Try it on CodePen. We split JSX over multiple lines for readability. While it isn't required, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of [automatic semicolon insertion](http://stackoverflow.com/q/2846283). diff --git a/examples/hello-world.js b/examples/hello-world.js new file mode 100644 index 00000000..d0f87a59 --- /dev/null +++ b/examples/hello-world.js @@ -0,0 +1,4 @@ +ReactDOM.render( +

Hello, world!

, + document.getElementById('root') +); diff --git a/examples/index.html b/examples/index.html new file mode 100644 index 00000000..461f1105 --- /dev/null +++ b/examples/index.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/examples/introducing-jsx.js b/examples/introducing-jsx.js new file mode 100644 index 00000000..adb32664 --- /dev/null +++ b/examples/introducing-jsx.js @@ -0,0 +1,19 @@ +function formatName(user) { + return user.firstName + ' ' + user.lastName; +} + +const user = { + firstName: 'Harper', + lastName: 'Perez', +}; + +const element = ( +

+ Hello, {formatName(user)}! +

+); + +ReactDOM.render( + element, + document.getElementById('root') +); diff --git a/gatsby-node.js b/gatsby-node.js index 0fc10c4f..5a078ffc 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -8,6 +8,7 @@ const {resolve} = require('path'); const webpack = require('webpack'); +const fs = require('fs'); exports.modifyWebpackConfig = ({config, stage}) => { // See https://github.com/FormidableLabs/react-live/issues/5 @@ -74,11 +75,11 @@ exports.createPages = async ({graphql, boundActionCreators}) => { // (which gets created by Gatsby during a separate phase). } else if ( slug.includes('blog/') || - slug.includes('community/') || - slug.includes('contributing/') || - slug.includes('docs/') || - slug.includes('tutorial/') || - slug.includes('warnings/') + slug.includes('community/') || + slug.includes('contributing/') || + slug.includes('docs/') || + slug.includes('tutorial/') || + slug.includes('warnings/') ) { let template; if (slug.includes('blog/')) { @@ -87,8 +88,8 @@ exports.createPages = async ({graphql, boundActionCreators}) => { template = communityTemplate; } else if ( slug.includes('contributing/') || - slug.includes('docs/') || - slug.includes('warnings/') + slug.includes('docs/') || + slug.includes('warnings/') ) { template = docsTemplate; } else if (slug.includes('tutorial/')) { @@ -117,8 +118,8 @@ exports.createPages = async ({graphql, boundActionCreators}) => { redirect.forEach(fromPath => { if (redirectToSlugMap[fromPath] != null) { console.error(`Duplicate redirect detected from "${fromPath}" to:\n` + - `* ${redirectToSlugMap[fromPath]}\n` + - `* ${slug}\n` + `* ${redirectToSlugMap[fromPath]}\n` + + `* ${slug}\n` ); process.exit(1); } @@ -161,6 +162,29 @@ exports.createPages = async ({graphql, boundActionCreators}) => { redirectInBrowser: true, toPath: newestBlogNode.fields.slug, }); + + // Create Codepen example pages + const htmlTemplate = fs.readFileSync('./examples/index.html', 'utf8'); + fs.readdirSync('./examples').forEach(file => { + // Only create pages for the JS files + if (file.toLowerCase().split('.').pop() === 'js') { + const slug = file.substring(0, file.length - 3); + const jsTemplate = fs.readFileSync(`./examples/${file}`, 'utf8'); + + createPage({ + path: `/examples/${slug}`, + component: resolve('./src/templates/codepen-example.js'), + context: { + slug, + payload: { + html: htmlTemplate, + js: jsTemplate, + }, + }, + }); + } + }); + }; // Parse date information out of blog post filename. diff --git a/package.json b/package.json index 1d214c9f..b6106a10 100644 --- a/package.json +++ b/package.json @@ -84,4 +84,4 @@ "devDependencies": { "eslint-config-prettier": "^2.6.0" } -} +} \ No newline at end of file diff --git a/src/templates/codepen-example.js b/src/templates/codepen-example.js new file mode 100644 index 00000000..7079cc53 --- /dev/null +++ b/src/templates/codepen-example.js @@ -0,0 +1,64 @@ +'use strict'; + +import React, {Component} from 'react'; +import Container from 'components/Container'; +import {colors} from 'theme'; +// import {version} from '../site-constants'; + +// Copied over styles from ButtonLink for the submit btn +const primaryStyle = { + backgroundColor: colors.brand, + color: colors.black, + padding: '10px 25px', + whiteSpace: 'nowrap', + transition: 'background-color 0.2s ease-out', + outline: 0, + border: 'none', + cursor: 'pointer', + + ':hover': { + backgroundColor: colors.white, + }, + + display: 'inline-block', + fontSize: 16, +}; + +class CodepenExample extends Component { + componentDidMount() { + this.codepenForm.submit(); + } + + render() { + const {payload} = this.props.pathContext; + // Set codepen options + payload.js_pre_processor = 'babel'; + // Only have the JS editor open (default for all examples) + payload.editors = '0010'; + // We can pass @version in the URL for version locking, if desired. + payload.js_external = `https://unpkg.com/react/umd/react.development.js;https://unpkg.com/react-dom/umd/react-dom.development.js`; + + return ( + +

Redirecting to Codepen...

+
{ + this.codepenForm = form; + }} + action="https://codepen.io/pen/define" + method="POST"> + + + +
+
+ ); + } +} + +export default CodepenExample;