From 08eca6737d7d68e3b812847743b90ae667a956ce Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Sat, 12 Mar 2016 11:53:57 -0800 Subject: [PATCH] Add support for json/yaml/toml pages --- lib/isomorphic/create-routes.js | 64 +++++++++++++++----------------- lib/loaders/html-loader/index.js | 9 +++++ lib/utils/glob-pages.js | 18 ++++++++- lib/utils/webpack.config.js | 2 +- 4 files changed, 57 insertions(+), 36 deletions(-) create mode 100644 lib/loaders/html-loader/index.js diff --git a/lib/isomorphic/create-routes.js b/lib/isomorphic/create-routes.js index 7d3b2a3137d97..d1dbeadaf224b 100644 --- a/lib/isomorphic/create-routes.js +++ b/lib/isomorphic/create-routes.js @@ -82,44 +82,40 @@ module.exports = (files, pagesReq) => { parentRoute.childRoutes.push(route) }) - const markdownWrapper = require('wrappers/md') - const htmlWrapper = require('wrappers/html') + const staticFileTypes = [ + 'md', + 'html', + 'json', + 'yaml', + 'toml', + ] + const reactComponentFileTypes = [ + 'js', + 'jsx', + 'cjsx', + ] + const wrappers = {} + staticFileTypes.forEach((type) => { + try { + wrappers[type] = require(`wrappers/${type}`) + } catch (e) { + // Ignore error + } + }) pages.forEach((p) => { const page = p - // TODO add ways to load data for other file types. - // Should be able to install a gatsby-toml plugin to add support - // for TOML. Perhaps everything other than JSX and Markdown should be plugins. - // Or even they are plugins but they have built-in 'blessed' plugins. let handler - switch (page.file.ext) { - case 'md': - handler = markdownWrapper - // TODO figure out if this is redundant as data already added in - // glob-pages. - page.data = pagesReq(`./${page.requirePath}`) - break - case 'html': - handler = htmlWrapper - break - case 'jsx': - handler = pagesReq(`./${page.requirePath}`) - page.data = (() => { - if (pagesReq(`./${page.requirePath}`).metadata) { - return pagesReq(`./${page.requirePath}`).metadata() - } - })() - break - case 'cjsx': - handler = pagesReq(`./${page.requirePath}`) - page.data = (() => { - if (pagesReq(`./${page.requirePath}`).metadata) { - return pagesReq(`./${page.requirePath}`).metadata() - } - })() - break - default: - handler = pagesReq(`./${page.requirePath}`) + if (staticFileTypes.indexOf(page.file.ext) !== -1) { + handler = wrappers[page.file.ext] + page.data = pagesReq(`./${page.requirePath}`) + } else if (reactComponentFileTypes.indexOf(page.file.ext) !== -1) { + handler = pagesReq(`./${page.requirePath}`) + page.data = (() => { + if (pagesReq(`./${page.requirePath}`).metadata) { + return pagesReq(`./${page.requirePath}`).metadata() + } + })() } // Determine parent template for page. diff --git a/lib/loaders/html-loader/index.js b/lib/loaders/html-loader/index.js new file mode 100644 index 0000000000000..b49758e395e46 --- /dev/null +++ b/lib/loaders/html-loader/index.js @@ -0,0 +1,9 @@ +import htmlFrontMatter from 'html-frontmatter' +import objectAssign from 'object-assign' + +module.exports = function (content) { + this.cacheable() + const data = objectAssign({}, htmlFrontMatter(content), { body: content }) + this.value = data + return `module.exports = ${JSON.stringify(data)}` +} diff --git a/lib/utils/glob-pages.js b/lib/utils/glob-pages.js index 568d62c664256..f9d8e276647e8 100644 --- a/lib/utils/glob-pages.js +++ b/lib/utils/glob-pages.js @@ -15,7 +15,20 @@ module.exports = (directory, callback) => { // Make this list easy to modify through the config? // Or just keep adding extensions...? - const globQuery = `${directory}/pages/**/?(*.coffee|*.cjsx|*.jsx|*.js|*.md|*.html)` + const fileTypesToGlob = [ + 'coffee', + 'cjsx', + 'jsx', + 'js', + 'md', + 'html', + 'json', + 'yaml', + 'toml', + ] + const fileGlobQuery = fileTypesToGlob.map((type) => `*.${type}`) + const joinedFileQuery = fileGlobQuery.join('|') + const globQuery = `${directory}/pages/**/?(${joinedFileQuery})` glob(globQuery, null, (err, pages) => { if (err) { return callback(err) } @@ -36,6 +49,9 @@ module.exports = (directory, callback) => { parsed.dirname = slash(parsed.dirname) // Load data for each file type. + // TODO use webpack-require to ensure data loaded + // here (in node context) is consistent with what's loaded + // in the browser. let data if (ext === 'md') { const rawData = frontMatter(fs.readFileSync(page, 'utf-8')) diff --git a/lib/utils/webpack.config.js b/lib/utils/webpack.config.js index 934d507cd7212..5f5b29d0daa25 100644 --- a/lib/utils/webpack.config.js +++ b/lib/utils/webpack.config.js @@ -153,7 +153,7 @@ module.exports = (program, directory, stage, webpackPort = 1500, routes = []) => }) config.loader('html', { test: /\.html$/, - loader: 'raw', + loader: 'html', }) config.loader('json', { test: /\.json$/,