Node.js express: confuse about ejs template - node.js

I put my ejs template file in views folder like:
views
|
|--foo.html
|
|--layout.html
so I config my ejs template:
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
I render my foo template by this:
res.render('foo.html', {title: 'test'});
I want use layout.html as the master layout template, I also add <%- body%> tag in layout.html, but is doesn't work, what I saw is only return the ended foo.html.
Why the layout.html can't be the master layout?Or how can I set it to the master layout?

Ahah you just got tricked by Express 3 change in layout management.
The official example: https://github.com/visionmedia/express/tree/master/examples/ejs
Has not been updated.
In Jade you now have to use blocks and extend the layout.
http://www.devthought.com/code/use-jade-blocks-not-layouts/

Try to use ejs-locals then you can do this in a login.ejs file:
<% layout('layout') -%>
<form></form>

Related

How do you render when organising project by feature?

I have changed the structure of my project and now I group stuff by features. Instead of putting all routes in "Routes", all controllers in "controllers", etc.
I find the new way much better but I have found that for rendering the local file, as it is not anymore in the "views" folder, I have to do:
res.render("../auth/login");// presumably we are in views so we go up and then auth/login.ejs
And inside login.ejs I have to do:
<%include ../views/partials/header %>
Is this the way to follow when using project structure by feature?
The folder express uses for templates is called views, and is enabled by default:
app.set('views', './views'); //this code runs when you call: var app = express();
If you want to set multiple locations that express will look for views, you can do so by calling:
app.set('views', __dirname + '/foo');
Now, express will look in the views and foo folders for templates to use.
If you want to set multiple folders, you can call app.set multiple times, or simply pass an array of folders to app.set:
app.set('views', [__dirname + '/foo', __dirname + '/bar']);
Now, express will look in the views, foo, and bar folders for templates.
Lets say you have foo.ejs in the foo folder and bar.ejs in the bar folder. You can access these templates like this:
<%- include 'foo' %>
<%- include 'bar' %>
This question was a good reference for your problem.

Nodejs Express handlebars how to include .hbs inside another .hbs without templates

How could I include .hbs inside another .hbs without templates? I'm using a component based architecture for Nodejs wih Express and I need to include hbs files with content for use the {{values}} in both, html and js sides without duplicating anything and clean.
I tried using partialsDir like this:
app.engine('.hbs', exphbs({
defaultLayout: 'layout',
extname: '.hbs',
layoutsDir: path.join(__dirname),
partialsDir: [
path.join(__dirname, 'dashboard', '_public', 'main'),
path.join(__dirname, 'home', '_public', 'main')
]
}));
but it gets all of the scripts of all of the views of all of the routes. And using {{>viewScript}} (templates) it load all the .hbs (when I go to home I have the home partial .hbs, when I go to dashboard I have the home and the dashboard partials .hbs so that not works for me.
I tried with src, but it doesn't work (mime error)
<script src="viewScript.hbs"></script>
I can combine both .hbs with its own js inside one .hbs file, ok, but I wanted to keep those pieces separated.
I found a clean solution for this case to get those pieces on separate files (more simple than any kind of complex template system when you have the views in components instead of having all views on an single path).
In .hbs could be a small dictionary before loading the script with all string values I could need.
<script>
var hello = "{{{lang.hello}}}";
</script>
<script src="viewScript.js"></script>
this method is simple, don't duplicate anything and leaves me to do dynamic names with jquery and a lot of more stuff.

Handlebars, how to create layout for sub page using Node and express

I'm currently working on a simple CMS. I have some basic layout set up for each page like that:
app.engine('handlebars', exphbs({defaultLayout:'layout'}));
app.set('view engine', 'handlebars');
I have some pages and I would like to setup sublayout for those pages.
For example.
Each page need to have root layout but gallery/all, gallery/new etc. need its own sublayout. How can I do it?
solution :
I found a solution for this. Instead of using layout use handlebar partials
You can use other layout: 'gallery_all_layout' in router:
res.render('gallery/all', {
pageTitle: 'Gallery List',
layout: 'gallery_all_layout'; //place it the same folder defaultLayout 'layout'
...
});

How to achieve jade template inherit in node.js

I have two jade template in the same folder,just like:
|__layout.jade
|__content.jade
and the layout.jade is the parent template, the content.jade will inherit from it: so in the layout.jade:
doctype 5
html(lang="en")
head
title= title
body
block content
in the content.jade
extends layout
block content
h1 this is frome nested template
however, when I run it, the inherit doesn't work, it only show the parent template's content
so what't wrong with my code?
Make sure you include the keyword "append" in content.jade.
extends layout
block append content
h1 this is from nested template
More on this here.
This might be a total red herring, but I noticed your two files seem to have inconsistent indentation (at least as pasted in above).
Does it work if you correct this?
I had a similar problem and tried various answers for node.js on stack-overflow/Jade documentation.
In your app.js file check the following..
1) Check that the view engine is set to jade (now renamed pug):
app.set("view engine", "jade");
2) Set the views folder (i.e. where you've saved your template/views files):
app.set("views", __dirname + "/views");
3) Set layout to false:
app.set('view options', { layout: false });
4) If your using express, check that you are rendering the correct file
app.get("/", function(req, res){
res.render("contents.jade");
});
Hope that helps
I tested your code, it is ok, would you like to try a newer version of node.js and jade?

EJS layouts on Express 3

I am having some problem with the EJS layout file on Express 3. Express just can't seem to find the layout for rendering. It just skips the layout.ejs totally which means that the output misses out of all the stylesheets and such.
res.render('login', { user: req.user });
and the configuration part,
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
and in the layout.ejs I have added the body tag,
<%- body %>
I have been trying out Jade before and it worked just fine, so the problem is just EJS.
Thanks in advance.
https://github.com/visionmedia/ejs/issues/48
I am uncertain whether the above has been updated but it suggests that layout functionality has been deprecated in express 3.
As a result, I have been using ejs-locals to implement equivalent functionality:
https://github.com/RandomEtc/ejs-locals

Resources