Using a global wrapper template in Express/Jade - node.js

I've had a quick skim of the Jade documentation and I can't seem to figure out how to apply a wrapper to all templates that I output.
How is this usually done?

It sounds like you want template inheritance:
// layout.jade
!!!5
html
body
block content
The content block is what you define in all templates that are going to inherit the layout template:
// index.jade
extends layout
block content
h1 Hello World!
When you render index.jade, this is the result:
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
</body>
</html>
So in layout.jade, you set up all common elements like JS/CSS, headers/footers, etc.

Related

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}}

How to use HTML syntax in jade templates

I want to focus on learning how to build things in node without having to fiddle about with the jade syntax. I want to know if its possible to blend native html syntax in jade templates along with its looping syntax etc.If so how. If not, is there a template engine for node that will allow this.
Thank you.
For sure you can blend plain HTML and Jade code, just use Piped Text.
For example:
| Plain HTML
Here an example from the Jade Online Demo (actually great to play around with and test some sort of things!):
doctype html
html(lang="en")
head
title= pageTitle
script(type='text/javascript').
if (foo) {
bar(1 + 5)
}
body
h1 Jade - node template engine
#container.col
if youAreUsingJade
p You are amazing
else
p Get on it!
p.
Jade is a terse and simple
templating language with a
strong focus on performance
and powerful features.
| Plain HTML
with this test data:
{
pageTitle: 'Jade Demo',
youAreUsingJade: true
}
generates this code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Jade Demo</title>
<script type="text/javascript">
if (foo) {
bar(1 + 5)
}
</script>
</head>
<body>
<h1>Jade - node template engine</h1>
<div id="container" class="col">
<p>You are amazing</p>
<p>
Jade is a terse and simple
templating language with a
strong focus on performance
and powerful features.
</p>
</div>Plain HTML
</body>
</html>

Jade Include doesn't render included page content

I'm trying do an app with Node/Express/Jade/Stylus.
The problem is that Jade won't render the content of an included file.
Here are the files:
layout.jade:
doctype 5
html
block head
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
header
block header
#main-container
block content
footer
block footer
index.jade:
extends layout
include helpers/header
block content
form#form-login
helpers/header.jade:
extends ../layout
block header
#test
p Hello World
img(src="images/Logo.jpg" alt="Logo")
The rendered page is blank. In the page there is nothing. The image url is right, so tha's not part of the problem. I checked the page code, and header.jade was completely ignored.
I checked if the header.jade is loaded, and it is loaded (I tried putting an error in it).
Here the code of the rendered page:
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<header></header>
<div id="main-container">
<form id="form-login"></form>
</div>
<footer></footer>
</body>
</html>
It looks like a block doesn't propagate properly from an include to a layout (I'm not overly familiar with Jade so this might be intended behaviour), because this seems to work:
// index.jade
extends layout
block header
include helpers/header
block content
form#form-login
Also, you shouldn't use extends ../layout in your header include, otherwise your layout file will be rendered twice.

How to use literal expressions under templates in locomotivejs?

I have the following template:
<!DOCTYPE HTML>
<html>
<head>
<link href="css/style.css" rel="stylesheet"/>
<script type="text/javascript" src="/js/libs-0001.js" async="async"></script>
<script type="text/javascript" src="/js/app-0004.js" async="async"></script>
<script>
var name = {literal}<%= name %>{/literal};
var version = {literal}<%= version %>{/literal}};
</script>
</head><body></body></html>
Like in smarty, from php, I want to use {literal} declarations in the template, under the script session.
How to do this in locomotivejs views?
As far as I understand {literal}/{/literal}, everything between those tags isn't interpreted. EJS templates don't have something similar, although there are ways of circumventing that.
One way is to configure EJS to use different open/close tags, described here.
Another way is to use a different templating engine altogether, which isn't too difficult since LocomotiveJS isn't hardcoded to using EJS templates. I like the Swig templating engine myself, which has the {% raw %} tag that seems to do the same as {literal}.

How to append block to parent using jade template

I'm trying to create a modular layout using jade template. I would like to append a script block from a child into its parents parent. I'm not quite sure if its possible at all.
Here is my structure
layout.jade
head.jade
index.jade
users.jade
layout.jade:
doctype
html#html
include head
body
block content
head.jade:
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
block scripts
index.jade:
extends layout
block content
h1 Hello
include users
users.jade
block append scripts
script(src='/javascripts/user.js')
ul
each user, i in users
li(class=i+"-"+user) #{user}
My desired html output should be:
<!DOCTYPE html>
<html id="html">
<head>
<title>Index</title>
<link href="/stylesheets/style.css" rel="stylesheet">
<script src="/javascripts/user.js"> <!--// append this from user.jade into head.jade //-->
</head>
<body>
<h1>Hello bob</h1>
<li class="0-user1">user1</li>
This should be possible, and there are examples in the jade documentation that do exactly this. Your code all looks fine except you need to indent your script tag in users.jade so it is indented below the block append script directive.
I tried to use the same approach to define a tab-control.
I defined the pages in separate jade-files.
Each jade-file appended a block that contained the tab-page which was included.
It also did not work until I appended something to the block in my 'index.jade' as below:
extends layout
append scripts
//- dummy
block content
h1 Hello
include users
However I also would like to add that since I added multiple .jade files I ran in the following. Each file inclued jade-template used block append to add a tab-page but the order in which the pages were added was reversed.

Resources