Skip to content

Commit

Permalink
update to new multi tpl architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
jescalan committed Jul 29, 2017
1 parent 999cdab commit d5aa544
Show file tree
Hide file tree
Showing 15 changed files with 73 additions and 74 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ new Contentful({
})
```

### Aggressive Refresh

By default, this plugin will only fetch data once when you start your watcher, for development speed purposes. This means that if you change your data, you will have to restart the watcher to pick up the changes. If you are in a phase where you are making frequent data changes and would like a more aggressive updating strategy, you can set the `aggressiveRefresh` option to `true`, and your dreams will come true. However, note that this will slow down your local development, as it will fetch and link all entires every time you save a file, so it's only recommended for temporary use.

### Testing

To run the tests locally, you'll need to add a `test/.env` with your name and token values:
Expand Down
77 changes: 37 additions & 40 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
const contentful = require('contentful')
const Joi = require('joi')
const W = require('when')
const fs = require('fs')
const path = require('path')
const node = require('when/node')
const reshape = require('reshape')
const loader = require('reshape-loader')
const SpikeUtil = require('spike-util')
const bindAllClass = require('es6bindall')

// This plugin works in almost exactly the same way as spike-records, but has
// been customized specifically for contentful. For a more thoroughly annotated
Expand All @@ -25,17 +21,44 @@ class Contentful {
accessToken: this.accessToken,
space: this.spaceId
})
bindAllClass(this, ['apply', 'run'])
}

apply (compiler) {
this.util = new SpikeUtil(compiler.options)
this.util.runAll(compiler, this.run)
let templatePairs

// if there are single template pages, configure them here
compiler.plugin('before-loader-process', (ctx, options) => {
// map each template path to its config position
if (!templatePairs) {
templatePairs = this.contentTypes.reduce((m, model, idx) => {
if (!model.template) return m
if (!model.template.path) {
throw new Error(`${model.name}.template must have a "path" property`)
}
if (!model.template.output) {
throw new Error(`${model.name}.template must have an "output" function`)
}
m[model.template.path] = idx
return m
}, {})
}

this.util.runAll(compiler, this.run.bind(this, compiler))
// get the relative path of the file currently being compiled
const p = ctx.resourcePath.replace(`${compiler.options.context}/`, '')

compiler.plugin('compilation', (compilation) => {
compilation.plugin('normal-module-loader', (loaderContext) => {
this.loaderContext = loaderContext
// match this path to the template pairs to get the model's full config
if (typeof templatePairs[p] === 'undefined') return options
const conf = this.contentTypes[templatePairs[p]]
const data = this.addDataTo.contentful[conf.name]

// add a reshape multi option to compile each template separately
options.multi = data.map((d) => {
return { locals: { item: d }, name: conf.template.output(d) }
})
return options
})

compiler.plugin('emit', (compilation, done) => {
Expand All @@ -47,17 +70,14 @@ class Contentful {
return writeJson(compilation, ct.json, this.addDataTo.contentful[ct.name])
})

const templateContent = this.contentTypes.filter((ct) => {
return ct.template
})

W.map(templateContent, (contentType) => {
return writeTemplate.call(this, compiler, compilation, contentType)
}).done(() => done(), done)
done()
})
}

run (compiler, compilation, done) {
run (compilation, done) {
// only pull data on the initial compile in watch mode
if (this.addDataTo.contentful && !this.aggressiveRefresh) return done()

return W.reduce(this.contentTypes, (m, ct) => {
let transformFn = ct.transform
let options = Object.assign({
Expand Down Expand Up @@ -175,28 +195,5 @@ function writeJson (compilation, filename, data) {
}
}

function writeTemplate (compiler, compilation, contentType) {
const data = this.addDataTo.contentful[contentType.name]
const filePath = path.join(compiler.options.context, contentType.template.path)

return node.call(fs.readFile.bind(fs), filePath, 'utf8').then((template) => {
return W.map(data, (item) => {
const newLocals = Object.assign({}, this.addDataTo, { item })

const options = loader.parseOptions.call(this.loaderContext, this.util.getSpikeOptions().reshape, {})

return reshape(options)
.process(template)
.then((res) => {
const html = res.output(newLocals)
compilation.assets[contentType.template.output(item)] = {
source: () => html,
size: () => html.length
}
})
})
})
}

module.exports = Contentful
module.exports.transform = transform
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@
"bugs": "https://github.com/static-dev/spike-contentful/issues",
"dependencies": {
"contentful": "^4.5.0",
"es6bindall": "^0.0.9",
"joi": "^10.6.0",
"reshape": "^0.4.1",
"reshape-loader": "^1.1.0",
"when": "^3.7.8"
},
"devDependencies": {
"ava": "^0.21.0",
"coveralls": "^2.13.1",
"dotenv": "^4.0.0",
"nyc": "^11.0.3",
"reshape-standard": "^3.0.0",
"reshape-standard": "^3.0.1",
"rimraf": "^2.6.0",
"spike-core": "^2.2.0",
"standard": "^10.0.2"
Expand Down
1 change: 0 additions & 1 deletion test/fixtures/default/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const standard = require('reshape-standard')
const locals = {}

module.exports = {
matchers: { html: '*(**/)*.sgr' },
reshape: standard({ locals }),
plugins: [new Contentful({
accessToken: process.env.accessToken,
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/default/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<each loop='cat of contentful.cats'>
<p>{{ cat.fields.name }}</p>
</each>
2 changes: 0 additions & 2 deletions test/fixtures/default/index.sgr

This file was deleted.

1 change: 1 addition & 0 deletions test/fixtures/error/error.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>{{ notItem.fields.name }}</p>
1 change: 0 additions & 1 deletion test/fixtures/json/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const htmlStandards = require('reshape-standard')
const locals = {}

module.exports = {
matchers: { html: '*(**/)*.sgr' },
reshape: htmlStandards({ locals }),
plugins: [new Contentful({
accessToken: process.env.accessToken,
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/json/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<each loop='dog of contentful.dogs'>
<p>{{ dog.fields.name }}</p>
</each>
2 changes: 0 additions & 2 deletions test/fixtures/json/index.sgr

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/template/error.sgr

This file was deleted.

1 change: 1 addition & 0 deletions test/fixtures/template/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>{{ item.fields.name }}</p>
1 change: 0 additions & 1 deletion test/fixtures/template/template.sgr

This file was deleted.

27 changes: 11 additions & 16 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ const fs = require('fs')
const rimraf = require('rimraf')
const standard = require('reshape-standard')

const compilerMock = { options: { spike: { locals: {} } } }

test('errors without an "accessToken"', (t) => {
t.throws(
() => { new Contentful({ spaceId: 'xxx' }) }, // eslint-disable-line
Expand Down Expand Up @@ -98,7 +96,7 @@ test.cb('returns valid content', (t) => {
]
})

api.run(compilerMock, undefined, () => {
api.run(undefined, () => {
t.is(locals.contentful.dogs.length, 2)
t.is(locals.contentful.cats.length, 3)
t.end()
Expand All @@ -114,7 +112,7 @@ test.cb('defaults id to name if not present', (t) => {
contentTypes: [{ name: 'cat' }]
})

api.run(compilerMock, undefined, () => {
api.run(undefined, () => {
t.is(locals.contentful.cat.length, 3)
t.end()
})
Expand All @@ -135,7 +133,7 @@ test.cb('implements request options', (t) => {
]
})

api.run(compilerMock, undefined, () => {
api.run(undefined, () => {
t.is(locals.contentful.cats.length, 1)
t.is(locals.contentful.cats[0].fields.name, 'Garfield')
t.end()
Expand Down Expand Up @@ -164,7 +162,7 @@ test.cb('works with custom transform function', (t) => {
]
})

api.run(compilerMock, undefined, () => {
api.run(undefined, () => {
t.is(locals.contentful.cats[0].doge, 'wow')
t.end()
})
Expand All @@ -188,7 +186,7 @@ test.cb('can implement default transform function', (t) => {
]
})

api.run(compilerMock, undefined, () => {
api.run(undefined, () => {
t.truthy(typeof locals.contentful.cats[0].name === 'string')
t.end()
})
Expand All @@ -205,7 +203,7 @@ test.cb('works as a plugin to spike', (t) => {
project.on('warning', t.end)
project.on('compile', () => {
const src = fs.readFileSync(path.join(projectPath, 'public/index.html'), 'utf8')
t.truthy(src === '<p>Nyan Cat</p>')
t.truthy(src.trim() === '<p>Nyan Cat</p>')
rimraf.sync(path.join(projectPath, 'public'))
t.end()
})
Expand Down Expand Up @@ -253,24 +251,22 @@ test.cb('accepts template object and generates html', (t) => {
order: 'sys.createdAt'
},
template: {
path: '../template/template.sgr',
path: 'template.html',
output: (item) => `cats/${item.fields.name}.html`
}
}
]
})

const projectPath = path.join(__dirname, 'fixtures/default')
const projectPath = path.join(__dirname, 'fixtures/template')
const project = new Spike({
root: projectPath,
matchers: { html: '**/*.sgr' },
reshape: standard({ locals }),
entry: { main: [path.join(projectPath, 'main.js')] },
plugins: [contentful]
})

project.on('error', t.end)
project.on('warning', t.end)
project.on('compile', () => {
const file1 = fs.readFileSync(path.join(projectPath, 'public/cats/Happy Cat.html'), 'utf8')
const file2 = fs.readFileSync(path.join(projectPath, 'public/cats/Nyan Cat.html'), 'utf8')
Expand All @@ -297,17 +293,16 @@ test.cb('generates error if template has an error', (t) => {
limit: 1
},
template: {
path: '../template/error.sgr',
path: 'error.html',
output: (item) => `cats/${item.fields.name}.html`
}
}
]
})

const projectPath = path.join(__dirname, 'fixtures/default')
const projectPath = path.join(__dirname, 'fixtures/error')
const project = new Spike({
root: projectPath,
matchers: { html: '**/*.sgr' },
reshape: standard({ locals }),
entry: { main: [path.join(projectPath, 'main.js')] },
plugins: [contentful]
Expand All @@ -316,7 +311,7 @@ test.cb('generates error if template has an error', (t) => {
project.on('warning', t.end)
project.on('compile', () => t.end('no error'))
project.on('error', (error) => {
t.is(error.toString(), "Error: Cannot read property 'fields' of undefined")
t.regex(error.toString(), /Error: Cannot read property 'fields' of undefined/)
rimraf.sync(path.join(projectPath, 'public'))
t.end()
})
Expand Down
18 changes: 11 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2216,6 +2216,10 @@ es6-weak-map@^2.0.1:
es6-iterator "^2.0.1"
es6-symbol "^3.1.1"

es6bindall@^0.0.9:
version "0.0.9"
resolved "https://registry.yarnpkg.com/es6bindall/-/es6bindall-0.0.9.tgz#71e00afa69f8dd59ac5ac898a0d31c978df817d5"

escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
Expand Down Expand Up @@ -5426,17 +5430,17 @@ reshape-plugin-util@^0.2.0, reshape-plugin-util@^0.2.1:
dependencies:
when "^3.7.7"

reshape-retext@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/reshape-retext/-/reshape-retext-1.0.0.tgz#879730f6e5b5d108913e28ee210fc42fb8848cda"
reshape-retext@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/reshape-retext/-/reshape-retext-1.0.1.tgz#015f7ca4162d4ae69359c26e122737c46262a793"
dependencies:
reshape-plugin-util "^0.2.0"
retext "^5.0.0"
when "^3.7.8"

reshape-standard@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/reshape-standard/-/reshape-standard-3.0.0.tgz#8aff2cfbbe336e5737d68cde19bde72387d76378"
reshape-standard@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/reshape-standard/-/reshape-standard-3.0.1.tgz#dbaef3c67839ebdd7a316e1b3862a554b946e09f"
dependencies:
markdown-it "^8.2.2"
reshape-beautify "^0.1.2"
Expand All @@ -5446,7 +5450,7 @@ reshape-standard@^3.0.0:
reshape-include "^1.0.0"
reshape-layouts "^1.0.0"
reshape-minify "^1.1.0"
reshape-retext "^1.0.0"
reshape-retext "^1.0.1"
retext-smartypants "^3.0.0"

reshape@^0.4.1:
Expand Down

0 comments on commit d5aa544

Please sign in to comment.