Skip to content

Commit

Permalink
Merge 955d757 into a7a4e7c
Browse files Browse the repository at this point in the history
  • Loading branch information
nknapp committed Jun 17, 2016
2 parents a7a4e7c + 955d757 commit 3ae8822
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 96 deletions.
13 changes: 13 additions & 0 deletions .thought/partials/usage.md.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,19 @@ In a similar fashion, we could replace other parts of the configuration, like te
and the pre-processor. If we would provide a new preprocessor, it could call the old one,
by calling `this.parent(args)`

### Which partial generates what?

When we want to overriding parts of the output, we are looking for the correct partial to do so.
For this purpose, the engine allows to specify a "wrapper function" for partials. This function
is called with the contents and the name of a partial and returns the new content. Programs like
`Thought` can optionally include the partial names into the output to show the user which partial
to override in order to modify a given part of the output.


{{{example 'examples/example-partial-names.js'}}}

{{{exec 'node example-partial-names.js' cwd='examples/'}}}

### Accessing engine and configuration helpers

The configuration and the engine itself is passed as additional parameter into each helper call:
Expand Down
45 changes: 0 additions & 45 deletions .verb.md

This file was deleted.

85 changes: 35 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The following example demonstrates how to use this module:

├── config-module.js
├── example-merge.js
├── example-partial-names.js
├── example.js
├── hb-helpers.js
├── hb-preprocessor.js
Expand Down Expand Up @@ -126,30 +127,6 @@ Github-Name: {{{github.name}}}
The output of this example is:

```
custom false {}
debugState false {}
custom false { handlebars:
{ config:
{ partials: {},
helpers: {},
templates: {},
data: {},
preprocessor: [Function: identity],
hbsOptions: {} },
watched: [] } }
debugState false { handlebars:
{ config:
{ partials: {},
helpers: {},
templates: {},
data: {},
preprocessor: [Function: identity],
hbsOptions: {} },
watched: [] } }
custom false { _metadata: { config: { modules: [] } } }
debugState false { _metadata: { config: { modules: [] } } }
custom false { handlebars: { state: 'pending' } }
debugState false { handlebars: { state: 'pending' } }
https://api.github.com/users/nknapp
{ handlebars:
{ 'text1.txt': 'I\'m nknapp\n\nI\'m living in Darmstadt.\n\n------\nGithub-Name: Nils Knappmeier',
Expand Down Expand Up @@ -189,32 +166,6 @@ Blog: {{{github.blog}}}
The output of this example is

```
custom false {}
debugState false {}
custom false { handlebars:
{ config:
{ partials: {},
helpers: {},
templates: {},
data: {},
preprocessor: [Function: identity],
hbsOptions: {} },
watched: [] } }
debugState false { handlebars:
{ config:
{ partials: {},
helpers: {},
templates: {},
data: {},
preprocessor: [Function: identity],
hbsOptions: {} },
watched: [] } }
custom false { _metadata: { config: { modules: [] } } }
debugState false { _metadata: { config: { modules: [] } } }
custom false { handlebars: { state: 'pending' } }
debugState false { handlebars: { state: 'pending' } }
custom false { handlebars: { state: 'pending' } }
debugState false { handlebars: { state: 'pending' } }
https://api.github.com/users/nknapp
{ handlebars:
{ 'text1.txt': 'I\'m nknapp\n\nI\'m living in Darmstadt.\n\n------\nBlog: http://www.knappmeier.de',
Expand All @@ -225,6 +176,39 @@ In a similar fashion, we could replace other parts of the configuration, like te
and the pre-processor. If we would provide a new preprocessor, it could call the old one,
by calling `this.parent(args)`

### Which partial generates what?

When we want to overriding parts of the output, we are looking for the correct partial to do so.
For this purpose, the engine allows to specify a "wrapper function" for partials. This function
is called with the contents and the name of a partial and returns the new content. Programs like
`Thought` can optionally include the partial names into the output to show the user which partial
to override in order to modify a given part of the output.


```js
var customize = require('customize')
customize()
.registerEngine('handlebars', require('customize-engine-handlebars'))
.load(require('./config-module.js'))
.merge({
handlebars: {
partials: 'partials2',
partialWrapper: function (contents, name) {
return '[BEGIN ' + name + ']\n' + contents + '[END ' + name + ']'
}
}
})
.run()
.done(console.log)
```

```
https://api.github.com/users/nknapp
{ handlebars:
{ 'text1.txt': 'I\'m nknapp\n\nI\'m living in Darmstadt.\n\n[BEGIN footer]\n------\nBlog: http://www.knappmeier.de[END footer]',
'text2.txt': 'I\'m nknapp\n\nI\'m living in DARMSTADT.\n\n[BEGIN footer]\n------\nBlog: http://www.knappmeier.de[END footer]' } }
```

### Accessing engine and configuration helpers

The configuration and the engine itself is passed as additional parameter into each helper call:
Expand Down Expand Up @@ -285,6 +269,7 @@ The default configuration for the handlebars engine
| Name | Type | Description |
| --- | --- | --- |
| partials | <code>string</code> | path to a partials directory. Each `.hbs`-file in the directory (or in the tree) is registered as partial by its name (or relative path), without the `.hbs`-extension. |
| partialWrapper | <code>function</code> | a function that can modify partials just before they are registered with the Handlebars engine. It receives the partial contents as first parameter and the partial name as second parameter and must return the new content (or a promise for the content. The parameter was introduced mainly for debugging purposes (i.e. to surround each partial with a string containing the name of the partial). When this function is overridden, the parent function is available throught `this.parent`. |
| helpers | <code>string</code> &#124; <code>object</code> &#124; <code>function</code> | if this is an object it is assumed to be a list of helper functions, if this is function it is assumed to return an object of helper functions, if this is a string, it is assumed to be the path to a module returning either an object of a function as above. |
| templates | <code>string</code> | path to a directory containing templates. Handlebars is called with each `.hbs`-file as template. The result of the engine consists of an object with a property for each template and the Handlebars result for this template as value. |
| data | <code>string</code> &#124; <code>object</code> &#124; <code>function</code> | a javascript-object to use as input for handlebars. Same as with the `helpers`, it is also acceptable to specify the path to a module exporting the data and a function computing the data. |
Expand Down
14 changes: 14 additions & 0 deletions examples/example-partial-names.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var customize = require('customize')
customize()
.registerEngine('handlebars', require('../'))
.load(require('./config-module.js'))
.merge({
handlebars: {
partials: 'partials2',
partialWrapper: function (contents, name) {
return '[BEGIN ' + name + ']\n' + contents + '[END ' + name + ']'
}
}
})
.run()
.done(console.log)
11 changes: 10 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ var contents = function (partials) {
* The default configuration for the handlebars engine
* @property {string} partials path to a partials directory. Each `.hbs`-file in the directory (or in the tree)
* is registered as partial by its name (or relative path), without the `.hbs`-extension.
* @property {function(string, string):(string|Promise<string>)} partialWrapper a function that can modify partials
* just before they are registered with the Handlebars engine. It receives the partial contents as
* first parameter and the partial name as second parameter and must return the new content (or a promise for
* the content. The parameter was introduced mainly for debugging purposes (i.e. to surround each
* partial with a string containing the name of the partial). When this function is overridden, the
* parent function is available throught `this.parent`.
* @property {string|object|function} helpers if this is an object it is assumed to be a list of helper functions,
* if this is function it is assumed to return an object of helper functions, if this is a string,
* it is assumed to be the path to a module returning either an object of a function as above.
Expand All @@ -47,6 +53,7 @@ var contents = function (partials) {
* @typedef {object} InternalHbsConfig the internal configuration object that
* is passed into the merge function.
* @property {object<{path:string,contents:string}>} partials the Handlebars partials that should be registered
* @property {function(string,string): (string|Promise<string>)} partialWrapper the partial wrapper function.
* @property {object<function> helpers the Handlebars helpers that should be registered
* @property {object<{path:string,contents:string}>} templates
* @property {object} data the data object to render with Handlebars
Expand All @@ -64,6 +71,7 @@ module.exports = {

defaultConfig: {
partials: {},
partialWrapper: function (contents, name) { return contents },
helpers: {},
templates: {},
data: {},
Expand Down Expand Up @@ -92,6 +100,7 @@ module.exports = {

return {
partials: files(config.partials),
partialWrapper: config.partialWrapper && customize.withParent(config.partialWrapper),
helpers: helpers,
templates: files(config.templates),
data: data,
Expand Down Expand Up @@ -139,7 +148,7 @@ module.exports = {
// support helpers returning promises
var hbs = promisedHandlebars(Handlebars)

var partials = contents(config.partials)
var partials = _.mapValues(contents(config.partials), config.partialWrapper)
hbs.registerPartial(partials)
hbs.registerHelper(addEngine(config.helpers, hbs, config))
var templates = contents(config.templates)
Expand Down
39 changes: 39 additions & 0 deletions test/main-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,43 @@ describe('customize-engine-handlebars', function () {
})

xit('should throw an exception if loading an existing helpers module fails', function () {})

it('should apply the partial wrapper', function () {
var hb2 = hb.merge({
handlebars: {
partialWrapper: function (contents, name) {
return '[' + name + '] ' + contents + ' [/' + name + ']'
}
}
})
return expect(hb2.run()).to.eventually.deep.equal({
handlebars: {
'a.md': 'a.md [eins] testPartials1/eins ->one<- [/eins]',
'b.md': 'b.md [zwei] testPartials1/zwei ->two<- [/zwei] helper1(->two<-)'
}
})
})

it('the parent partial wrapper should be available through `this.parent()`', function () {
var hb2 = hb.merge({
handlebars: {
partialWrapper: function (contents, name) {
return '[' + name + '] ' + contents + ' [/' + name + ']'
}
}
})
.merge({
handlebars: {
partialWrapper: function (contents, name) {
return '(' + this.parent(contents, name) + ')'
}
}
})
return expect(hb2.run()).to.eventually.deep.equal({
handlebars: {
'a.md': 'a.md ([eins] testPartials1/eins ->one<- [/eins])',
'b.md': 'b.md ([zwei] testPartials1/zwei ->two<- [/zwei]) helper1(->two<-)'
}
})
})
})

0 comments on commit 3ae8822

Please sign in to comment.