Fixes #408 - Allow transformer to be registered at the template level

This commit is contained in:
Patrick Steele-Idem 2016-11-09 14:41:33 -07:00
parent 478211856e
commit a35e6bdbc3
10 changed files with 77 additions and 1 deletions

View File

@ -45,6 +45,12 @@ function transformTreeHelper(node, context) {
}
function transformTree(rootNode, context) {
context.taglibLookup.forEachTemplateTransformer((transformer) => {
var transformFunc = transformer.getFunc();
rootNode = transformFunc(rootNode, context) || rootNode;
});
/*
* The tree is continuously transformed until we go through an entire pass where
* there were no new nodes that needed to be transformed. This loop makes sure that

View File

@ -50,6 +50,7 @@ class Taglib {
this.dirname = null;
this.tags = {};
this.textTransformers = [];
this.transformers = [];
this.attributes = {};
this.patternAttributes = [];
this.inputFilesLookup = {};
@ -91,6 +92,9 @@ class Taglib {
addTextTransformer(transformer) {
this.textTransformers.push(transformer);
}
addTransformer(transformer) {
this.transformers.push(transformer);
}
forEachTag(callback, thisObj) {
forEachEntry(this.tags, function (key, tag) {
callback.call(thisObj, tag);

View File

@ -301,6 +301,33 @@ class TaglibLoader {
var taglib = this.taglib;
taglib.id = value;
}
transformer(value) {
// Marko allows a "text-transformer" to be registered. The provided
// text transformer will be called for any static text found in a template.
var taglib = this.taglib;
var dirname = this.dirname;
var transformer = new Taglib.Transformer();
if (typeof value === 'string') {
value = {
path: value
};
}
propertyHandlers(value, {
path(value) {
var path = resolve(value, dirname);
transformer.path = path;
}
}, this.dependencyChain.append('transformer').toString());
ok(transformer.path, '"path" is required for transformer');
taglib.addTransformer(transformer);
}
}
exports.loadTaglib = function(filePath, taglib, dependencyChain) {

View File

@ -143,6 +143,7 @@ class TaglibLookup {
merge(this.merged, {
tags: taglib.tags,
transformers: taglib.transformers,
textTransformers: taglib.textTransformers,
attributes: taglib.attributes,
patternAttributes: taglib.patternAttributes
@ -286,6 +287,13 @@ class TaglibLookup {
return attrDef;
}
forEachTemplateTransformer(callback, thisObj) {
var transformers = this.merged.transformers;
if (transformers && transformers.length) {
transformers.forEach(callback, thisObj);
}
}
forEachNodeTransformer(node, callback, thisObj) {
/*
* Based on the type of node we have to choose how to transform it
@ -332,7 +340,7 @@ class TaglibLookup {
this.merged.tags[tagName].forEachTransformer(addTransformer);
}
}
if (this.merged.tags['*']) {
this.merged.tags['*'].forEachTransformer(addTransformer);
}

View File

@ -0,0 +1,6 @@
<!--BEGIN: template.marko-->
<div>
<h1>Outer</h1>
<!--BEGIN: template-a.marko--><div><h1>Template A</h1></div><!--END: template-a.marko-->
<!--BEGIN: template-b.marko--><div><h1>Template B</h1></div><!--END: template-b.marko-->
</div><!--END: template.marko-->

View File

@ -0,0 +1,3 @@
{
"transformer": "./transformer"
}

View File

@ -0,0 +1,3 @@
<div>
<h1>Template A</h1>
</div>

View File

@ -0,0 +1,3 @@
<div>
<h1>Template B</h1>
</div>

View File

@ -0,0 +1,6 @@
<marko-compiler-options preserve-whitespace />
<div>
<h1>Outer</h1>
<include('./template-a.marko')/>
<include('./template-b.marko')/>
</div>

View File

@ -0,0 +1,10 @@
var path = require('path');
module.exports = function(rootNode, context) {
var builder = context.builder;
var templateName = path.basename(context.filename);
rootNode.prependChild(builder.htmlComment(builder.literal('BEGIN: ' + templateName)));
rootNode.appendChild(builder.htmlComment(builder.literal('END: ' + templateName)));
};