mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
170 lines
4.5 KiB
JavaScript
170 lines
4.5 KiB
JavaScript
'use strict';
|
|
// helpers provide a core set of various utility methods to compiled templates
|
|
var helpers;
|
|
|
|
/**
|
|
* Method is for internal usage only. This method
|
|
* is invoked by code in a compiled Marko template and
|
|
* it is used to create a new Template instance.
|
|
* @private
|
|
*/
|
|
exports.c = function createTemplate(path) {
|
|
return new Template(path);
|
|
};
|
|
|
|
var AsyncStream;
|
|
|
|
function createOut(globalData) {
|
|
return new AsyncStream(globalData);
|
|
}
|
|
|
|
// If the optional "stream" module is available
|
|
// then Readable will be a readable stream
|
|
|
|
var extend = require('raptor-util/extend');
|
|
|
|
exports.AsyncStream = AsyncStream;
|
|
|
|
function Template(path, func, options) {
|
|
this.path = path;
|
|
this._ = func;
|
|
this._shouldBuffer = !options || options.shouldBuffer !== false;
|
|
this.meta = undefined;
|
|
}
|
|
|
|
Template.prototype = {
|
|
createOut: createOut,
|
|
|
|
renderSync: function(data) {
|
|
var localData;
|
|
var globalData;
|
|
|
|
if ((localData = data)) {
|
|
globalData = localData.$global;
|
|
} else {
|
|
localData = {};
|
|
}
|
|
|
|
var out = new AsyncStream(globalData);
|
|
out.sync();
|
|
|
|
this._(localData, out);
|
|
return out.getOutput();
|
|
},
|
|
|
|
/**
|
|
* Renders a template to either a stream (if the last
|
|
* argument is a Stream instance) or
|
|
* provides the output to a callback function (if the last
|
|
* argument is a Function).
|
|
*
|
|
* Supported signatures:
|
|
*
|
|
* render(data, callback)
|
|
* render(data, out)
|
|
* render(data, stream)
|
|
* render(data, out, callback)
|
|
* render(data, stream, callback)
|
|
*
|
|
* @param {Object} data The view model data for the template
|
|
* @param {AsyncStream} out A Stream or an AsyncStream instance
|
|
* @param {Function} callback A callback function
|
|
* @return {AsyncStream} Returns the AsyncStream instance that the template is rendered to
|
|
*/
|
|
render: function(data, out, callback) {
|
|
var renderFunc = this._;
|
|
|
|
var finalData;
|
|
var globalData;
|
|
if (data) {
|
|
finalData = data;
|
|
|
|
if ((globalData = data.$global)) {
|
|
// We will *move* the "$global" property
|
|
// into the "out.global" object
|
|
data.$global = null;
|
|
}
|
|
} else {
|
|
finalData = {};
|
|
}
|
|
|
|
if (out) {
|
|
// The out can either be a callback function or AsyncStream...
|
|
if (out.isAsyncStream) {
|
|
if (callback) {
|
|
out
|
|
.on('finish', function() {
|
|
callback(null, out.getOutput(), out);
|
|
})
|
|
.once('error', callback);
|
|
}
|
|
|
|
if (globalData) {
|
|
extend(out.global, globalData);
|
|
}
|
|
|
|
renderFunc(finalData, out);
|
|
|
|
return out;
|
|
} else if (typeof out === 'function') {
|
|
callback = out;
|
|
out = null;
|
|
}
|
|
}
|
|
|
|
var shouldBuffer = this._shouldBuffer;
|
|
|
|
var finalOut = new AsyncStream(globalData, out, null, shouldBuffer);
|
|
|
|
if (callback) {
|
|
finalOut
|
|
.on('finish', function() {
|
|
callback(null, finalOut.getOutput(), finalOut);
|
|
})
|
|
.once('error', callback);
|
|
}
|
|
|
|
// Invoke the compiled template's render function to have it
|
|
// write out strings to the provided out.
|
|
renderFunc(finalData, finalOut);
|
|
|
|
// Automatically end output stream (the writer) if we
|
|
// had to create an async writer (which might happen
|
|
// if the caller did not provide a writer/out or the
|
|
// writer/out was not an AsyncStream).
|
|
//
|
|
// If out parameter was originally an AsyncStream then
|
|
// we assume that we are writing to output that was
|
|
// created in the context of another rendering job.
|
|
return finalOut.end();
|
|
},
|
|
|
|
stream: function() {
|
|
throw new Error('You must require("marko/stream")');
|
|
}
|
|
};
|
|
|
|
function createInlineMarkoTemplate(filename, renderFunc) {
|
|
return new Template(filename, renderFunc);
|
|
}
|
|
|
|
exports.createWriter = function(writer) {
|
|
return new AsyncStream(null, writer);
|
|
};
|
|
|
|
exports._inline = createInlineMarkoTemplate;
|
|
|
|
exports.createOut = createOut;
|
|
|
|
exports.Template = Template;
|
|
|
|
helpers = require('./helpers');
|
|
exports.helpers = helpers;
|
|
|
|
|
|
|
|
AsyncStream = require('./AsyncStream');
|
|
|
|
exports.enableAsyncStackTrace = AsyncStream.enableAsyncStackTrace;
|
|
|
|
require('../')._setRuntime(exports); |