raycmorgan / mu Goto Github PK
View Code? Open in Web Editor NEWA Node.js Mustache template engine (and compiler)
License: MIT License
A Node.js Mustache template engine (and compiler)
License: MIT License
C:\Program Files\nodejs\sites\examples\Mu>node demo
The "sys" module is now called "util". It should have a similar interface.
Outputting examples/simple.html.mu with a chunkSize of 10
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
SyntaxError: Unexpected token ILLEGAL
at Object.compile (C:\Program Files\nodejs\sites\examples\Mu\lib\mu\compiler.js:23:19)
at C:\Program Files\nodejs\sites\examples\Mu\lib\mu.js:50:36
at C:\Program Files\nodejs\sites\examples\Mu\lib\mu\parser.js:22:9
at Array.0 (C:\Program Files\nodejs\sites\examples\Mu\lib\mu\preprocessor.js:24:14) at EventEmitter._tickCallback (node.js:192:40)`
I'm using Mu2 with express for my rendering, and for some reason it's outright crashing whenever there's an error instead of emitting an "error" event on the stream. Here's the code I'm using:
var stream = mu.compileAndRender(name, local);
stream.pipe(res);
stream.on("error",function(err){
res.send(err);
})
The error I was getting was:
C:\Users\.....\node_modules\mu2\lib\mu\parser.js:36
throw new Error('Encountered an unclosed section.');
Which I have since fixed. But I'd prefer things to fail more graceful whereas my server is currently just crashing whenever I have an error.
Any help would be much appreciated.
It seems both the repository and package.json are missing license information. I assume this is under MIT license, like most of Node.js modules, but obviously this can't be taken for granted
Template:
{{#person?}}
Hi {{name}}!
{{/person?}}
Hash:
{
"person?": { "name": "Jon" }
}
Result:
Hi!
This also seems to be the case on the mustach demo site :(
Hello. I've wrote simple benchmark (http://github.com/mbeloshitsky/Mu/blob/master/benchmarks/blocking.js) to check how Mu templating deals with event loop and get following results:
*** Mu templating
Ticks: 2
Time: 643ms
*** Idle time
Ticks: 429437
Time: 644ms
Seems that mu in it's synchronous version (asynchronous probably too but i've not tested it) stalls event loop while rendering template. Possible solution is inject nextTick somewhere in rendering process.
Hi,
I get the following error trying to use the demo code with express:
Error: template_not_in_cache
at Object.render (/usr/local/lib/node/.npm/mu/0.5.1/package/lib/mu.js:110:11)
at Object. (/Volumes/Docs/Node/sppericat/server.js:17:5)
at param (/usr/local/lib/node/.npm/connect/1.3.0/package/lib/middleware/router.js:148:21)
at pass (/usr/local/lib/node/.npm/connect/1.3.0/package/lib/middleware/router.js:164:10)
at Object.router as handle
at next (/usr/local/lib/node/.npm/connect/1.3.0/package/lib/http.js:204:15)
at Object.handle (/usr/local/lib/node/.npm/express/2.2.1/package/lib/http.js:75:5)
at next (/usr/local/lib/node/.npm/connect/1.3.0/package/lib/http.js:204:15)
at HTTPServer.handle (/usr/local/lib/node/.npm/connect/1.3.0/package/lib/http.js:217:3)
at HTTPServer.emit (events.js:67:17)
Cheers,
Stephane
node> var mu = kiwi.require('mu', '0.0.1')
Error: process.mixin() has been removed.
at EventEmitter.mixin (node.js:11:11)
at Object. (/Users/bitzesty/.kiwi/current/seeds/mu/0.0.1/lib/mu/compiler.js:76:9)
at Module._compile (module:384:23)
at Module._loadScriptSync (module:393:16)
at Module.loadSync (module:296:10)
at loadModule (module:241:16)
at require (module:364:12)
at Object. (/Users/bitzesty/.kiwi/current/seeds/mu/0.0.1/lib/mu.js:8:19)
at Module._compile (module:384:23)
at Module._loadScriptSync (module:393:16)
I've recently integrated Mu with express as the default templating engine for HTML files. I used the following module to achieve it:
var mu = require('mu2');
exports.__express = function (path, options, callback) {
var result = '';
var stream = mu.compileAndRender(path, options)
.on('data', function (data) {
result += data.toString();
})
.on('end', function () {
callback(null, result);
});
}
I wonder if you'd consider integrating something like the above into Mu? It needs a little more work, because you should be able to control caching within the options handle which I haven't wired up. But the above code works along with the following to integrate it into express:
app.set('views', __dirname + '/layouts'); // tell express where my views are
app.engine('html', muexpress.__express); // register the mu templating engine (using my mu-express gateway)
app.set('view engine', 'html'); // register the default template engine as html
If you integrate it, I'd be keen to add a patch to https://github.com/visionmedia/consolidate.js/ so that you can use Mu with express quite simply.
Let me know your thoughts. I'd be happy to integrate it into Mu myself and send through a pull request.
cheers,
Scott.
Looks like it has to do with https://github.com/raycmorgan/Mu/blob/master/lib/mu/renderer.js#L90
I am getting this error when calling compileAndRender('path/to/file', { test: null });
As of commit 7b4f33132476af0c6bd2c5edd074d6fe6932de88
, a deprecated process.mixin
is being used in compiler.js
on line 76. It was deprecated in node in version 0.1.32.
You can read more about it here: http://groups.google.com/group/nodejs/browse_thread/thread/e82b45b3f8faa5af/531a88bc64b66f58
The fix appears to be simply to rely on the user to provide a utility class that provides process.mixin
functionality.
janl/mustache.js#91 is a similar bug for mustache.js, which is now resolved so unfortunately I'm going to have to switch back to mustache.js for the time being
Consider adding asynchronous lambda support? It would work as follows:
The solution would look like this:
var data = {
value: function( body, cb ) {
process.nextTick(function() {
cb('result');
});
}
}
I've implemented a solution here: juliangoacher@599ea69
The solution will inspect the arity of a value function to try and avoid the situation where a function which doesn't accept the callback returns undefined and so hangs the process.
Is there anyway to write the output of mu.compileAndRender to a html file?
Ive been trying with fs.writefile and all I get is partially formatted html with broken tags.
Using the v2 branch (npm default) I'm getting errors when simply just repeating sections. E.g.
{{#user}}
Hi {{name}}!
{{/user}}
...
{{#user}}
Bye {{name}}
{{/user}}
If user is found, this yields:
Error: Cyclic proto value
at insertProto (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:174:17)
at section (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:137:17)
at next (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:53:20)
at next (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:38:16)
at next (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:32:27)
at next (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:38:16)
at next (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:48:18)
at next (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:38:16)
at render (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:84:3)
at section (/usr/local/lib/node/.npm/mu/0.5.2/package/lib/mu/renderer.js:138:5)
Can we do this? If not I would love to see this made possible!
EDIT: OK looking at the source, it is possible using a combination of parser.js
and compiler.js
.
Would be exceptional if you exposed a direct API however! I could make a patch if your time is limited.
I've noticed that the text output will append new lines to the start and end of the text being replaced.
Here is a simple script:
var mu = require('mu2');
mu.root = __dirname + '/templates';
mu.compileAndRender('test.html', {name: 'John'})
.on('data', function (data) {
console.log(data.toString());
});
templates/test.html is:
<h1>Hello {{name}}</h1>
The output is:
<h1>Hello
John
</h1>
instead of:
<h1>Hello John</h1>
I'm using node v0.8.4 and tried with both npm and github versions of mu2.
Example:
Working:
<b>{{foo}}</b>
Fails:
<b>
{{foo}}
</b>
Exception:
/node_modules/mu2/lib/mu/parser.js:95
throw new Error('Encountered an unclosed tag: "' + this.otag + this.buff
^
__MU_NEWLINE__</b>"an unclosed tag: "{{foo}}
at Object.scanTag (/node_modules/mu2/lib/mu/parser.js:95:13)
at Object.tokenize (/node_modules/mu2/lib/mu/parser.js:29:56)
at Object.parse (/node_modules/mu2/lib/mu/parser.js:9:17)
at /node_modules/mu2/lib/mu.js:37:21
at [object Object].<anonymous> (fs.js:115:5)
at [object Object].emit (events.js:64:17)
at afterRead (fs.js:1117:12)
at Object.wrapper [as oncomplete] (fs.js:254:17)
When looking in your examples there are no examples where you use newlines when working with tags, but I think this is a normal usage of HTML?
First of all, I'm sorry. Test case here: pepve@414899a
It'd be nice if we could specify a default file extension so that we could reference "foo.html"
as just {{> foo}}
instead of {{> foo.html}}
, just to make the templates a little cleaner. Also, maybe use that for the render
and compile
functions as well.
Currently mu does not support changing the tag form ({{ }} to say <% %>).
{{! this works }}
{{! this
is meant to, but doesn't. }}
..it fails. I tried with a tpl containing {{mytag}} and a json shema {john:"I'm john"}, I got no response from the server (I use the example mentioned on the main page).
It seems simple to correct, but that really harm (I mean if I forget only one string the client never get the data). Would be better if {{mytag}} would be replaced by a blank if not found :) (throwing an error in the server, but not blocking evthg)
Ciao,
Jk.
It would be great to use this in CouchDB (which also supports basic CommonJS functionality) and perhaps even in the browserassuming the drawbacks there (http://www.sitepen.com/blog/2010/07/16/asynchronous-commonjs-modules-for-the-browser-and-introducing-transporter/) can be dealt with.
It would be much faster to figure out how to hook up Mu with Express if there existed a sample app or any kind of tips. I get the impression from previous (now closed) issues related to Express that it is possible to make it work, but the conversation is in shorthand that assumes much better Express and Mu skills than mine. This is where documentation usually comes in.
hey guys, I was playing with mu-cli.js
and couldn't make partials work...
partial.html
<h1>yo-ho-ho</h1>
template.html
<html>
<body>
{{> partial}}
</body>
</html>
command:
cat template.html | node_modules/mu2/lib/mu-cli.js --view={}
output:
<html>
<body>
</body>
</html>
desired output:
<html>
<body>
<h1>yo-ho-ho</h1>
</body>
</html>
am I doing something wrong?
Would real like to be able to render nested templates. This would allow me to break my html up into reusable parts rather than duplication code every where. My thought would be to enable renders to be passed as part of the view. Something like this:
var stream = mu.compileAndRender('index.mu', {
header: mu.compileAndRender('header.mu', {
title:'Home page'
});
});
I'm finding that writing data to a HTTP response stream stops after the first replacement.
This is the code to replicate:
var http = require('http');
var mu = require("mu2");
http.createServer(function(req, res) {
mu.clearCache("helloMsg");
mu.compileText("helloMsg", "<p>Hello, {{name}}.</p>");
mu.render("helloMsg", {name: "John"}).on('data', function(data) {
var asString = data.toString();
console.log(asString);
res.write("<body>"+asString+"</body>");
res.end();
});
}).listen(8888);
HTTP output (note that ".
" has been stripped):<body><p>Hello, </body>
Console output:
<p>Hello,
John
.</p>
I'm using Node.js v0.10.5 on Linux Mint and mu2 is reported as version 0.5.17.
I tried to run the following code:
mu.render("index.html", {host: IOHOST}, {}, function(err, buffer) {httphelper.sendHTML(res, 200, buffer)})
Then "err" has the following error: "SyntaxError: Unexpected identifier"
It fails in compiler.js at "var func = eval(code);" with code:
(function COMPILED(context, options) {
options = options || {};
var Mu = M;
var REE = new RenderEventEmitter(options);
process.nextTick(function () {
REE.write(Mu.escape(Mu.normalize(context, "host")));
REE.close();
});
return REE;
})
I checked that the template file is read correctly, I tried the example, also fails.
I use the latest NodeJS (1.92) and Mu.
One of the rather nice features of janl's implementation of Mustache in JS is that the context is exposed, so it can be overwritten in order to provide certain filters/defaults/features.
It can be exposed quite easily by changing function walkToFind(context, name)
in render.js to render.context = function(context, name)
.
I would really like to see this in Mu. Thank you for your time.
Hi, I'm trying to listen on output stream for error message and then emit it as data, but it doesn't work โ the request hangs up and never returns. I need to output error message instead of missing partial, and keep all the rest blocks rendered.
Is there a way to solve my problem?
pageData = ""
pageStream = mu.compileAndRender fileName
pageStream.on "data", (data) ->
pageData += data
pageStream.on "end", ->
stream = mu.compileAndRender "layout.html", {page: pageData}
util.pump stream, response
pageStream.on "error", (err) ->
pageStream.emit 'data', err.message
# pageStream.emit 'end'
Is it possible to add support for NPM?
http://github.com/isaacs/npm/blob/master/doc/developers.md
Hey, I was using mu to render posts, and posts had a "replies" array that also contained posts. So my post.html looked something like
{{#post}}
<div class="post" id="post_{{id}}">
<div class="message">{{message}}</div>
<div class="replies">
{{#replies}} {{>post.html}} {{/replies}}
</div>
</div>
{{/post}}
Then in some file I tried to render some posts by calling {{> post.html}}
which then made my CPU spike and node to take up like a gig of RAM in a few seconds.
Curiously, when I had refreshed my page, the rendering had become instantaneous and the RAM usage was increasing at the same speed at before.
My conclusion from this is that Mu entered an infinite loop while trying to compile post.html into a template because when it got to the code with {{> post.html}}
, the template hadn't been compiled yet so it was being fetched from memory and compiled, which just kept on happening.
I haven't looked into the code, but I'm guessing you can remove the check for a template being compiled at compile time, and leave that check for when something is actually being rendered.
My first impression is that this looks pretty cool. I'm wondering if you think it would be good to make the event types emitted more in line with what Node emits:
The data
event would become a body
event
The eof
event would become a complete
event
The code fragment below is a copy from mustache, but I can't get render object defined for lambda support. The console told me argument render is undefined. Is there something that i misunderstand?
Template:
{{#wrapped}}
{{name}} is awesome.
{{/wrapped}}
Hash:
{
"name": "Willy",
"wrapped": function() {
return function(text, render) { //render param is undefined
return "<b>" + render(text) + "<b/>"
}
}
}
Here's a fix for the error:
/node_modules/mu2/mu/parser.js
Line 67 should be replaced with:
buffer.write(content, 0, 'utf8');
Mu2 does not seem to support dot notation. It does not crash, but it does not seem to output the value of the variable:
{{object.property}}
I get this deprecation warning whenever I use Mu in my projects with Node 0.6+. I tried manually changing the import in compiler.js
from sys
to util
and everything seemed to work fine.
I think it's worth noting somewhere in your Readme that, in order to be able to use partials, you must configure mu.root, like so:
var mu = require('mu');
var path = require('path');
mu.root = path.join(__dirname, 'server/views');
Assuming you were storing your views in the folder server/views relative to the main app.js file. There doesn't appear to be a way to call a partial like so
{{>server/views/header.mu}}
So, the definition, I presume, directs Mu where to look for
{{>header.mu}}
maybe i missed it, but when iterating through a simple array like [1, 2, 3, 4], shouldn't {{.}} indicate the current item? how to handle unnamed items?
Following your example I keep getting a crash when using util.pump(stream, req) when req is using the express (i.e. connect) middleware. Apparently there has been some sort of api change: http-party/node-http-proxy#112
Also why are you giving examples using util.pump() when it is marked as experimental? Is there a more stable way to ship stuff to the response?
My old node-ios7crypt web app would silently crash when referencing mustache template files that did not exist. Would be nice if mustache caught this error before attempting to read from template files.
Missing return
at line 34 in mu.js (0.5.13):
if (err) {
callback(new Error('file_not_found'));//errors.fileNotFound(mu.root, filename, err)));
}
when file isn't present:
.../node_modules/mu2/lib/mu/parser.js:15
this.template = template.replace(/\r\n/g, carriage)
^
TypeError: Cannot call method 'replace' of undefined
at Object.Parser (.../node_modules/mu2/lib/mu/parser.js:15:28)
at Object.parse (.../node_modules/mu2/lib/mu/parser.js:10:16)
at .../node_modules/mu2/lib/mu.js:37:21
at [object Object]. (fs.js:88:5)
at [object Object].emit (events.js:67:17)
at Object.oncomplete (fs.js:1058:12)
The "compileText" function does not work anymore as shown in the example, the signature is different. Breaks legacy code.
Not sure if this is a moustache issue, node.js issue or Mu2 issue.
I'm using partials to include templates. For example:
home.mu
<p1>Welcome {{person}}</p1>
page.mu
<html>
{{> home.mu}}
</html>
Which works fine. But now I want to convert it so that I can pass the name of the template to include as a string in the view that is rendered. Like this:
var stream = mu.compileAndRender('page.mu', {
content: "home.mu"
});
And the modified page.mu template:
<html>
{{> content}}
</html>
But it does not work. Mu chucks an error at
DEBUG: TypeError: Cannot call method 'replace' of undefined
at Object.Parser (/Users/sensis/projects/Happiness Index/server/node_modules/mu2/lib/mu/parser.js:15:28)
at Object.parse (/Users/sensis/projects/Happiness Index/server/node_modules/mu2/lib/mu/parser.js:10:16)
at /Users/sensis/projects/Happiness Index/server/node_modules/mu2/lib/mu.js:37:21
I've also tried rendering home.mu separately, but I've not been able to figure out how to convert a stream to a string for inclusion in the view for rendering page.mu.
I suspect that I need to redesign this to all work asynchronously, but as I'm new to node.js, I've not been able to figure out how to do this.
Any ideas how to approach this?
Mu is cool. But lambdas (http://mustache.github.com/mustache.5.html - lambdas section) not work. Its not implemented yet?
Hey,
Is there a way to just get the template informations mu2 uses? Just resolve the partials and don't render any data to the template (and don't replace other mustache tags except partials)
Use case: Use the same templates on client and server. I have to find a way to deliver a partial free version of the templates to the client.
Adding a HTML nodes some string parameter with double quotes will crash the compilation on the "eval" ( lib/compiler.js @ 24 line ) of the generated template function.
Besides there are some tests (complex.html.mu) with the ["]-s inside, they doesn't trigger exception and ["] are escaped properly. It seems the issue is caused by partials. If you remove ["] from inner_partial.html.mu in example below, the top-level ["]-s in partial.html.mu are magically correct escaped.
There is a dirty workaround: just use sinlge quotes (') for the parameters in templates and all will be good.
This case (with params in tags in partial) seems needs to be checked in tests. Plus some try-catch block for the "eval" would not hurt anyone.
in partial.html.mu
in inner_partial.html.mu
Will produce this code for the template-function:
(function COMPILED(context, options) {
options = options || {};
var Mu = M;
var REE = new RenderEventEmitter(options);
process.nextTick(function () {
REE.write("<h1>First: ");
REE.write(Mu.escape(Mu.normalize(context, "title")));
REE.write("</h1>");
REE.write("\n");
REE.write("<h1 class="header">"); //<-- not good here, will cause exception...
REE.write(Mu.escape(Mu.normalize(context, "title")));
REE.write("</h1>");
REE.write("\n");
REE.write("<div class="title">Again, "); // <-- and here
REE.write(Mu.escape(Mu.normalize(context, "title")));
REE.write("!</div>");
REE.write("\n");
REE.write("\n");
REE.close();
});
return REE;
})
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.