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

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.

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.

express-handlebars accessing variables declared in the client javascript

I am learning to use handlebars for templates in my website.
I am using node.js so I have used the express-handlebars module as it seems popular and has a lot of support.
I set up some basic config as so..
var exphbs = require('express-handlebars');
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({
defaultLayout: 'layout',
}));
app.set('view engine', 'handlebars');
My understanding is that my views in handlebars (ie my content pages) are templates in handlebars and under the hood I think these templates are being compiled on my behalf so that I can concentrate on using them.
Now, I can pass in data to the template from my node express router and then access and render data in the template using the handlebars notation {{ variable }}.
That's great. But....I want to declare variables on the client using javascript, probably as the result of getting some data back from an Ajax call that I want to enter. Unfortunately this never seems to work. I cannot figure out how I can access a local variable in my template. There is surely a way to do it?
the #with block helper looked promising but unfortunately it didn't do what I expected.
Here is a snippet of one of my content pages with a couple of attempts to declare data locally and render its value.
<div>
<script>let test = {
text: 'this is my example text'
};
</script>
<div>
{{#with test}}
{{text}}
{{/with}}
</div>
<div>
{{test.text}}
</div>
</div>
I have read a lot of articles and watched a lot of videos and I just cannot find anywhere where somebody uses the 'express-handlebars' module and then renders data defined locally.
I am probably missing something obvious but I have been struggling for a while now.
Does anybody have any idea how I can do this please?
thanks in advance.
Okay...it looks like client-side templateing has to be configured separately using webpack. I suppose this makes sense because express handlebars compiles the templates (which just resolves to plain javascript that takes the variables I want to render and wraps in the html needed) and I haven't been able to find any templates on my client through the inspector in the browser. I haven't had chance to try it yet, but this looks promising : http://initialdigital.com/sharing-handlebars-templates-on-both-server-client-in-node-js-express-with-webpack/

How replace jade by html

I'm using the express skelton to develope an app. I don't know how to use jade language, so I want to convert this files to html, I did that, but my problem now it's I have 2 lines the aim js : app.js that have to change
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
Please can you help me to change this lines, thank you.
You can use EJS(http://embeddedjs.com/) as a view engine and use the html (in form of ejs files)
`app.set('view engine', 'ejs');`
and place the .ejs files containing the html code within the view folder.
You'll have to update the dependencies in the package.json as well
"ejs": ">= 0.0.0"
For listing static html pages, use this property in express
`app.use(express.static(path.join(__dirname, 'public')));`
and place your .html files within the public folder.

How can you convert "view engine" value in expressjs to render html instead of jade?

This is my current code:
app.set('view engine', 'jade');
I want to convert the jade files to html and render html instead. I tried substituting 'jade' with 'html' but that didnt' work.
You can use res.sendfile to serve HTML files:
res.sendfile('path/to/html/file.html');
(to convert any existing Jade files to HTML, you can install Jade globally using npm install jade -g and use the command line utility jade to convert them)
But that doesn't "render" anything, because rendering assumes some form of templating engine. If you want to use a different templating engine, perhaps one that looks more like HTML than Jade does, you can take a look at ejs or swig.
Also, instead of using res.sendfile, you can use the express.static middleware, which will serve any static files (like plain HTML, JS, CSS):
app.use(express.static(__dirname + '/public'));

Node.js express: confuse about ejs template

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>

Resources