Emulating the 'layout' functionality of Jade while using Mustache - node.js

I setup node and express then integrated the mustache.js template by following the instructions on this page:
http://bitdrift.com/post/2376383378/using-mustache-templates-in-express
So far so good, except I'm having a lot of trouble trying to setup mustache.js to have the same functionality as Jade's "layout". I'm basically trying to setup 1 master file to serve as a shell for my other pages similar to extending a template with Django.
Ex. The layout file could have this:
[html]
[title]my title[/title]
[body]{{content}}[/body]
[/html]
Where {{content}} gets replaced with the contents of a file which I would specify somehow in the route for that page.
I just have no idea how to set this up with express because I'm still a huge newbie with it and the way it's setup with Jade is automagical which seems to be specific to Jade only.
With Jade you just need to make a "layout.jade" file and have something like this as your route:
app.get('/', function(req, res) { res.render('home', { title: 'My home page' }); });
Then it magically adds the contents of home.jade into your layout.jade file wherever you specified the body!= body tag.
So yeah, how can I set something like that up with Mustache? If you know the answer please explain it step by step.

You could write a stache renderer plugin for docpad

Related

What does app.engine() do ? And what are ext and callback?

I tried reading through the documentation and they said
app.engine(ext, callback)
Register the given template engine callback as ext By default will require() the engine based on the file extension. For example if you try to render a "foo.jade" file Express will invoke the following internally, and cache the require() on subsequent calls to increase performance.
I am having a tough time figuring out what do ext and callback here even mean.
This is part of the view/template engine functionality of Express. Many times your request handlers only return some JSON object. But other times you want to build a regular "document" like a fully built HTML page, or RSS feed etc. Template engines help you achieve this, though they are by no means mandatory. You could use other approaches (build strings by hand for example, if you like the pain), or you could use a library such as pug/moustache etc by hand. The view engine functionality basically integrates libraries such as pug/moustache into express so it's easier to use them.
The linked page has a nice example of how this would be used in practice:
Then create a route to render the index.pug file. If the view engine property is not set, you must specify the extension of the view file. Otherwise, you can omit it.
app.get('/', function (req, res) {
res.render('index', { title: 'Hey', message: 'Hello there!' })
})
When you make a request to the home page, the index.pug file will be rendered as HTML.
Many times express knows about various template engines. So it's enough to say express.set('view engine', 'pug') and it can do the right thing as long as the pug package is installed.
Other times you need to use app.engine to tell it more explicitly what to do. It is called like app.engine('jade', require('jade').__express). The first parameter is just the extension express should be looking for. So when you say req.render('index', ...) it would look for an index.jade file. The second parameter is the function which actually does the integration between the view engine (which, as I've said, is a separate thing from express), and express itself. consolidate.js is a package with integrations for a lot of view engines.
But if you want to see what this function does, checkout developing template engines for Express. The callback parameter must look like function(filePath, options, callback). filePath is just the name of the disk file to use for rendering, so index.jade in the example from above. callback is a standard node callback, invoked as callback(err) on error or callback(null, renderedContent) on success. options is an object passed in from the req.render('index.jade', /* options */ { title: 'foo', content: 'bar' }). It's then up to you to decide how to actually do the rendering based on the supplied arguments.
In simple terms: ext - extension, callback - library (engine) that will render the file with the given extension.

Render 2 templates at the same time on Node/Express

I come from the PHP scenario, so this may be a wrong question.
I serve a page (templates with Handlebars) to client this way:
router.get('/', function(req, res) {
res.render('home');
});
and it works, but what if I need to divide my template in some different parts (so I'm able to reuse one of this in many different way)? For example, I have a template for header and one for footer.
Something like this:
router.get('/', function(req, res) {
res.render('header');
res.render('content');
res.render('footer');
});
How can I achieve this? Thanks.
Assuming you are using handlebars template rendering service, you can use partials.
http://handlebarsjs.com/partials.html
Code example: https://github.com/donpark/hbs/blob/master/examples/partial/views/index.hbs
The basic high level call stack follows like this:
res.render('page') ---> parses N of partials (recursively) --> html out

How to get username injected into html?

I have a static html site:
index.html
I want to use handlebars {{username}} to inject a username variable. It looks like:
res.render('index', {username:'MyName'})
should work. The problem is my index.html is in my '/static' (my express.static()) directory. What is the best way to get my username variable into my html page without having to convert it to something that doesn't look like html? Thats why I dont want to use jade and prefer handlebars. If there is some other way, it would be best.
Update: I would like to preserve the same structure I have (keeping everything in my static directory) as opposed to moving things out to a "views" directory. Is this possible?
Then you must have to use Template engine. You can use Jade it also support HTML, only you have to use . at end of tag like:
doctype 5
html. // THAT DOT
<body>
<div>This is jade testing with HTML</div>
</body>
Is there a way to keep the file in my /static directory without having
to put it in the "views" directory?
Yes you can use _dirname while rendering
app.get('/anyurl/' , function(req, res){
res.render(__dirname + '/../static/path/folder') //modify path according to your structure
});

Using template inline in Jade

I'd like to pass the name of a template file to my jade template and have it expand that template. I'm using node and express.
html
div(id="content")
extend #(content}
seems intuitive to me but it doesn't work. Is this possible and/or is there an alternative pattern to better achieve this?
After rethinking the pattern (I'm brand new to express and node), I realized a better solution. What I've done is taken the content (which was all static) and included it in block statements in multiple template files. I then serve those template files based on the route.
Say I have a layout page that has header and footer and multiple views: index, search, and getting started.
//layout.jade
html
head
block extra_headers
body
div(id="header")
div(id="content")
block content
div(id="footer")
//index.jade
html
block head
script(src="sss.js")
block content
| welcome to my home page
//results.jade
html
block head
script(src="search.js")
block content
| my search results
And so on with 'getting started'. My node code then looks like this:
app.get('/', function(res, req) {
return res.render('index'); // renders the index view.
});

Blocks and Extends in Jade layouts with Express not functioning

I have a small express site written for node. I'm using Jade for layouts, and trying to get a handle on the new extends/block bits. When I use the standard layout/child view pattern list here, everything works great:
https://github.com/visionmedia/express/blob/master/examples/jade/views/layout.jade
I want to get fancy and use blocks to stuff custom html into specific parts of the master layout. So I transitioned over to something that looks more like this:
https://github.com/visionmedia/jade/blob/master/examples/extend-layout.jade
https://github.com/visionmedia/jade/blob/master/examples/extend.jade
Using the exact code in the extend-layout example above, my pages will always render the extend-layout.jade part, but never the content inside. Anything inside of a block never seems to get rendered. I've given this a try, but it doesn't help:
https://github.com/visionmedia/jade/issues/377
I'm running node 0.6.2, express 0.2.5, and jade 0.18. Any takers?
The layout config entry is deprecated now anyway with v3 of Express.
You can only use the block/extends style.
So I've figured out what was up. I was manually specifying the layout to use in express - I was setting it to the correct layout, but removing that line solved the problem. Example (for others who run into this):
exports.index = function(req, res){
res.render('index', { title: 'Express' }) // this works!
res.render('index', { title: 'Express', layout: 'layout' }) // this doesn't work
};
I would have expected a different behavior - including an explicit layout like this simply caused the child view to not render within the master layout.

Resources