Render 2 templates at the same time on Node/Express - node.js

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

Related

How to serve static html files through express without explicit rendering

I have around 20+ HTML files. I would like to render them, when requested as host/filename.html, without having to use response.render for each file. If I simply move my views folder in public folder (and set views of express accordingly), the browser is not rendering these HTMLs. Rather, I see the code on the screen. Can someone please advice on this?
You can try using something like this:
'/someRoute': (req, res, next) => {
res.status(200).sendFile(process.cwd() + '/views/index.html');
}

Multiple layouts with Handlebars and ExpressJS?

If I'm using Handlebars as my templating engine with Express 4, it seems like there is only the option to specify a single layout template to use for all your views:
app.engine('hbs', expressHbs({extname:'hbs', defaultLayout:'layout.hbs'}));
What if your app needs multiple layouts? What if viewA.hbs uses one layout and viewB.hbs needs a different layout?
As I'm learning nodejs, I'm coming from a PHP Laravel background where the Blade templating engine has you specify which layout to use at the top of each view file. It makes it really simple to switch between layout templates for any given view.
You should be able to pass in the layout from your route/controller when you call the render method.
router.get('/', function(req, res) {
res.render('home', {layout: 'viewBLayout.hbs'});
});
I am pretty sure jade will let you switch layouts from inside the template but I don't know if you can do that with handlebars.
If you use express-hbs, you can specify a layout in the template with a comment like:
{{!< layout}}
Alternatively, you can try exphbs. It also supports layout comments and multiple layouts can be nested. (Disclaimer: I wrote it.)
make sure you first make two files named "main.handlebars" and "backend.handlebars" in /layouts directory:
Try this code for two routes if you want for example
router.get('/', function(req, res) {
res.render('home', {layout: 'main'});
});
router.get('/backend', function(req, res) {
res.render('home', {layout: 'backend'});
});

node, express, jade: How to process form data

Is there any best practise code pattern how to process HTML form data with express and jade templates? I was wondering, if it would make sense to use a PHP like self calling loop of the form template, say in your router script you have two handler for the same route, one for GET and the other for POST requests. Something like:
exports.getHandler = function(req, res){
res.render('/formhandling/', {mode: "form-filling"});
}
exports.postHandler = function(req, res){
res.render('/formhandling/', {mode: "form-processing"});
}
and the jade template might look like
extends layout
block content
h1 #{title}
if mode == "form-processing"
p Form data processed...
else
form(name="", method="post", action="/formhandling/")
...
Does that make any sense or did I get something completely wrong?
I feel like you could just use jQuery to hide the form after the user submitted, instead of rendering the response again. If you want to do any processing of the form on the server side, you can do that in your app.js.
app.get('/', routes.form);
app.post('/', function(res,req){
/* form processing here
you could also do this with an external route */
});
Edit: Also, see my answer on this question

What is the correct way to use express with a second div that needs data

I have the following layout.jade file:
!!! 5
html
head
body
#left
#leftbody
#center
#centerbody
#container!= body
#right
#rightbody
And I have the following route.js file:
app.get('/',
function(req, res) {
Post.find({}).execFind(
function(err, data) {
res.render('post/index', {
posts: data
});
});
});
I'm currently rendering #centerbody based on links in the #leftbody. I'm wondering how I could use express to populate the #rightbody. Currently I'm populating a ul in #rightbody using an ajax call in document.ready but was wondering if there was another way using express.
I would strongly advise you to have a look at Jade includes, or, even better, Jade template inheritance
This would allow you to keep, for all your pages, the common parts of the page in separated files. And allow easier maintenance. This is definitely the thing to do.

Emulating the 'layout' functionality of Jade while using Mustache

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

Resources