Send data along with html file using res.render() in express.js/node.js - node.js

How to access variable "name" in index.html file using res.render?
app.get("/", function(req, res){
res.render('index.html',{name: "xyz"});
});
Following is the example of codeigniter, I want to achieve same in node.js:
$data["name"] = "xyz"
$this->load->view("index", $data);
I can access "name" using $name in index.html while working in codeigniter. How to access the "name" variable in index.html while using node.js?

The problem is that you need to use something like $ npm install pug --save for that. Then you can make a 'Pug template file named index.pug in the views directory' (or in the directory of your existing index.html file) This template should contain the following:
html
head
title= title
body
h1= name
Then in your nodeJS file you can use res.render like this:
app.get('/', function (req, res) {
res.render('index', { name: 'xyz' })
})
Here are the docs I used (from the comment) https://expressjs.com/en/guide/using-template-engines.html
Hope this helps!

Related

How to access the variable passed through res.renderer?

I'm passing a variable to my template renderer in ExpressJs like so:
index.js
app.get('/simple_view/', function(req, res, next){
title='A TITLE';
res.render('simple', {
title: title
});
});
I would like to access the title variable in a JS script on my template page, but I'm getting Uncaught ReferenceError: title is not defined error.
simple.pug
script.
console.log(title);
How can I solve this?
The Getting Started for PUG already showcases how to embed variables. You do this by using #{variable_name}, e.g. #{title} in your case.

template layout for PugJs

I used NodeJs with Handlebars and thought about switching to PugJs because some functionality is native - using Handlebars requires some helper functions / partials.
In Handlebars I have to define a layout and pass in the template. In PugJs I created two example routes
First route file:
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index', {
title: 'Home',
template: 'main'
});
});
module.exports = router;
Second route file:
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index', {
title: 'Page2',
template: 'pageTwo'
});
});
module.exports = router;
As you can see I always have to render my index file and pass in the desired pug file as a template variable.
index.pug
doctype html
html
include ./header.pug
body
include ./templates/#{template}.pug
header.pug
head
title #{title} template!
main.pug
script(src='./client/main.js')
h1 main content here
pageTwo.pug
p pageTwo
When rendering the pug files I get this error
ENOENT: no such file or directory, open
'...\views\templates\#{template}.pug'
How can I replace #{template} with the correct template variable?
Dynamic template selection isn't a feature of pug, I believe it has something to do with how pug pre-compiles everything into a JavaScript function that stays in-memory inside node.js when it runs. The benefit of that is super-fast page rendering, so we're happy to keep using pug and just work around this.
Speaking of which, you can accomplish what you want to do using conditional logic:
doctype html
html
include ./header.pug
body
if template === 'pageOne'
include ./templates/pageOne.pug
else if template === 'pageTwo'
include ./templates/pageTwo.pug
else
include ./templates/home.pug
You should also look into the extends feature to simplify adding the header into your templates and mixins to resuse code between templates. You might find that these features could provide a better solution to your requirements with some redesign.

Load templates from existing file

I'm using Handlebars in my NodeJS application as my templating engine.
I've put all my templates in a views folder like so :
-
- /controllers
- /views
- index.html
- server.js
Here's my code to render the template when the user access a given URL (using express for routing) :
app.get("/", function(req, res){
var template = handlebars.compile("views/index.html");
var data = {"name": "Charles"};
var result = template(data);
res.send(result);
});
I'm trying to render a template from a file, but it's not working. This is what the browser outputs directly when I'm accessing the / URL :
views/index.html
That makes sense, since it's interpreting the given param as a string directly and not as a path to an external template.
How can I load my template file (in this case the one in views/index.html to a variable, so that I can then render the template?
The only examples I found were storing all the templates in a file and loading them via AJAX, but all these examples were from "front-end" handlebars and not when using it with Node.
Is it possible to achieve what I want? I looked at the documentation but it's hard to find good infos for handlebars with NodeJS.
From your description, it sounds like you want handlebars as view engine, with dynamic views. You don't need to do this manually, here is an example (using express-handlebars):
var handlebars = require('express-handlebars');
app.engine('.html', handlebars({layout: false, extname: '.html'}));
app.set('view engine', '.html');
app.get("/:view", function(req, res){
var view = req.params.view;
res.render(view, { "name": "Charles" }); // Whatever data you want
});
With handlebars you have to load the file yourself or you can precompile the files (using grunt/gulp maybe) I feel way more confortable with swig ( http://paularmstrong.github.io/swig/ )
It is very simple to use. And it has also integration with express if you want.
var swig = require('swig');
swig.renderFile('/path/to/template.html', {
pagename: 'awesome people',
authors: ['Paul', 'Jim', 'Jane']
});
In your case
app.get("/", function(req, res){
res.send(swig.renderFile('views/index.html', {"name": "Charles"}));
});

NodeJS, Express - Render EJS view to a download file

I have a NodeJS, Express 3 app that uses EJS templating. I have a route that enables 'preview' of some form fields containing HTML and CSS that are posted. It simply plugs them in and renders my preview.ejs template like this..
app.post('/preview', function(req, res){
var htm = req.body.htm;
var css = req.body.css;
res.render('preview',{_layoutFile:'', htm:htm, css:css});
});
What I'd like to do now is a similar route that forces download of the file instead..
app.post('/download', function(req, res){
var htm = req.body.htm;
var css = req.body.css;
// res.download or res.sendfile here ??
});
I see that there is a res.sendfile() and res.download(), but how can I use these with my EJS 'preview' view template?
P.S. - I'm also using Mikeal's request is this same app. I wonder if there is a way I could use pipe to fs (filesystem) and then force download of the saved file?
See: http://expressjs.com/api.html#res.attachment
res.attachment() sets Content-Disposition: attachment header which tells the browser to treat the response as a download.
app.post('/download', function(req, res){
var htm = req.body.htm;
var css = req.body.css;
res.attachment();
res.render('preview',{_layoutFile:'', htm:htm, css:css});
});

how do i compile multiple jade files

let's start off with the following 4 jade files.
layout.jade
html
head
block cms_head
body
block cms_body
home_page.jade
extends layout
block append cms_head
title home page
block append cms_body
p superman ate so many different apples
plugin_a.jade
block append cms_body
p i got plugged in... genius
plugin_for_jquery.jade
block append cms_head
script(src="/jquery-1.8.3.js")
so i can easily render the home page by doing:
app.get("/", function(req, res){
res.render("home_page");
});
which is fantastic, however in order to allow for plugability in my app, i would like to allow their views to take advantage of existing templates, and append/prepend/replace content to whatever the plugin needs to show.
what i am trying to do is render home_page.jade, then render plugin_a.jade and plugin_for_jquery.jade ... the basic idea is there can be a variable number of plugins, and each plugin adding it's own content to the view.
I tried this (obviously it didn't work)
for plugin in plugins
include= plugin.name
So any ideas on how i can do that?
as far as i know there is no possability in jade to readout the directory
but using node:
var fs = require("fs");
app.get("/", function(req, res){
fs.readdir(DIR_OF_PLUGINS, function(err, list){
res.render("home_page", {"list": list});
});
});
and in homepage.jade
- for(plugin in list)
include = plugin
btw: you should build a router and a functions document with something like
//router.js // or app.js
var funct = require("routes/functions")
app.get('/', funct.home);
//functions.js
exports.home = function(req, res){

Resources