Add post processing for templates

This commit is contained in:
Samy Pessé
2016-04-25 13:52:56 +02:00
parent 244fb0ca28
commit 4aed2cf652
6 changed files with 106 additions and 2 deletions
+23
View File
@@ -9,12 +9,24 @@ var NODE_ENDARGS = '%%endargs%%';
var blockBodies = {};
var TemplateBlock = Immutable.Record({
// Name of block, also the start tag
name: String(),
// End tag, default to "end<name>"
end: String(),
// Function to process the block content
process: Function(),
// List of String, for inner block tags
blocks: Immutable.List(),
// List of shortcuts to replace with this block
shortcuts: Immutable.List(),
// Function to execute in post processing
post: null,
parse: true
}, 'TemplateBlock');
@@ -208,6 +220,7 @@ TemplateBlock.prototype.handleBlockResult = function(result) {
if (is.string(result)) {
result = { body: result };
}
result.name = this.getName();
return result;
};
@@ -250,6 +263,16 @@ TemplateBlock.indexBlockResult = function(blk) {
return key;
};
/**
Get a block results indexed for a specific key
@param {String} key
@return {Object|undefined}
*/
TemplateBlock.getBlockResultByKey = function(key) {
return blockBodies[key];
};
/**
Create a template block from a function or an object
+13
View File
@@ -42,6 +42,19 @@ TemplateEngine.prototype.getContext = function() {
return this.get('context');
};
/**
Return a block by its name (or undefined)
@param {String} name
@return {TemplateBlock}
*/
TemplateEngine.prototype.getBlock = function(name) {
var blocks = this.getBlocks();
return blocks.find(function(block) {
return block.getName() === name;
});
};
/**
Return a nunjucks environment from this configuration
+6 -1
View File
@@ -14,6 +14,7 @@ var createTemplateEngine = require('./createTemplateEngine');
*/
function generatePage(output, page) {
var book = output.getBook();
var engine = createTemplateEngine(output);
return Parse.parsePage(book, page)
.then(function(resultPage) {
@@ -34,13 +35,17 @@ function generatePage(output, page) {
// Render templating syntax
.then(function(content) {
var engine = createTemplateEngine(output);
return Templating.render(engine, filePath, content);
})
// Render page using parser (markdown -> HTML)
.then(parser.page).get('content')
// Post processing for templating syntax
.then(function(content) {
return Templating.postRender(engine, content);
})
// Return new page
.then(function(content) {
return resultPage.set('content', content);
+2 -1
View File
@@ -1,4 +1,5 @@
module.exports = {
render: require('./render')
render: require('./render'),
postRender: require('./postRender')
};
+28
View File
@@ -0,0 +1,28 @@
var Promise = require('../utils/promise');
var replaceBlocks = require('./replaceBlocks');
/**
Post render a template:
- Execute "post" for blocks
- Replace block content
@param {TemplateEngine} engine
@param {String} content
@return {Promise<String>}
*/
function postRender(engine, content) {
var result = replaceBlocks(content);
return Promise.forEach(result.blocks, function(blockType) {
var block = engine.getBlock();
var post = block.getPost();
if (!post) {
return;
}
return post();
})
.thenResolve(result.content);
}
module.exports = postRender;
+34
View File
@@ -0,0 +1,34 @@
var Immutable = require('immutable');
var TemplateBlock = require('../models/templateBlock');
/**
Replace position markers of blocks by body after processing
This is done to avoid that markdown/asciidoc processer parse the block content
@param {String} content
@return {Object} {blocks: Set, content: String}
*/
function replaceBlocks(content) {
var blockTypes = new Immutable.Set();
var newContent = content.replace(/\{\{\-\%([\s\S]+?)\%\-\}\}/g, function(match, key) {
var replacedWith = match;
var block = TemplateBlock.getBlockResultByKey(key);
if (block) {
var result = replaceBlocks(block.body);
blockTypes = blockTypes.add(block.name);
blockTypes = blockTypes.concat(result.blocks);
replacedWith = result.content;
}
return replacedWith;
});
return {
content: newContent,
blocks: blockTypes
};
}
module.exports = replaceBlocks;