mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Renamed "context" to "out"
This commit is contained in:
parent
6b603568aa
commit
33ab7744a9
81
README.md
81
README.md
@ -17,7 +17,7 @@ Marko is an extensible, streaming, asynchronous, [high performance](https://gith
|
||||
- [Callback API](#callback-api)
|
||||
- [Streaming API](#streaming-api)
|
||||
- [Synchronous API](#synchronous-api)
|
||||
- [Asynchronous Render Context API](#asynchronous-render-context-api)
|
||||
- [Asynchronous Rendering API](#asynchronous-rendering-api)
|
||||
- [Browser-side Rendering](#browser-side-rendering)
|
||||
- [Using the RaptorJS Optimizer](#using-the-raptorjs-optimizer)
|
||||
- [Using Browserify](#using-browserify)
|
||||
@ -69,7 +69,7 @@ Marko is an extensible, streaming, asynchronous, [high performance](https://gith
|
||||
|
||||
Most front-end developers are familiar with, and comfortable with, templating languages such as [Handlebars](https://github.com/wycats/handlebars.js), [Dust](https://github.com/linkedin/dustjs) or [Mustache](http://mustache.github.io/) so why was Marko introduced?
|
||||
|
||||
What makes Marko different is that it is an HTML-based templating language that does not rely on a custom language grammar. Any HTML file is a valid Marko template and vice-versa, and the Marko compiler uses an [off-the-shelf HTML parser](https://github.com/fb55/htmlparser2). Because Marko understands the HTML structure of the templates, it can do more powerful things that would not be possible in a text-based templating languages such as Handlerbars, Dust or Mustache. Marko allows developers to _extend the HTML language_ by introducing custom HTML elements and attributes. On top of that, utilizing the HTML structure for applying templating directives makes templates more readable and allows input templates to more closely resemble the final HTML structure.
|
||||
What makes Marko different is that it is an HTML-based templating language that does not rely on a custom language grammar. Any HTML file is a valid Marko template and vice-versa, and the Marko compiler uses an [off-the-shelf HTML parser](https://github.com/fb55/htmlparser2). Because Marko understands the HTML structure of the templates, it can do more powerful things that would not be possible in a text-based templating languages such as Handlerbars, Dust or Mustache. Marko allows developers to _extend the HTML language_ by introducing custom HTML elements and attributes. On top of that, utilizing the HTML structure for applying templating directives makes templates more readable and allows data templates to more closely resemble the final HTML structure.
|
||||
|
||||
Let's compare Marko with Handlebars (a text-based templating language):
|
||||
|
||||
@ -176,7 +176,7 @@ Hello World!
|
||||
</ul>
|
||||
```
|
||||
|
||||
For comparison, given the following input data consisting of an empty array of colors:
|
||||
For comparison, given the following data data consisting of an empty array of colors:
|
||||
|
||||
```javascript
|
||||
{
|
||||
@ -331,7 +331,7 @@ var output = template.renderSync({
|
||||
console.log('Output HTML: ' + output);
|
||||
```
|
||||
|
||||
### Asynchronous Render Context API
|
||||
### Asynchronous Rendering API
|
||||
|
||||
```javascript
|
||||
var marko = require('marko');
|
||||
@ -339,26 +339,26 @@ var template = marko.load('template.marko');
|
||||
|
||||
var out = require('fs').createWriteStream('index.html', 'utf8');
|
||||
|
||||
var context = marko.createContext(out);
|
||||
var out = marko.createWriter(out);
|
||||
|
||||
// Render the first chunk asynchronously (after 1s delay):
|
||||
var asyncContext = context.beginAsync();
|
||||
var asyncOut = out.beginAsync();
|
||||
setTimeout(function() {
|
||||
asyncContext.write('BEGIN ');
|
||||
asyncContext.end();
|
||||
asyncOut.write('BEGIN ');
|
||||
asyncOut.end();
|
||||
}, 1000);
|
||||
|
||||
// Render the template to the existing render context:
|
||||
// Render the template to the original writer:
|
||||
template.render({
|
||||
name: 'World'
|
||||
},
|
||||
context);
|
||||
out);
|
||||
|
||||
// Write the last chunk synchronously:
|
||||
context.write(' END');
|
||||
out.write(' END');
|
||||
|
||||
// End the rendering context
|
||||
context.end();
|
||||
// End the rendering out
|
||||
out.end();
|
||||
```
|
||||
|
||||
Despite rendering the first chunk asynchronously, the above program will stream out the output in the correct order to `index.html`:
|
||||
@ -367,7 +367,7 @@ Despite rendering the first chunk asynchronously, the above program will stream
|
||||
BEGIN Hello World! END
|
||||
```
|
||||
|
||||
For more details, please see the documentation for the [raptor-render-context](https://github.com/raptorjs3/raptor-render-context) module.
|
||||
For more details, please see the documentation for the [async-writer](https://github.com/raptorjs3/async-writer) module.
|
||||
|
||||
## Browser-side Rendering
|
||||
|
||||
@ -425,7 +425,7 @@ browserify -t markoify run.js > browser.js
|
||||
|
||||
## Template Compilation
|
||||
|
||||
The Marko compiler produces a Node.js-compatible, CommonJS module as output. This output format has the advantage that compiled template modules can benefit from a context-aware module loader and templates can easily be transported to work in the browser using the [RaptorJS Optimizer](https://github.com/raptorjs3/optimizer) or [Browserify](https://github.com/substack/node-browserify).
|
||||
The Marko compiler produces a Node.js-compatible, CommonJS module as output. This output format has the advantage that compiled template modules can benefit from a out-aware module loader and templates can easily be transported to work in the browser using the [RaptorJS Optimizer](https://github.com/raptorjs3/optimizer) or [Browserify](https://github.com/substack/node-browserify).
|
||||
|
||||
The `marko` module will automatically compile templates loaded by your application on the server, but you can also choose to precompile all templates. This can be helpful as a build or test step to catch errors early.
|
||||
|
||||
@ -474,26 +474,26 @@ module.exports = function create(__helpers) {
|
||||
forEach = __helpers.f,
|
||||
escapeXmlAttr = __helpers.xa;
|
||||
|
||||
return function render(data, context) {
|
||||
context.w('Hello ' +
|
||||
return function render(data, out) {
|
||||
out.w('Hello ' +
|
||||
escapeXml(data.name) +
|
||||
'! ');
|
||||
|
||||
if (notEmpty(data.colors)) {
|
||||
context.w('<ul>');
|
||||
out.w('<ul>');
|
||||
|
||||
forEach(data.colors, function(color) {
|
||||
context.w('<li style="color: ' +
|
||||
out.w('<li style="color: ' +
|
||||
escapeXmlAttr(color) +
|
||||
'">' +
|
||||
escapeXml(color) +
|
||||
'</li>');
|
||||
});
|
||||
|
||||
context.w('</ul>');
|
||||
out.w('</ul>');
|
||||
}
|
||||
else {
|
||||
context.w('<div>No colors!</div>');
|
||||
out.w('<div>No colors!</div>');
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -624,6 +624,15 @@ Input data passed to a template is made available using a special `data` variabl
|
||||
<var name="name" value="data.name.toUpperCase()" />
|
||||
```
|
||||
|
||||
The `<with>` directive can be used to create scoped variables as shown in the following sample code:
|
||||
|
||||
```html
|
||||
<with vars="nameUpper=data.name.toUpperCase(); nameLower=data.name.toLowerCase()">
|
||||
Hello $nameUpper!
|
||||
Hello $nameLower!
|
||||
</with>
|
||||
```
|
||||
|
||||
## Conditionals
|
||||
|
||||
### if...else-if...else
|
||||
@ -859,7 +868,7 @@ The above macro can then be invoked as part of any expression. Alternatively, th
|
||||
|
||||
### invoke
|
||||
|
||||
The `<invoke>` directive can be used to invoke a function defined using the `<def>` directive or a function that is part of the input to a template. The `<invoke>` directive allows arguments to be passed using element attributes, but that format is only supported for functions that were previously defined using the `<def>` directive.
|
||||
The `<invoke>` directive can be used to invoke a function defined using the `<def>` directive or a function that is part of the input data to a template. The `<invoke>` directive allows arguments to be passed using element attributes, but that format is only supported for functions that were previously defined using the `<def>` directive.
|
||||
|
||||
```html
|
||||
<def function="greeting(name, count)">
|
||||
@ -1067,23 +1076,23 @@ For more details, please see [https://github.com/raptorjs3/marko-taglib-layout](
|
||||
|
||||
## Tag Renderer
|
||||
|
||||
Every tag should be mapped to a "renderer". A renderer is just a function that takes two arguments (`input` and `context`). The `input` argument is an arbitrary object that contains the input data for the renderer. The `context` argument is an [asynchronous rendering context](https://github.com/raptorjs3/raptor-render-context) that wraps an output stream. Output can be produced using `context.write(someString)` There is no class hierarchy or tie-ins to Marko when implementing a tag renderer. A simple tag renderer is shown below:
|
||||
Every tag should be mapped to a "renderer". A renderer is just a function that takes two arguments (`data` and `out`). The `data` argument is an arbitrary object that contains the data data for the renderer. The `out` argument is an [asynchronous rendering out](https://github.com/raptorjs3/async-writer) that wraps an output stream. Output can be produced using `out.write(someString)` There is no class hierarchy or tie-ins to Marko when implementing a tag renderer. A simple tag renderer is shown below:
|
||||
|
||||
```javascript
|
||||
module.exports = function(input, context) {
|
||||
context.write('Hello ' + input.name + '!');
|
||||
module.exports = function(data, out) {
|
||||
out.write('Hello ' + data.name + '!');
|
||||
}
|
||||
```
|
||||
|
||||
If, and only if, a tag has nested content, then a special `invokeBody` method will be added to the `input` object. If a renderer wants to render the nested body content then it must call the `invokeBody` method. For example:
|
||||
If, and only if, a tag has nested content, then a special `invokeBody` method will be added to the `data` object. If a renderer wants to render the nested body content then it must call the `invokeBody` method. For example:
|
||||
|
||||
```javascript
|
||||
module.exports = function(input, context) {
|
||||
context.write('BEFORE BODY');
|
||||
if (input.invokeBody) {
|
||||
input.invokeBody();
|
||||
module.exports = function(data, out) {
|
||||
out.write('BEFORE BODY');
|
||||
if (data.invokeBody) {
|
||||
data.invokeBody();
|
||||
}
|
||||
context.write('AFTER BODY');
|
||||
out.write('AFTER BODY');
|
||||
}
|
||||
```
|
||||
|
||||
@ -1248,11 +1257,11 @@ _components/tabs/renderer.js:_
|
||||
var templatePath = require.resolve('./template.marko');
|
||||
var template = require('marko').load(templatePath);
|
||||
|
||||
module.exports = function render(input, context) {
|
||||
module.exports = function render(data, out) {
|
||||
var nestedTabs = [];
|
||||
|
||||
// Invoke the body function to discover nested <ui-tab> tags
|
||||
input.invokeBody({ // Invoke the body with the scoped "tabs" variable
|
||||
data.invokeBody({ // Invoke the body with the scoped "tabs" variable
|
||||
addTab: function(tab) {
|
||||
tab.id = tab.id || ("tab" + tabs.length);
|
||||
nestedTabs.push(tab);
|
||||
@ -1262,16 +1271,16 @@ module.exports = function render(input, context) {
|
||||
// Now render the markup for the tabs:
|
||||
template.render({
|
||||
tabs: nestedTabs
|
||||
}, context);
|
||||
}, out);
|
||||
};
|
||||
```
|
||||
|
||||
_components/tab/renderer.js:_
|
||||
|
||||
```javascript
|
||||
module.exports = function render(input, context) {
|
||||
module.exports = function render(data, out) {
|
||||
// Register with parent but don't render anything
|
||||
input.tabs.addTab(input);
|
||||
data.tabs.addTab(data);
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@ -135,9 +135,9 @@ Node.prototype = {
|
||||
var methodCall;
|
||||
|
||||
if (escapeXml !== false) {
|
||||
methodCall = 'context.captureString(';
|
||||
methodCall = 'out.captureString(';
|
||||
} else {
|
||||
methodCall = '__helpers.c(context, ';
|
||||
methodCall = '__helpers.c(out, ';
|
||||
}
|
||||
|
||||
return template.makeExpression({
|
||||
@ -531,4 +531,4 @@ Node.prototype = {
|
||||
return this.escapeXmlContext;
|
||||
}
|
||||
};
|
||||
module.exports = Node;
|
||||
module.exports = Node;
|
||||
|
||||
@ -74,7 +74,7 @@ CodeWriter.prototype = {
|
||||
if (!this._bufferedWrites) {
|
||||
this._bufferedWrites = [];
|
||||
}
|
||||
|
||||
|
||||
this._bufferedWrites.push(expression);
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ CodeWriter.prototype = {
|
||||
|
||||
function concat() {
|
||||
|
||||
code.append(_this.indentStr() + 'context.w(');
|
||||
code.append(_this.indentStr() + 'out.w(');
|
||||
|
||||
_bufferedWrites.forEach(function (expression, i) {
|
||||
if (i !== 0) {
|
||||
@ -178,9 +178,9 @@ CodeWriter.prototype = {
|
||||
|
||||
function chain() {
|
||||
_bufferedWrites.forEach(function (arg, i) {
|
||||
|
||||
|
||||
if (i === 0) {
|
||||
this._code.append(this.indentStr() + 'context.w(');
|
||||
this._code.append(this.indentStr() + 'out.w(');
|
||||
} else {
|
||||
this.incIndent();
|
||||
this._code.append(this.indentStr() + '.w(');
|
||||
@ -211,7 +211,7 @@ CodeWriter.prototype = {
|
||||
} else {
|
||||
chain();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
incIndent: function (delta) {
|
||||
@ -270,7 +270,7 @@ TemplateBuilder.prototype = {
|
||||
}
|
||||
},
|
||||
getStaticHelperFunction: function (varName, propName) {
|
||||
|
||||
|
||||
var added = this.helperFunctionsAdded[propName];
|
||||
if (added) {
|
||||
return added;
|
||||
@ -285,7 +285,7 @@ TemplateBuilder.prototype = {
|
||||
},
|
||||
addStaticVar: function (name, expression) {
|
||||
name = safeVarName(name);
|
||||
|
||||
|
||||
if (!this.staticVarsLookup.hasOwnProperty(name)) {
|
||||
this.staticVarsLookup[name] = true;
|
||||
this.staticVars.push({
|
||||
@ -300,7 +300,7 @@ TemplateBuilder.prototype = {
|
||||
},
|
||||
addVar: function (name, expression) {
|
||||
name = safeVarName(name);
|
||||
|
||||
|
||||
this.vars[name] = true;
|
||||
this.vars.push({
|
||||
name: name,
|
||||
@ -354,7 +354,7 @@ TemplateBuilder.prototype = {
|
||||
if (!this.hasExpression(templatePath)) {
|
||||
// Resolve the static string to a full path only once
|
||||
templateVar = this.addStaticVar(templatePath, '__helpers.l(require.resolve(' + this.compiler.convertType(templatePath, 'string', true) + '))');
|
||||
this.statement(this.makeExpression(templateVar + '.render(' + dataExpression + ', context);'));
|
||||
this.statement(this.makeExpression(templateVar + '.render(' + dataExpression + ', out);'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -379,7 +379,7 @@ TemplateBuilder.prototype = {
|
||||
contextHelperMethodCall: function (methodName, args) {
|
||||
if (!this.hasErrors()) {
|
||||
args = arrayFromArguments(arguments, 1);
|
||||
args.unshift('context');
|
||||
args.unshift('out');
|
||||
this.writer.functionCall('__helpers.' + methodName, args);
|
||||
}
|
||||
return this;
|
||||
@ -444,18 +444,18 @@ TemplateBuilder.prototype = {
|
||||
return '';
|
||||
}
|
||||
var out = new StringBuilder();
|
||||
|
||||
|
||||
var params = this.params;
|
||||
if (params) {
|
||||
params = ['context'].concat(params);
|
||||
params = ['out'].concat(params);
|
||||
} else {
|
||||
params = ['context'];
|
||||
params = ['out'];
|
||||
}
|
||||
out.append('module.exports = function create(__helpers) {\n');
|
||||
//Write out the static variables
|
||||
this.writer.flush();
|
||||
this._writeVars(this.staticVars, out, INDENT);
|
||||
out.append('\n' + INDENT + 'return function render(data, context) {\n');
|
||||
out.append('\n' + INDENT + 'return function render(data, out) {\n');
|
||||
//Write out the render variables
|
||||
if (this.vars && this.vars.length) {
|
||||
this._writeVars(this.vars, out, INDENT + INDENT);
|
||||
@ -510,4 +510,4 @@ TemplateBuilder.prototype = {
|
||||
},
|
||||
INDENT: INDENT
|
||||
};
|
||||
module.exports = TemplateBuilder;
|
||||
module.exports = TemplateBuilder;
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
"raptor-polyfill": "^1.0.0-beta",
|
||||
"raptor-promises": "^1.0.0-beta",
|
||||
"raptor-regexp": "^1.0.0-beta",
|
||||
"raptor-render-context": "^1.0.0-beta",
|
||||
"async-writer": "^1.0.0-beta",
|
||||
"raptor-strings": "^1.0.0-beta",
|
||||
"marko-taglib-async": "^1.1.0",
|
||||
"marko-taglib-layout": "^1.1.0",
|
||||
@ -56,4 +56,4 @@
|
||||
"registry": "https://registry.npmjs.org/"
|
||||
},
|
||||
"version": "1.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,14 +20,14 @@
|
||||
* <p>The code for the Marko compiler is kept separately
|
||||
* in the {@link raptor/templating/compiler} module.
|
||||
*/
|
||||
var renderContext = require('raptor-render-context');
|
||||
var Context = renderContext.Context;
|
||||
var asyncWriter = require('async-writer');
|
||||
var helpers = require('./helpers');
|
||||
var loader = require('./loader');
|
||||
var cache = {};
|
||||
var Readable;
|
||||
var AsyncWriter = asyncWriter.AsyncWriter;
|
||||
|
||||
exports.Context = Context;
|
||||
exports.AsyncWriter = AsyncWriter;
|
||||
|
||||
|
||||
var stream;
|
||||
@ -43,16 +43,16 @@ if (streamPath) {
|
||||
}
|
||||
|
||||
|
||||
function renderWithCallback(template, data, context, callback) {
|
||||
context
|
||||
function renderWithCallback(template, data, out, callback) {
|
||||
out
|
||||
.on('end', function() {
|
||||
callback(null, context.getOutput());
|
||||
callback(null, out.getOutput());
|
||||
})
|
||||
.on('error', callback);
|
||||
|
||||
template._(data, context); //Invoke the template rendering function with the required arguments
|
||||
template._(data, out); //Invoke the template rendering function with the required arguments
|
||||
|
||||
context.end();
|
||||
out.end();
|
||||
}
|
||||
|
||||
function Template(renderFunc) {
|
||||
@ -61,13 +61,13 @@ function Template(renderFunc) {
|
||||
|
||||
Template.prototype = {
|
||||
renderSync: function(data) {
|
||||
var context = new Context();
|
||||
context.sync();
|
||||
this._(data, context);
|
||||
context.end();
|
||||
return context.getOutput();
|
||||
var out = new AsyncWriter();
|
||||
out.sync();
|
||||
this._(data, out);
|
||||
out.end();
|
||||
return out.getOutput();
|
||||
},
|
||||
render: function(data, context, callback) {
|
||||
render: function(data, out, callback) {
|
||||
if (data == null) {
|
||||
data = {};
|
||||
}
|
||||
@ -75,23 +75,23 @@ Template.prototype = {
|
||||
// callback is last argument if provided
|
||||
callback = arguments[arguments.length - 1];
|
||||
if (typeof callback === 'function') {
|
||||
if (arguments.length === 2) { // data, context, callback
|
||||
callback = context;
|
||||
context = new Context();
|
||||
if (arguments.length === 2) { // data, out, callback
|
||||
callback = out;
|
||||
out = new AsyncWriter();
|
||||
}
|
||||
renderWithCallback(this, data, context, callback);
|
||||
renderWithCallback(this, data, out, callback);
|
||||
} else {
|
||||
if (context.isRenderContext) {
|
||||
this._(data, context);
|
||||
if (out.isRenderContext) {
|
||||
this._(data, out);
|
||||
} else {
|
||||
// Assume the "context" is really a stream
|
||||
context = new Context(context);
|
||||
this._(data, context);
|
||||
context.end(); // End the context and the underlying stream
|
||||
// Assume the "out" is really a stream
|
||||
out = new AsyncWriter(out);
|
||||
this._(data, out);
|
||||
out.end(); // End the out and the underlying stream
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
return out;
|
||||
},
|
||||
stream: function(data) {
|
||||
if (!stream) {
|
||||
@ -131,9 +131,9 @@ if (stream) {
|
||||
var template = this._t;
|
||||
var data = this._d;
|
||||
|
||||
var context = exports.createContext(this);
|
||||
template.render(data, context);
|
||||
context.end();
|
||||
var out = exports.createWriter(this);
|
||||
template.render(data, out);
|
||||
out.end();
|
||||
}
|
||||
};
|
||||
|
||||
@ -158,8 +158,8 @@ function load(templatePath) {
|
||||
|
||||
exports.load = load;
|
||||
|
||||
exports.render = function (templatePath, data, context) {
|
||||
return load(templatePath).render(data, context);
|
||||
exports.render = function (templatePath, data, out) {
|
||||
return load(templatePath).render(data, out);
|
||||
};
|
||||
|
||||
exports.stream = function(templatePath, data) {
|
||||
@ -170,8 +170,8 @@ exports.unload = function(templatePath) {
|
||||
delete cache[templatePath];
|
||||
};
|
||||
|
||||
exports.createContext = function(writer) {
|
||||
return new Context(writer);
|
||||
exports.createWriter = function(writer) {
|
||||
return new AsyncWriter(writer);
|
||||
};
|
||||
|
||||
exports.helpers = helpers;
|
||||
|
||||
@ -5,7 +5,7 @@ var req = require; // Fool the optimizer
|
||||
|
||||
|
||||
module.exports = {
|
||||
render: function (input, context) {
|
||||
render: function (input, out) {
|
||||
if (raptorCache === undefined) {
|
||||
try {
|
||||
raptorCache = req('raptor-cache');
|
||||
@ -25,7 +25,7 @@ module.exports = {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var cacheKey = input.cacheKey;
|
||||
if (!cacheKey) {
|
||||
throw new Error('cache-key is required for <cached-fragment>');
|
||||
@ -34,13 +34,13 @@ module.exports = {
|
||||
var cacheManager = input.cacheManager || defaultCacheManager;
|
||||
|
||||
var cache = cacheManager.getCache(input.cacheName || 'marko/cached-fragment');
|
||||
|
||||
var asyncContext = context.beginAsync();
|
||||
|
||||
|
||||
var asyncContext = out.beginAsync();
|
||||
|
||||
cache.get(cacheKey,
|
||||
{
|
||||
builder: function(callback) {
|
||||
var result = context.captureString(function () {
|
||||
var result = out.captureString(function () {
|
||||
if (input.invokeBody) {
|
||||
input.invokeBody();
|
||||
}
|
||||
@ -51,7 +51,7 @@ module.exports = {
|
||||
if (err) {
|
||||
return asyncContext.error(err);
|
||||
}
|
||||
|
||||
|
||||
asyncContext.end(result);
|
||||
});
|
||||
}
|
||||
|
||||
@ -51,13 +51,13 @@ DefNode.prototype = {
|
||||
if (func.indexOf('(') === -1) {
|
||||
func += '()';
|
||||
}
|
||||
|
||||
|
||||
template.statement('function ' + func + ' {').indent(function () {
|
||||
template.line('return __helpers.c(context, function() {').indent(function () {
|
||||
template.line('return __helpers.c(out, function() {').indent(function () {
|
||||
this.generateCodeForChildren(template);
|
||||
}, this).line('});');
|
||||
}, this).line('}');
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = DefNode;
|
||||
module.exports = DefNode;
|
||||
|
||||
@ -50,7 +50,7 @@ function getPropsStr(props, template) {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (propsArray.length) {
|
||||
return '{\n' + propsArray.join(',\n') + '\n' + template.indentStr() + '}';
|
||||
} else {
|
||||
@ -107,7 +107,7 @@ TagHandlerNode.prototype = {
|
||||
this.tag.forEachImportedVariable(function (importedVariable) {
|
||||
this.setProperty(importedVariable.targetProperty, template.makeExpression(importedVariable.expression));
|
||||
}, this);
|
||||
|
||||
|
||||
var _this = this;
|
||||
var variableNames = [];
|
||||
_this.tag.forEachVariable(function (nestedVar) {
|
||||
@ -149,7 +149,7 @@ TagHandlerNode.prototype = {
|
||||
}
|
||||
|
||||
template.functionCall(tagHelperVar, function () {
|
||||
template.code('context,\n').indent(function () {
|
||||
template.code('out,\n').indent(function () {
|
||||
template.line(handlerVar + ',').indent();
|
||||
if (_this.inputExpression) {
|
||||
template.code(_this.inputExpression);
|
||||
@ -176,4 +176,4 @@ TagHandlerNode.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = TagHandlerNode;
|
||||
module.exports = TagHandlerNode;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
module.exports = function render(input, context) {
|
||||
context.write('<!--');
|
||||
module.exports = function render(input, out) {
|
||||
out.write('<!--');
|
||||
if (input.invokeBody) {
|
||||
input.invokeBody();
|
||||
}
|
||||
context.write('-->');
|
||||
};
|
||||
out.write('-->');
|
||||
};
|
||||
|
||||
@ -35,7 +35,7 @@ describe('marko/api' , function() {
|
||||
});
|
||||
|
||||
it('should allow a template to be rendered to a context wrapping a string builder', function(done) {
|
||||
var context = marko.createContext();
|
||||
var context = marko.createWriter();
|
||||
context
|
||||
.on('end', function() {
|
||||
expect(context.getOutput()).to.equal('Hello John!');
|
||||
@ -62,7 +62,7 @@ describe('marko/api' , function() {
|
||||
output += data;
|
||||
});
|
||||
|
||||
var context = marko.createContext(stream);
|
||||
var context = marko.createWriter(stream);
|
||||
context
|
||||
.on('end', function() {
|
||||
expect(output).to.equal('Hello John!');
|
||||
@ -125,7 +125,7 @@ describe('marko/api' , function() {
|
||||
});
|
||||
|
||||
it('should allow a template to be loaded and rendered to a context wrapping a string builder', function(done) {
|
||||
var context = marko.createContext();
|
||||
var context = marko.createWriter();
|
||||
context
|
||||
.on('end', function() {
|
||||
expect(context.getOutput()).to.equal('Hello John!');
|
||||
@ -152,7 +152,7 @@ describe('marko/api' , function() {
|
||||
output += data;
|
||||
});
|
||||
|
||||
var context = marko.createContext(stream);
|
||||
var context = marko.createWriter(stream);
|
||||
context
|
||||
.on('end', function() {
|
||||
expect(output).to.equal('Hello John!');
|
||||
|
||||
@ -52,7 +52,7 @@ function testRender(path, data, done, options) {
|
||||
} catch(e) {
|
||||
return done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('marko/dust' , function() {
|
||||
@ -98,4 +98,3 @@ describe('marko/dust' , function() {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ function testRender(path, data, done, options) {
|
||||
|
||||
var compiler = require('../compiler').createCompiler(inputPath);
|
||||
var src = fs.readFileSync(inputPath, {encoding: 'utf8'});
|
||||
|
||||
|
||||
var compiledSrc = compiler.compile(src);
|
||||
fs.writeFileSync(compiledPath, compiledSrc, {encoding: 'utf8'});
|
||||
|
||||
@ -34,22 +34,22 @@ function testRender(path, data, done, options) {
|
||||
|
||||
// console.log('\nCompiled (' + inputPath + '):\n---------\n' + compiledSrc);
|
||||
|
||||
|
||||
|
||||
|
||||
var marko = require('../');
|
||||
var Context = marko.Context;
|
||||
var context = options.context || new Context(new StringBuilder());
|
||||
var AsyncWriter = marko.AsyncWriter;
|
||||
var out = options.out || new AsyncWriter(new StringBuilder());
|
||||
|
||||
require('../compiler').defaultOptions.checkUpToDate = false;
|
||||
|
||||
|
||||
if (options.dataProviders) {
|
||||
var dataProviders = require('raptor-data-providers').forContext(context);
|
||||
var dataProviders = require('raptor-data-providers').forContext(out);
|
||||
dataProviders.register(options.dataProviders);
|
||||
}
|
||||
|
||||
marko.render(inputPath, data, context)
|
||||
marko.render(inputPath, data, out)
|
||||
.on('end', function() {
|
||||
var output = context.getOutput();
|
||||
var output = out.getOutput();
|
||||
|
||||
fs.writeFileSync(actualPath, output, {encoding: 'utf8'});
|
||||
|
||||
@ -72,7 +72,7 @@ function testRender(path, data, done, options) {
|
||||
.on('error', done)
|
||||
.end();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
describe('marko/marko-async' , function() {
|
||||
@ -99,7 +99,7 @@ describe('marko/marko-async' , function() {
|
||||
'D3': delayedDataProvider(200),
|
||||
'D4': delayedDataProvider(800)
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a simple template with async fragments correctly (2)', function(done) {
|
||||
@ -110,7 +110,7 @@ describe('marko/marko-async' , function() {
|
||||
'D3': delayedDataProvider(300),
|
||||
'D4': delayedDataProvider(150)
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a simple template with async fragments correctly (3)', function(done) {
|
||||
@ -121,7 +121,7 @@ describe('marko/marko-async' , function() {
|
||||
'D3': delayedDataProvider(300),
|
||||
'D4': delayedDataProvider(100)
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a simple template with async fragments correctly (4)', function(done) {
|
||||
@ -132,7 +132,7 @@ describe('marko/marko-async' , function() {
|
||||
'D3': delayedDataProvider(200),
|
||||
'D4': delayedDataProvider(100)
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a less simple template with async fragments correctly (1)', function(done) {
|
||||
@ -146,7 +146,7 @@ describe('marko/marko-async' , function() {
|
||||
'D6': delayedDataProvider(100),
|
||||
'D7': delayedDataProvider(50)
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a less simple template with async fragments correctly (2)', function(done) {
|
||||
@ -160,7 +160,7 @@ describe('marko/marko-async' , function() {
|
||||
'D6': delayedDataProvider(100),
|
||||
'D7': delayedDataProvider(200)
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a less simple template with async fragments correctly (3)', function(done) {
|
||||
@ -174,7 +174,7 @@ describe('marko/marko-async' , function() {
|
||||
'D6': delayedDataProvider(100),
|
||||
'D7': delayedDataProvider(200)
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow for using macros inside async fragments", function(done) {
|
||||
@ -182,10 +182,10 @@ describe('marko/marko-async' , function() {
|
||||
dataProviders: {
|
||||
'D1': delayedDataProvider(100)
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow for shared and context-specific data providers", function(done) {
|
||||
it("should allow for global data providers", function(done) {
|
||||
require('raptor-data-providers').register({
|
||||
'sharedData': function(args, done) {
|
||||
var deferred = require('raptor-promises').defer();
|
||||
@ -303,4 +303,3 @@ describe('marko/marko-async' , function() {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@ -30,12 +30,12 @@ function testRender(path, data, done, options) {
|
||||
|
||||
require('../compiler').defaultOptions.checkUpToDate = false;
|
||||
|
||||
var Context = marko.Context;
|
||||
var context = options.context || new Context(new StringBuilder());
|
||||
var AsyncWriter = marko.AsyncWriter;
|
||||
var out = options.out || new AsyncWriter(new StringBuilder());
|
||||
|
||||
marko.render(inputPath, data, context)
|
||||
marko.render(inputPath, data, out)
|
||||
.on('end', function() {
|
||||
var output = context.getOutput();
|
||||
var output = out.getOutput();
|
||||
|
||||
fs.writeFileSync(actualPath, output, {encoding: 'utf8'});
|
||||
|
||||
@ -273,31 +273,6 @@ describe('marko/marko' , function() {
|
||||
testRender("test-project/html-templates/dynamic-attributes3.marko", {}, done);
|
||||
});
|
||||
|
||||
// it("should allow for nodes to be converted to expressions", function(done) {
|
||||
// var ElementNode = require('raptor/templating/compiler/ElementNode');
|
||||
// var TextNode = require('raptor/templating/compiler/TextNode');
|
||||
// var TemplateBuilder = require('raptor/templating/compiler/TemplateBuilder');
|
||||
|
||||
// var compiler = require('raptor/templating/compiler').createCompiler();
|
||||
// var template = new TemplateBuilder(compiler);
|
||||
|
||||
// var div = new ElementNode("div");
|
||||
// var text = new TextNode("Hello World!");
|
||||
// div.appendChild(text);
|
||||
|
||||
// var expression = div.getExpression(template).toString();
|
||||
// var bodyContentExpression = div.getBodyContentExpression(template).toString();
|
||||
|
||||
// var sb = require('raptor/strings').createStringBuilder();
|
||||
// var context = require('raptor/templating').createContext(sb);
|
||||
// var output = eval(expression);
|
||||
// expect(output.toString()).toEqual('<div>Hello World!</div>');
|
||||
|
||||
// output = eval(bodyContentExpression);
|
||||
// expect(output.toString()).toEqual('Hello World!');
|
||||
|
||||
// });
|
||||
|
||||
it("should allow for nested attributes", function(done) {
|
||||
testRender("test-project/html-templates/nested-attrs.marko", {active: true}, done);
|
||||
});
|
||||
|
||||
@ -27,12 +27,12 @@ function testRender(path, data, done, options) {
|
||||
require('../compiler').defaultOptions.checkUpToDate = false;
|
||||
|
||||
var marko = require('../');
|
||||
var Context = marko.Context;
|
||||
var context = options.context || new Context(new StringBuilder());
|
||||
var AsyncWriter = marko.AsyncWriter;
|
||||
var out = options.out || new AsyncWriter(new StringBuilder());
|
||||
|
||||
marko.render(inputPath, data, context)
|
||||
marko.render(inputPath, data, out)
|
||||
.on('end', function() {
|
||||
var output = context.getOutput();
|
||||
var output = out.getOutput();
|
||||
|
||||
fs.writeFileSync(actualPath, output, {encoding: 'utf8'});
|
||||
|
||||
@ -253,31 +253,6 @@ describe('marko/xml' , function() {
|
||||
testRender("test-project/xml-templates/dynamic-attributes3.marko.xml", {}, done);
|
||||
});
|
||||
|
||||
// it("should allow for nodes to be converted to expressions", function(done) {
|
||||
// var ElementNode = require('raptor/templating/compiler/ElementNode');
|
||||
// var TextNode = require('raptor/templating/compiler/TextNode');
|
||||
// var TemplateBuilder = require('raptor/templating/compiler/TemplateBuilder');
|
||||
|
||||
// var compiler = require('raptor/templating/compiler').createCompiler();
|
||||
// var template = new TemplateBuilder(compiler);
|
||||
|
||||
// var div = new ElementNode("div");
|
||||
// var text = new TextNode("Hello World!");
|
||||
// div.appendChild(text);
|
||||
|
||||
// var expression = div.getExpression(template).toString();
|
||||
// var bodyContentExpression = div.getBodyContentExpression(template).toString();
|
||||
|
||||
// var sb = require('raptor/strings').createStringBuilder();
|
||||
// var context = require('raptor/templating').createContext(sb);
|
||||
// var output = eval(expression);
|
||||
// expect(output.toString()).toEqual('<div>Hello World!</div>');
|
||||
|
||||
// output = eval(bodyContentExpression);
|
||||
// expect(output.toString()).toEqual('Hello World!');
|
||||
|
||||
// });
|
||||
|
||||
it("should allow for nested attributes", function(done) {
|
||||
testRender("test-project/xml-templates/nested-attrs.marko.xml", {active: true}, done);
|
||||
});
|
||||
|
||||
@ -5,8 +5,8 @@ module.exports = function create(__helpers) {
|
||||
hello_renderer = require("./hello-renderer"),
|
||||
_tag = __helpers.t;
|
||||
|
||||
return function render(data, context) {
|
||||
_tag(context,
|
||||
return function render(data, out) {
|
||||
_tag(out,
|
||||
hello_renderer,
|
||||
{
|
||||
"name": "World"
|
||||
|
||||
@ -4,8 +4,8 @@ module.exports = function create(__helpers) {
|
||||
notEmpty = __helpers.ne,
|
||||
escapeXml = __helpers.x;
|
||||
|
||||
return function render(data, context) {
|
||||
context.w('Hello ' +
|
||||
return function render(data, out) {
|
||||
out.w('Hello ' +
|
||||
escapeXml(data.name) +
|
||||
'! Hello ' +
|
||||
str(data.name) +
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{%
|
||||
function test(name) {
|
||||
context.write("Hello " + name + "!");
|
||||
out.write("Hello " + name + "!");
|
||||
}
|
||||
%}
|
||||
{%
|
||||
@ -8,20 +8,20 @@
|
||||
return "Hello " + name + "!";
|
||||
}
|
||||
%}
|
||||
|
||||
|
||||
A
|
||||
|
||||
|
||||
<p>
|
||||
<invoke function="test('World')"/>
|
||||
<c-write value="test2('World')"/>
|
||||
</p>
|
||||
|
||||
|
||||
B
|
||||
|
||||
|
||||
<p>
|
||||
<def function="greeting(name, count)">
|
||||
Hello ${name}! You have ${count} new messages.
|
||||
</def>
|
||||
<invoke function="greeting" name="Frank" count="${10}"/>
|
||||
<invoke function="greeting('John', 20)"/>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
@ -3,7 +3,7 @@ module.exports = function create(__helpers) {
|
||||
empty = __helpers.e,
|
||||
notEmpty = __helpers.ne;
|
||||
|
||||
return function render(data, context) {
|
||||
context.w('Hello John');
|
||||
return function render(data, out) {
|
||||
out.w('Hello John');
|
||||
};
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
<c-template>
|
||||
{%
|
||||
function test(name) {
|
||||
context.write("Hello " + name + "!");
|
||||
out.write("Hello " + name + "!");
|
||||
}
|
||||
%}
|
||||
{%
|
||||
@ -9,16 +9,16 @@
|
||||
return "Hello " + name + "!";
|
||||
}
|
||||
%}
|
||||
|
||||
|
||||
A
|
||||
|
||||
|
||||
<p>
|
||||
<invoke function="test('World')"/>
|
||||
<c-write value="test2('World')"/>
|
||||
</p>
|
||||
|
||||
|
||||
B
|
||||
|
||||
|
||||
<p>
|
||||
<def function="greeting(name, count)">
|
||||
Hello ${name}! You have ${count} new messages.
|
||||
@ -27,4 +27,4 @@
|
||||
<invoke function="greeting('John', 20)"/>
|
||||
</p>
|
||||
|
||||
</c-template>
|
||||
</c-template>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user