I cannot get mustache reading partials added like so {{>my_partial}} when using it with consolidate.js. I start my express application with something like:
file index.js:
var express = require('express'),
cons = require('consolidate');
app.configure(function(){
app.set( 'models', BACKEND + '/models' ); // Set the models directory
app.set( 'views', BACKEND + '/views' ); // Set the views directory
app.set( 'controllers', BACKEND + '/controllers' ); // Set the controllers dir
app.set( 'view engine', 'html' ); // Set Mustache as the templating engine
app.engine( 'html', cons.mustache );
app.engine( 'mustache', cons.mustache );
app.use( app.router ); // Set the router
app.use( '/public', express.static( BASEPATH + '/frontend/public' ) ); // set frontend/public to /public for users
app.use( '/js', express.static( BASEPATH + '/frontend/js' ) );
app.use( '/out', express.static( BASEPATH + '/out' ) ); // documentation path
// Set client side libraries here (Make them available to the public based on settings.json)
for(setting in SETTINGS.public) {
app.use( SETTINGS.public[setting], express.static(BASEPATH + SETTINGS.public[setting]) );
}
});
Then, somewhere in the controller, I use the render like so:
function Blog(app, request, response){
var fs = require('fs'),
Blog = require( app.get('models') + '/blog' ),
model = new Blog(),
scripts = fs.readFileSync( VIEWS + '/m_scripts.mustache').toString() ;
model.List(function(data){
response.render('layout',
{
title : 'My Blog',
body : 'Hello Mustache World',
list : data.rows,
cache : false,
partials : {
m_scripts : partialStr
}
}
);
});
};
exports.list = Blog;
The m_scripts.mustache has:
<script data-src="ergierjgoejoij"></script>
The layout template renders just fine, and the params pass through just fine too, the partial m_scripts gets passed with the text passed by readFileSync().toString() just fine BUT the HTML stuff gets encoded and rendered useless.
My question is, is there a way I can just put in the layout.mustache {{>m_scripts}} and mustache understands to load the m_scripts.mustache automatically without the need to pass it to the render(). If not, what am I missing?
Turns out, at this moment, consolidate.js does not support partials. There is a pull request to fix this but it hasn't been merged: https://github.com/simov/consolidate.js
I ended up using that fork instead by:
1) npm uninstall consolidate
2) npm install simov/consolidate.js
npm install simov/consolidate.js will install that forked version. Then I can do the following:
/**
* @module Blog Controller
*/
function Blog(app, request, response){
var Blog = require( app.get('models') + '/blog' ),
model = new Blog();
model.List(function(data){
response.render('layout',
{
title : 'My Blog',
body : 'Hello Mustache World',
list : data.rows,
cache : false
,partials : {
m_scripts : './backend/views/m_scripts.html'
}
}
);
});
};
exports.list = Blog;
It's a lot simpler than I thought. You pass the path to your partial instead and then you can use {{>m_scripts}} on the layout.html
Still, not sure if there is a way to make it, by default, look for {{>m_scripts}} on the views folder or something. That would be neat.
You can use Hogan instead of Mustache. Hogan will render templates with partials which you set in app.set('partials', partialsPathMap) as a path map.
You can use code in this gist:5149597 in your project. Then you do not need any more partials config when rendering templates.
Edited 2014-06-23:
For simpler, I wrote a npm to handle this. Just npm install mustlayout, the repository and document is here: https://github.com/mytharcher/mustlayout