Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for NotFoundRoute, Converted CJSX utils to JSX, Started moving from CoffeeScript to ES6 #37

Merged
merged 8 commits into from
Oct 3, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/isomorphic/create-routes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ filter = require 'lodash/collection/filter'
sortBy = require 'lodash/collection/sortBy'
last = require 'lodash/array/last'
includes = require 'underscore.string/include'
{ config } = require 'config'

module.exports = (pages, pagesReq) ->
templates = {}
Expand All @@ -12,6 +13,15 @@ module.exports = (pages, pagesReq) ->
handler: pagesReq './_template'
})

# Adds a handler for <NotFoundRoute /> that will serve as a 404 Page
if config.notFound
templates.rootNotFound = Router.createNotFoundRoute({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is a stopgap as we'll be adding support for "meta pages" soon like * routes through the coming plugin system (#36 (comment)). I'll be writing up a RFC soon with some thoughts about how the plugin system will work.

name: 'root-not-found'
path: "*"
handler: pagesReq './_404'
parentRoute: templates.root
})

# Arrange pages in data structure according to their position
# on the file system. Then use this to create routes.
#
Expand Down
44 changes: 44 additions & 0 deletions lib/isomorphic/gatsby-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { pages, config, relativePath } from 'config';
import filter from 'lodash/collection/filter';
import first from 'lodash/array/first';
import includes from 'underscore.string/include';

// Prefix links for Github Pages.
// TODO make this generic for all prefixing?
exports.link = function(link) {
if ((typeof __GH_PAGES__ !== "undefined" && __GH_PAGES__ !== null) && __GH_PAGES__ && (config.ghPagesURLPrefix != null)) {
return config.ghPagesURLPrefix + link;
} else {
return link;
}
};

// Get the child pages for a given template.
exports.templateChildrenPages = function(filename, state) {
// Pop off the file name to leave the relative directory
// path to this template.
var split = filename.split('/');
split.pop();
var result = split.join('/');
if (result === "") {
result = "/";
}

var childrenRoutes = first(
filter(
state.routes, function(route) { return includes(route.path, result); }
)
).childRoutes;

var childrenPaths = childrenRoutes.map(function(path) { return path.path; });

if (childrenPaths) {
var childPages = filter(pages, function(page) {
return childrenPaths.indexOf(page.path) >= 0;
});
} else {
childPages = [];
}

return childPages;
};
48 changes: 21 additions & 27 deletions lib/loaders/config-loader/index.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
// Generated by CoffeeScript 1.9.0
(function() {
var Router, globPages, loaderUtils, path, toml;
import toml from 'toml';
import loaderUtils from 'loader-utils';
import Router from 'react-router';
import path from 'path';

toml = require('toml');
import globPages from '../../utils/glob-pages';

loaderUtils = require('loader-utils');
module.exports = function(source) {
this.cacheable();
var callback = this.async();

Router = require('react-router');
var value = {};

path = require('path');
var directory = loaderUtils.parseQuery(this.query).directory;

globPages = require('../../utils/glob-pages');
// TODO support YAML + JSON + CSON as well here.
var config = toml.parse(source);
value.config = config;
value.relativePath = path.relative('.', directory);

module.exports = function(source) {
var callback, config, directory, value;
this.cacheable();
callback = this.async();
value = {};
directory = loaderUtils.parseQuery(this.query).directory;
config = toml.parse(source);
value.config = config;
value.relativePath = path.relative('.', directory);
return globPages(directory, (function(_this) {
return function(err, pagesData) {
value.pages = pagesData;
_this.value = [value];
return callback(null, 'module.exports = ' + JSON.stringify(value, void 0, "\t"));
};
})(this));
};

}).call(this);
// Load pages.
return globPages(directory, (err, pagesData) => {
value.pages = pagesData;
this.value = [value];
return callback(null, 'module.exports = ' + JSON.stringify(value, undefined, "\t"));
});
};
42 changes: 42 additions & 0 deletions lib/utils/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import generateStaticPages from './static-generation';
import buildProductionBundle from './build-production';
import postBuild from './post-build';
import globPages from './glob-pages';

module.exports = function(program) {
var {directory} = program;
try {
var customPostBuild = require(directory + "/post-build");
} catch (e) {
}

console.log("Generating static html pages");
return generateStaticPages(program, function(err, stats) {
if (err) {
console.log("failed at generating static html pages");
return console.log(err);
}
console.log("Compiling production bundle.js");
return buildProductionBundle(program, function(err, stats) {
if (err) {
console.log("failed to compile bundle.js");
return console.log(err);
}
console.log("Copying assets");
return postBuild(program, function(err, results) {
if (err) {
console.log("failed to copy assets");
return console.log(err);
}
if ((typeof customPostBuild !== "undefined" && customPostBuild !== null)) {
console.log("Performing custom post-build steps");
return globPages(directory, function(err, pages) {
return customPostBuild(pages, function(err) {
return console.log('Done');
});
});
}
});
});
});
};
56 changes: 56 additions & 0 deletions lib/utils/post-build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import path from 'path';
import glob from 'glob';
import fs from 'fs-extra';
import async from 'async';
import parsePath from 'parse-filepath';
import _ from 'underscore';

import globPages from './glob-pages';

module.exports = function(program, cb) {
var {relativeDirectory, directory} = program;

return globPages(directory, function(err, pages) {

// Async callback to copy each file.
var copy = function(file, callback) {
// Map file to path generated for that directory.
// e.g. if file is in directory 2015-06-16-my-sweet-blog-post that got
// rewritten to my-sweet-blog-post, we find that path rewrite so
// our asset gets copied to the right directory.
var parsed = parsePath(file);
var relativePath = path.relative(directory + "/pages", file);
var oldPath = parsePath(relativePath).dirname;

// Wouldn't rewrite basePath
if (oldPath === ".") {
oldPath = "/";
var newPath = `/${parsed.basename}`;
}

if (!(oldPath === "/")) {
var page = _.find(pages, function(page) {
// Ignore files that start with underscore (they're not pages).
if (page.file.name.slice(0,1) !== '_') {
return parsePath(page.requirePath).dirname === oldPath;
}
});

newPath = parsePath(page.path).dirname + parsed.basename;
}

newPath = directory + "/public/" + newPath;
return fs.copy(file, newPath, function(err) {
return callback(err);
}
);
};

// Copy static assets to public folder.
return glob(directory + '/pages/**/?(*.jpg|*.png|*.pdf|*.gif|*.ico)', null, function(err, files) {
return async.map(files, copy, function(err, results) {
return cb(err, results);
});
});
});
};
114 changes: 114 additions & 0 deletions lib/utils/serve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import Hapi from 'hapi';
import Boom from 'boom';
import React from 'react';
import Router from 'react-router';
import path from 'path';
import WebpackDevServer from 'webpack-dev-server';
import webpack from 'webpack';
import Negotiator from 'negotiator';
import parsePath from 'parse-filepath';
import _ from 'underscore';
import globPages from './glob-pages';
import webpackConfig from './webpack.config';

module.exports = function(program) {
var {relativeDirectory, directory} = program;

// Load pages for the site.
return globPages(directory, function(err, pages) {
try {
var HTML = require(directory + '/html');
} catch (e) {
console.log("error loading html template", e);
HTML = require(`${__dirname}/../isomorphic/html`);
}

// Generate random port for webpack to listen on.
// Perhaps should check if port is open.
var webpackPort = Math.round(Math.random() * 1000 + 1000);

var compilerConfig = webpackConfig(program, directory, 'serve', webpackPort);
var compiler = webpack(compilerConfig);

var webpackDevServer = new WebpackDevServer(compiler, {
hot: true,
quiet: true,
noInfo: true,
host: program.host,
stats: {
colors: true
}
});

// Start webpack-dev-server
webpackDevServer.listen(webpackPort, program.host, function() {});

// Setup and start Hapi to serve html + static files.
var server = new Hapi.Server();
server.connection({host: program.host, port: program.port});

server.route({
method: "GET",
path: '/bundle.js',
handler: {
proxy: {
uri: `http://localhost:${webpackPort}/bundle.js`,
passThrough: true,
xforward: true
}
}
});

server.route({
method: "GET",
path: '/html/{path*}',
handler(request, reply) {
if (request.path === "favicon.ico") {
return reply(Boom.notFound());
}

var html = React.renderToStaticMarkup(React.createElement(HTML));
html = "<!DOCTYPE html>\n" + html;
return reply(html);
}
});

server.route({
method: "GET",
path: '/{path*}',
handler: {
directory: {
path: directory + "/pages",
listing: false,
index: false
}
}
});

server.ext('onRequest', function(request, reply) {
var negotiator = new Negotiator(request.raw.req);

if (negotiator.mediaType() === "text/html") {
request.setUrl("/html" + request.path);
return reply.continue();
} else {
// Rewrite path to match disk path.
var parsed = parsePath(request.path);
var page = _.find(pages, function(page) { return page.path === (parsed.dirname + "/"); });

if (page) {
request.setUrl(`/${parsePath(page.requirePath).dirname}/${parsed.basename}`);
}

return reply.continue();
}
});

return server.start(function(err) {
if (err) {
console.log(err);
}
return console.log("Listening at:", server.info.uri);
});
});
};
52 changes: 0 additions & 52 deletions lib/utils/static-entry.cjsx

This file was deleted.