Skip to content

Commit

Permalink
Dynamically generate index page
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Jackson committed Mar 17, 2018
1 parent 92c087c commit db4a7df
Show file tree
Hide file tree
Showing 18 changed files with 645 additions and 542 deletions.
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
"angular": "1.5.8",
"babel-core": "^6.23.1",
"babel-loader": "^6.2.4",
"babel-plugin-transform-object-assign": "^6.5.0",
"babel-preset-es2015": "^6.6.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-1": "^6.5.0",
"babel-preset-stage-2": "^6.24.1",
"babel-register": "^6.9.0",
"backbone": "^1.2.3",
"body-parser": "^1.15.2",
Expand Down
113 changes: 32 additions & 81 deletions scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,38 @@ const mkdirp = require("mkdirp");
const React = require("react");
const ReactDOMServer = require("react-dom/server");

const e = React.createElement;
function writeFile(file, contents) {
mkdirp.sync(path.dirname(file));
fs.writeFileSync(file, contents);
}

function IndexPage({ data }) {
return e(
"html",
null,
e(
"head",
null,
e("link", { rel: "stylesheet", href: "/shared.css" })
),
e(
"body",
null,
e(
"div",
{ className: "index" },
e(
"div",
{ className: "index-logo" },
e(
"a",
{ href: "https://reacttraining.com" },
e("img", { src: "/logo.png" })
)
),
e(
"table",
{
className: "index-subjectsTable",
cellSpacing: 0,
cellPadding: 0
},
e(
"tbody",
null,
data.map((row, index) =>
e(
"tr",
{ key: index },
row.map((content, index) =>
e("td", { key: index }, content)
)
)
)
)
)
)
)
function renderPage(element) {
return (
"<!DOCTYPE html>" + ReactDOMServer.renderToStaticMarkup(element)
);
}

function SubjectPage({ bundle }) {
const e = React.createElement;

function HostPage({ bundle, data, title = "React Training" }) {
return e(
"html",
null,
e(
"head",
null,
e("link", { rel: "stylesheet", href: "/shared.css" })
e("meta", { charSet: "utf-8" }),
e("meta", {
name: "viewport",
content: "width=device-width, initial-scale=1"
}),
e("title", null, title),
data &&
e("script", {
dangerouslySetInnerHTML: {
__html: `window.__DATA__ = ${JSON.stringify(data)}`
}
})
),
e(
"body",
Expand All @@ -75,33 +47,18 @@ function SubjectPage({ bundle }) {
);
}

function renderPage(page, props) {
return (
"<!doctype html>" +
ReactDOMServer.renderToStaticMarkup(e(page, props))
);
}

function writeFile(file, contents) {
mkdirp.sync(path.dirname(file));
fs.writeFileSync(file, contents);
}

const publicDir = path.resolve(__dirname, "../public");
const subjectsDir = path.resolve(__dirname, "../subjects");
const subjectDirs = fs
.readdirSync(subjectsDir)
.map(file => path.join(subjectsDir, file))
.filter(file => fs.lstatSync(file).isDirectory());

const rows = [];
const subjects = [];

subjectDirs.forEach(dir => {
const split = path.basename(dir).split(/ (.+)/);
const n = split[0];
const subject = split[1];

const row = [n];
const subject = { index: split[0], name: split[1] };

const base = path
.basename(dir)
Expand All @@ -113,46 +70,40 @@ subjectDirs.forEach(dir => {

writeFile(
path.join(publicDir, base, "lecture.html"),
renderPage(SubjectPage, { bundle: `${base}/lecture` })
renderPage(e(HostPage, { bundle: `${base}/lecture` }))
);

row.push(e("a", { href: `/${base}/lecture.html` }, subject));
} else {
row.push(subject);
subject.lectureHref = `/${base}/lecture.html`;
}

if (fs.existsSync(path.join(dir, "exercise.js"))) {
console.log(`Building ${base}/exercise.html...`);

writeFile(
path.join(publicDir, base, "exercise.html"),
renderPage(SubjectPage, { bundle: `${base}/exercise` })
renderPage(e(HostPage, { bundle: `${base}/exercise` }))
);

row.push(e("a", { href: `/${base}/exercise.html` }, "exercise"));
} else {
row.push(null);
subject.exerciseHref = `/${base}/exercise.html`;
}

if (fs.existsSync(path.join(dir, "solution.js"))) {
console.log(`Building ${base}/solution.html...`);

writeFile(
path.join(publicDir, base, "solution.html"),
renderPage(SubjectPage, { bundle: `${base}/solution` })
renderPage(e(HostPage, { bundle: `${base}/solution` }))
);

row.push(e("a", { href: `/${base}/solution.html` }, "solution"));
} else {
row.push(null);
subject.solutionHref = `/${base}/solution.html`;
}

rows.push(row);
subjects.push(subject);
});

console.log(`Building index.html...`);

writeFile(
path.join(publicDir, "index.html"),
renderPage(IndexPage, { data: rows })
renderPage(e(HostPage, { bundle: "index", data: { subjects } }))
);
7 changes: 2 additions & 5 deletions subjects/.babelrc
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
{
"presets": [
"es2015",
"stage-1",
"env",
"stage-2",
"react"
],
"plugins": [
"transform-object-assign"
]
}
168 changes: 90 additions & 78 deletions subjects/02 Components/lecture.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import "./styles.css";

import React from "react";
import ReactDOM from "react-dom";

Expand All @@ -9,17 +11,19 @@ function handleClick() {
}

function ContentToggle() {
let summaryClassName = "ContentToggle__Summary";
let summaryClassName = "content-toggle-summary";

if (isOpen) summaryClassName += " ContentToggle__Summary--is-open";
if (isOpen) {
summaryClassName += " content-toggle-summary-open";
}

return (
<div className="ContentToggle">
<div className="content-toggle">
<button onClick={handleClick} className={summaryClassName}>
Tacos
</button>
{isOpen && (
<div className="ContentToggle__Details">
<div className="content-toggle-details">
<p>
A taco is a traditional Mexican dish composed of a corn or
wheat tortilla folded or rolled around a filling.
Expand Down Expand Up @@ -61,77 +65,85 @@ updateThePage();
// Side note: Be careful to use the React.Children utility methods.
// this.props.children is opaque!

//class ContentToggle extends React.Component {
// state = {
// isOpen: false
// }
//
// handleClick() {
// this.setState({
// isOpen: !this.state.isOpen
// })
//
// if (this.props.onToggle)
// this.props.onToggle()
// }
//
// render() {
// let summaryClassName = 'ContentToggle__Summary'
//
// if (this.state.isOpen)
// summaryClassName += ' ContentToggle__Summary--is-open'
//
// return (
// <div className="ContentToggle">
// <button onClick={this.handleClick} className={summaryClassName}>
// {this.props.title}
// </button>
// {this.state.isOpen && (
// <div className="ContentToggle__Details">
// {this.props.children}
// </div>
// )}
// </div>
// )
// }
//}
//
//class ToggleTracker extends React.Component {
// state = {
// numToggles: 0
// }
//
// handleToggle() {
// this.setState({
// numToggles: this.state.numToggles + 1
// })
// }
//
// render() {
// let { children } = this.props
//
// children = React.Children.map(children, (child) => (
// React.cloneElement(child, {
// onToggle: this.handleToggle
// })
// ))
//
// return (
// <div>
// <pre>{JSON.stringify(this.state, null, 2)}</pre>
// {children}
// </div>
// )
// }
//}
//
//ReactDOM.render((
// <ToggleTracker>
// <ContentToggle title="Tacos">
// <p>A taco is a traditional Mexican dish composed of a corn or wheat tortilla folded or rolled around a filling.</p>
// </ContentToggle>
// <ContentToggle title="Burritos">
// <p>A burrito is a type of Mexican and Tex-Mex food, consisting of a wheat flour tortilla wrapped or folded into a cylindrical shape to completely enclose the filling (in contrast to a taco, which is generally formed by simply folding a tortilla in half around a filling, leaving the semicircular perimeter open).</p>
// </ContentToggle>
// </ToggleTracker>
//), document.getElementById('app'))
// class ContentToggle extends React.Component {
// state = {
// isOpen: false
// };

// handleClick() {
// this.setState({ isOpen: !this.state.isOpen }, () => {
// if (this.props.onToggle) {
// this.props.onToggle();
// }
// });
// }

// render() {
// let summaryClassName = "content-toggle-summary";

// if (this.state.isOpen) {
// summaryClassName += " content-toggle-summary-open";
// }

// return (
// <div className="content-toggle">
// <button onClick={this.handleClick} className={summaryClassName}>
// {this.props.title}
// </button>
// {this.state.isOpen && (
// <div className="content-toggle-details">
// {this.props.children}
// </div>
// )}
// </div>
// );
// }
// }

// class ToggleTracker extends React.Component {
// state = {
// numToggles: 0
// };

// handleToggle() {
// this.setState({
// numToggles: this.state.numToggles + 1
// });
// }

// render() {
// const children = React.Children.map(this.props.children, child =>
// React.cloneElement(child, {
// onToggle: this.handleToggle
// })
// );

// return (
// <div>
// <pre>{JSON.stringify(this.state, null, 2)}</pre>
// {children}
// </div>
// );
// }
// }

// ReactDOM.render(
// <ToggleTracker>
// <ContentToggle title="Tacos">
// <p>
// A taco is a traditional Mexican dish composed of a corn or wheat
// tortilla folded or rolled around a filling.
// </p>
// </ContentToggle>
// <ContentToggle title="Burritos">
// <p>
// A burrito is a type of Mexican and Tex-Mex food, consisting of a
// wheat flour tortilla wrapped or folded into a cylindrical shape
// to completely enclose the filling (in contrast to a taco, which
// is generally formed by simply folding a tortilla in half around
// a filling, leaving the semicircular perimeter open).
// </p>
// </ContentToggle>
// </ToggleTracker>,
// document.getElementById("app")
// );
Loading

0 comments on commit db4a7df

Please sign in to comment.