How to use multiple blocks from different files? - node.js

I have a layout.jade that looks like this:
html
body
block content
block footer
My content.jade looks like that:
extends layout
block content
#Content Welcome
My footer.jade looks like that:
extends layout
block footer
#Footer Impressum
Now, when I run my app like that:
app.get('/', function(req, res) {
res.render('layout');
});
I do not see neither the content nor the footer.
When I run:
app.get('/', function(req, res) {
res.render('content');
});
Then I see the content.
When I run:
app.get('/', function(req, res) {
res.render('footer');
});
Then I see the footer.
How can I see both, content and footer?

You probably want something like this:
layout.jade
html
body
block content
include footer
pagename.jade
extends layout
block content
h1 My Content
footer.jade
p.footer Here is my footer
Then run res.render('pagename');.
Unless you want to have specific stuff in your footer per page, there's no point in making it a block.

Related

Changing script files used on the front end of a node backed website

I'm making a solitaire game using NodeJs and Express backend and phaser.io frontend. It will offer different layouts of cards to play.
I have the game working "just fine" alpha state, but with a single layout of cards setup in HTML like:
<script src="js/gameboards/data.js"></script>
<script src="js/tableau.js"></script>
where data.js is the file that describes the card layout, and tableau.js is the game logic. I have several different files in /gameboards and for the testing/building, I just change the filename when I want to change the layout.
data.js is not a JSON file, it's a JS object
let gameboard = {
info: {
title: "Standard",
description: "6 columns of 5 cards"
},
[...]
deal: function() {
for (let i = 0; i < this.vars.allstacks; i++) {
etc...
That contains simple object data as well as object methods that define patterns and repetition (like multiple stacks, pyramids, etc) so it can't really be made into a JSON or other straight data file.
What I want to do is present a list of anchors/links to the player of the layout options. They'll click the link to get sent into /game with the layout they chose.
The method I thought of was to have /index send POST-data containing the layoutname. Then, in /game
router.post('/', function(req, res, next) { ... })
with the HTML template and res.render containing
<script src="js/gameboards/<layoutname>.js"></script>
to call the right file.
Is there a better way of doing this than what I listed above? It seems kludgey to me as if there would be a more 'nodey' and elegant way to do it.
To do it in the way you describe you need to enable a templating engine like handlebars or Pug. For pug I do something like this:
In server:
const cdnAction = process.env.S3_CDN_ACTIVE;
app.route('*')
.get( (req, res) => {
const cdnCSSPath = `https://s3.amazonaws.com/${process.env.S3_BUCKET_CDN}/audience.css.gz`;
res.render('home', { cdnActive, cdnPath, cdnCSSPath });
});
In pug file 'home.pug' rendered above:
head
if cdnActive === 'true'
link(href=cdnCSSPath rel='stylesheet' type='text/css')
else
link(href='/style/embed.css' rel='stylesheet' type='text/css')

Why is my jade index page blank?

I'm broadly following this tutorial on Express, Mongo and Jade, and although I've successfully fetched back some data from mongo, but jade isn't rendering my page.
http://blog.ijasoneverett.com/2013/03/a-sample-app-with-node-js-express-and-mongodb-part-1/
Snippets are:
app.js:
app.get('/', function(req, res) {
employeeProvider.findAll(function(error, emps) {
// adding logging here shows that 'title' and 'emps' are correctly populated
res.render('index', { title:'Employees', employees:emps });
});
});
layout.jade:
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
index.jade:
extends layout
block content
h1= title
div
each employee in employees
div.employee
div.created_at= employee.created_at
div.title= employee.title
div.name= employee.name
When I extract the source from the page displayed in the browser, it just shows this:
<!DOCTYPE html><html><head><title>Employees</title><link rel="stylesheet" href="/stylesheets/style.css"></head><body></body></html>
In fact, nothing I put in jade.index to simplify it seems to get rendered. eg this also renders a blank page:
index.jade:
extends layout
block content
h1= title
Check again the tutorial and follow it (realy), since your code is diferent...
http://blog.ijasoneverett.com/2013/03/a-sample-app-with-node-js-express-and-mongodb-part-1/
The index.jade should be:
extends layout
block content
h1= title
#employees
- each employee in employees
div.employee
div.created_at= employee.created_at
div.title= employee.title
div.name= employee.name
a(href="/employee/new")!= "Add New Employee"
There are some needed css over #employees and
the each loop needs a - before itself.

Issue getting information to jade template with angular

I am working on a simple web app (new to it) and I am using jade/angular. I am trying to get a list to display some information, this is what I have:
layout.jade:
doctype
html(ng-app)
head
title= title
script(type='text/javascript', src='javascripts/lib/angular.min.js')
script(type='text/javascript', src='javascripts/lib/angular-resource.min.js')
script(src='//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js')
script(type='text/javascript', src='public/javascripts/app2.js')
link(rel='stylesheet',type='text/css', href='/stylesheets/boostrap.css')
body
block content
index.jade:
extends layout
block content
h1= title
div(class="container" ng-controller="AppCtrl")
h1 Angulair
ul(ng-repeat="airport in airports")
li {{airport.code}}
li {{airport.name}}
li {{airport.destination}}
and finally app2.js:
function AppCtrl ($scope){
$scope.airports = {
"PDX": {
"code": "PDX",
"name": "Portland",
"city": "Toronto"
}
};
}
EDIT: Everything below here is an edit...
I am working with node as well, this is what my project looks like
node_modules/
public/
img/
javascripts/
app2.js
stylesheets/(bootstrap files in here)
routes/
index.js
views/
partials/
index.jade
layout.jade
app.js
package.json
Also, I am using node for this project, In app.js I make a call to:
app.get('/', routes.index);
index.js:
exports.index = function(req, res){
res.render('index', { title: 'Angular Basic' });
};
As you can see, very simple stuff, but I cannot seem to get the list to display that airport information. Am I wrapping the jade template with angular correctly?
I CHANGED THE SCRIPTS IN layout.jade to include the angular resources. Now Nothing appears. I also added the brackets around the elements in the list tags, as suggested below. Still nothing appears.
tire0011 + Daiwei are both correct.
It's not your jade that is the problem. Here's a working sample incorporating tire0011 + Daiwei's suggestions:
http://plnkr.co/edit/q2DMGO0P50nWdf1PGlNJ?p=preview
you need to add a app module name
doctype
html(ng-app="appName")
then in your script first create your module and then the controller
var myModule = angular.module('appName', []);
myModule.controller("AppCtrl", function ($scope) {
// do your stuff
}
The problem is in your li tag, use {{ XXX }} to wrap your properties
li {{ airport.code }}
li {{ airport.city }}
li {{ airport.name }}

How to know if block content is empty in Jade

How can we check if block is exist in Jade, I'm trying to make a template in Jade where in i have following block in layout.jade and in login.jade i have extended layout.jade. Now when in account.jade i will have both left and main content blocks
extend layout.jade
div(class='col-md-4')
block leftcontainer
div(class='col-md-8')
block content
Now in login.jade i want to hide
div(class='col-md-4')
block leftcontainer
and make the main content full page, if leftcontainer is not there. It should look like this
div(class='col-md-12')
block content
if user is on some page i want to hide left column block. Say if user is in login page then
If I got it right, you wan't to hide a block if a user (e.g. a user who is logged in to your app) is at a certain page. If this is right do something like this:
Example with Express & Passport:
// server
app.get('/login', function(req, res){
if(req.isAuthenticated()) {
res.render('login', { 'user' : req.user } );
} else {
res.render('login', { 'user' : null } );
}
});
// layout
extend layout.jade
if user !== null
div(class='col-md-12')
block content
else
div(class='col-md-4')
block leftcontainer
div(class='col-md-8')
block content
In general you can work with other conditional statements in Jade, without Passport, this was just an example. You may want to take a look at the reference, especially under conditional or case.

Linking to other jade files

I'm trying to understand how Express and Jade works.
First of all, am I doing it right when I'm using layout.jade as a template file (header, body, footer) and using different files to show information in the body (see examples below)?
The code works fine, but i'm unsure if this is the right way to do stuff in Express. If I should keep going with this structure, how can I link to other files (eg.About.jade) internally from for example index.jade, to show that file instead of index.jade?
Thanks in advance!
layout.jade:
!!! 5
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
script(type='text/javascript', src='https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js')
script(type='text/javascript', src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js')
script(type='text/javascript', src='/javascripts/external.js')
// Header
header#header
// Navigation
nav#nav
// Navigation code (ul, li etc)...
// Sidebar
aside#sidebar
// Sidebar code...
// Body
body!= body
index.jade:
!!! 5
html
head
title= title
section#wrapper
img.imageStyle(src = '/images/test1.png')
// And so on...
About.jade:
// You get it...
I think what you're looking for are view rendering routes in express:
http://expressjs.com/en/guide/using-template-engines.html
So you can set up something like this:
app.get('/', function(req, res){
res.render('index.jade', { title: 'index' });
});
app.get('/about', function(req, res){
res.render('about.jade', { title: 'about' });
});
To link from one to the other, once you have the proper routes configured, you can just do something like:
a(href='/') index
a(href='/about') about
Update Also, you don't need this repeated again in index.
!!! 5
html
head
title= title
additionally to what Wes Freeman wrote you can also include other jade templates in your jade file.
that way you could have your header.jade, footer.jade and include them in your about.jade file. here's the include documentation from jade:
https://github.com/visionmedia/jade#a13
that way you only have to change the header.jade file if you add for example script or stylesheet tags that should be on every page.

Resources