Using layout view in Express with Consolidate and Mustache - node.js

I just started going through Node using Express and finally got Consolidate JS working properly to use Mustache as the templating view system per the instructions on the Consolidate JS Github page.
Mustache is loading properly, but I'm now wondering how to include the layout file along in the rendering of the template. The default Jade system loads the content of the .render method inside of the layout.jade file. I'm just wondering how to do the same, but with Mustache. Any help is greatly appreciated!
Code:
index.js
exports.index = function(req, res){
res.render('index', { title: "Work pl0x?" });
});
index.mustache
Welcome to {{title}}
I just want the index.mustache content to come in the "{{content}}" portion of the code below (layout.mustache). How can I do this?
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title>Project Name | {{title}}</title>
<link href="/stylesheets/style.css" rel="stylesheet" />
</head>
<body>
{{content}}
</body>
</html>

One way to get that behaviour (kind of) is this:
exports.index = function(req, res){
res.render('layout', { title: "Work pl0x?", partials: { content: "index" });
});
Then write like this in your layout.html
<body>
{{>content}}
</body>

The concept of layouts have been removed from express as of 3.0. Here's a reference link with more info.

Related

node express - milliseconds to load classes

I am working with node express. So far I didn´t use a template engine. I create my html file and send it via response.send(template); It works fine.
Now, I have more complex tags like a checkbox with several classes. Loading the route in the browser, it takes some milliseconds till the classes are loaded. Means, first I have a checkbox and it changes then to a button. I am talking about milliseconds, but is there a way to load the classes before actually showing the page?
Do template engines like handlebars or pug have such a feature?
Happy for some help to look in the right direction. Thank you!
If you use a template engine (ejs, pug, etc) you can then use the res.render(...) function. The res.render(...) function allows you to find data from the server side then send it over to the client along with the page.
Example:
const express = require('express');
const app = express();
app.use('view engine', 'ejs'); // Change ejs to your preferred view engine
app.get('/path/to/my/page', function(req, res) {
// Get data
res.render('example', { data: 'my-found-data' }); // Render the template 'example' with the data fetched
}
Additional documentation on using template engines can be found in official expresJS documentation here:
https://expressjs.com/en/guide/using-template-engines.html
What do you mean by classes here?
but is there a way to load the classes before actually showing the page?
CSS classes? if yes, you can provide link to load CSS in header of HTML document you use to load it
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Требуется авторизация</title>
<link rel="stylesheet" href="/assets/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<meta name="description" content="">
<meta name="Keywords" content="">
<meta name="robots" content="noindex">
</head>
<body>
See
<link rel="stylesheet" href="/assets/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
It loads bootstrap.min.css from /assets/bootstrap.min.css, and since its in header of page, all css classes are loaded before browser starts rendering page, so it renders it properly.
See https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/CSS_basics for details on loading css

Add scripts in express-handlebars from view

I am using Express-Handlebars as my templating engine and I use a layout for all my views. However, I want to be able to add scripts via the view for specific pages. Very much like in this example: is there a way to add CSS/JS later using EJS with nodejs/express
I want to add my scripts after the standard scripts that are used for all pages(bootstrap, jquery). These are placed at the bottom of body in my layout, like so:
<html>
<header>
...
</header>
<body>
...
{{{body}}}
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</body>
</html>
How would I go about doing this using Handlebars? Or is my best bet to use EJS? Or can I use both?
Any help is much appreciated,
Freece
Never mind! I realized that that method would contradict the foundations of Handlebars. Instead I added the following to my controller:
var scripts = [{ script: '/js/myTestScript.js' }];
...
res.render('contact', { title: 'Kontakt', scripts: scripts });
And in my layout it looks like this:
...
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
{{#each scripts}}
<script src="{{script}}"></script>
{{/each}}

Embedded JavaScript (EJS) - Dynamically setting view from route

I'm learning nodejs at the moment and my .ejs template files are pretty much standard (header, footer, js-defaults etc) - and the only thing that changes it the content in a HTML div.
I thought I could set a variable in my route and pass it along to the view (like you would a title or another variable), then include it - but it's not working (example below).
In Ruby you can do this with "yield" and I am trying to do the same with EJS.
Thanks for taking the time to read (and please forgive my ignorance in this matter).
Example Route
app.get('/fish', function(req, res) {
res.render('fish' {
title:"Fish",
template:"view/partials/content/fish.ejs"
});
});
Example EJS
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<% include views/partials/template/header.ejs %>
<body>
<div class="container">
<!-- Dynamic content here -->
<% include template %> <!-- tries to load template.ejs %>
</div>
</body>
<% include views/partials/template/footer.ejs %>
<% include views/partials/template/js-defaults.ejs %>
</html>
Looks like this is now supported in EJS. It was introduced in v2.0.1: 2015-01-02. The new syntax looks like this
<!-- Dynamic content here -->
<%- include(template) %>
To get this to work I had to disable caching in Express by setting:
app.set('view cache', false);

node.js jshtml-express layout

Hello!
Is there any way to have the master page or layout in jshtml?
I tried do this in .net Razor style, but it did't works.
Link to jshtml view engine.
My intention is to have mastarpage lets say is called layout.jshtml and some other subpages like index.jshtml and so on, like it is in razor.
More explanation of what I mean speaking "I would like have masterpage"
I have Layout.jshtml , this is my masterpage
<html>
<head>
<link rel="stylesheet" href="/stylesheets/style.css" ></link>
</head>
<body>
#writeBody();
</body>
</html>
and I have other view called some.jshtml
<h1>#locals.title</h1>
<div class="Mydata">
#locals.content
#locals.otherContent
</div>
When I run this page in browser I would like to have concatenation of layout.jshtml and some.jshtml. The content of some.jshtml is rendered in writeBody(); in layout.jshtml
When I speaking of concatenation I mean someThing like this. This is result that I can see in browser.
<html>
<head>
<link rel="stylesheet" href="/stylesheets/style.css" ></link>
</head>
<body>
<h1>title</h1>
<div class="Mydata">
content
otherContent
</div>
</body>
</html>
The jshtml repo links to the jshtml-express project.
The docs there give an example of how to use this in your project :
var express = require('express');
var port = parseInt(process.argv.pop());
var app = express();
app.configure(function() {
app.use(express.bodyParser());
app.use(app.router);
});
app.engine('jshtml', require('jshtml-express')); // make sure you have installed via npm install jshtml-express
app.set('view engine', 'jshtml');
I have not used this myself, but the process is similar with other templating systems (Jade, Handlebars, etc).
More explanation of what I mean speaking "I would like have masterpage"
I have Layout.jshtml , this is my masterpage
<html>
<head>
<link rel="stylesheet" href="/stylesheets/style.css" ></link>
</head>
<body>
#writeBody();
</body>
</html>
and I have other view called some.jshtml
<h1>#locals.title</h1>
<div class="Mydata">
#locals.content
#locals.otherContent
</div>
When I run this page in browser I would like to have concatenation of layout.jshtml and some.jshtml. The content of some.jshtml is rendered in writeBody(); in layout.jshtml
When I speaking of concatenation I mean someThing like this. This is result that I can see in browser.
<html>
<head>
<link rel="stylesheet" href="/stylesheets/style.css" ></link>
</head>
<body>
<h1>title</h1>
<div class="Mydata">
content
otherContent
</div>
</body>
</html>

Writing to <head> in ClientBehaviorRenderer

I am currently playing around with JSFs ClientBehavior API.
I want to create a client behavior that uses jQuery. Besides inclusion of the *.js files for jQuery another script will be required in the <head> section to bootstrap all the jQuery stuff i.e. create client side widgests.
I tried to follow this approach from victor herrera, but the component system event is never processed. I guess this is because ClientBehaviors do not inherit from UIComponent.
So my question is how to add dynamically created JS to the <head> of the rendered document.
This is what the rendered output in the end should look like:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
$(document).ready(function () {
// Dynamically created stuff here
}
</script>
</head>
<body>
...
<input type="text" id="myJSFInputWithClientBehavior" onclick="doSomeStuffWithjQuery()" />
</body>
</html>

Resources