Why is mypartial.ejs not showing? - node.js

I am trying to learn node.js with the help the book "Get programming with node.js" by Jonathan Wrexler. In chapter 10 the use of partials is explained very briefly and I am not getting it to work.
I made a nav.ejs in the partials-folder that looks like this:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
The layout.ejs-example in the book looks like this:
<body>
<header>Header</header>
<nav>
<% include partials/nav %>
</nav>
<%- body %>
<footer>Footer</footer>
</body>
But this gives me a syntax-error:
SyntaxError: Unexpected identifier in C:\node-projects\wandelverhalen\views\layout.ejs while compiling ejs
With the help of stackoverflow I changed the include template to:
<% include ("partials/nav"); %>
This solved the error, but it does not show the nav when I run it. And the page source shows a <nav>-tag that is empty.
I would appreciate any help.
For the sake of completeness, this is my index.js:
"use strict";
const port = 3000;
const express = require("express");
const app = express();
const homeController = require("./controllers/homeController");
const layouts = require("express-ejs-layouts");
app
.set("view engine", "ejs")
.use(
express.urlencoded({
extended: false
})
)
.use(express.json())
.use(layouts)
.use((req, res, next) => {
console.log(`Request made to ${req.url}`);
next();
})
.get("/", homeController.sendReqParam)
.get("/:myname", homeController.sendReqParam)
.listen(port, () => {
console.log(`Server is running on port ${port}`);
});

You want to use <%- include ("partials/nav"); %> to render your partial. The <% is just for scripting and control-flow and produces no output, thus you are not seeing anything added to the page. Adding a - after <% will cause it to output the unescaped value of include ("partials/nav").

Related

Bundler similar to webpack that can compile node.js express and EJS files

After trying to set up webpack5 + express + ejs to no avail, I'm looking for some kind of "bundler" that will optimize my server code (files) so those will be automatically minified/uglified/obfuscated/bundled/converted to ES5/ etc. when there is any code change. It must support server side EJS partials (cause I have almost finished project that use EJS from scratch), has option to modify (for example bundle/not bundle) or leave intact specific files.
I know what bundlers there are on the market but I did not try them - I don't know which one is best suited for my needs (if any, besides webpack ofcourse - cause I'm to stupid to properly set it up, cause of How do I serve Webpack bundles with EJS templates? or
Webpack 5 + express + EJS templates ...).
Ejs render loaders seems to require that you pass in your inline variables in the config file, rather than in your Express routes, which doesn't make much sense to me.
webpack: 5.38.1
express": 4.17.1
ejs-render-loader: 1.0.0*
I have difficulties configuring Webpack 5 to properly use EJS template files. Setup looks like this:
INDEX.JS
var express = require('express');
var app = express();
var page1 = require('./routes/page1.js');
var page2 = require('./routes/page2.js');
app.set('view engine', 'ejs');
app.set('views', __dirname + '/ejs');
var server = https.createServer(options, app).listen(port, host, function()
{
console.log('server is running!');
}
app.use('/page1', page1);
app.use('/page2', page2);
// + bla bla bla
PAGE1.JS
router.get('/', function(req, res, next)
{
res.render('page1', {data : data}); // here we render ejs file
res.end();
}
router.post('/page2', function(req, res, next)
{
// + bla bla bla
res.render('page2', {data : data}); // here we render ejs file
res.end();
}
PAGE1.EJS
<!DOCTYPE html>
<html>
<head>
<title>PAGE1</title>
<%- include ('head.ejs'); %>
</head>
<body>
<%- include ('header.ejs'); %>
<%- include ('menu.ejs'); %>
<div class="errors">
<% if (typeof errors == "undefined") { %>
<% } else { %>
<%- errors %>
<% } %>
</div>
</body>
</html>
PAGE2.JS
router.get('/', function(req, res, next)
{
res.render('page1', {data : data}); // here we render ejs file
res.end();
}
PAGE2.EJS
<!DOCTYPE html>
<html>
<head>
<title>PAGE2</title>
<%- include ('head.ejs'); %>
</head>
<body>
<%- include ('container.ejs'); %>
</body>
</html>
WEBPACK.CONFIG.JS
module.exports = {
target: "node",
entry: {
main: './SRC/index.js'
},
externalsPresets: {node: true},
externals: [webpackNodeExternals()],
module: {
rules: [
{
test: /\.ejs$/,
use: {
loader: 'ejs-render-loader'
}
}
]
}
}
Can somebody who has working config, show his settings, so I can adjust mine? Cause now EJS files are not bundled - seems webpack has problem with included data inside those files. Thanks!

ejs includes header but in some page don't load image

Folder list
Hi, I'm new to node, express and ejs; this is a folder list of my project and for some reason when I include the header and footer on home.ejs, I can see the image on the navbar, but if I do the same in terms-condition.ejs, node load the page correctly with the footer and the navbar, but the logo-image isn't shown in the page.
The only difference between home.ejs and terms-condition.ejs is that the last one is in a subfolder of /views.
index.ejs
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
app.get("/", function(req, res) {
res.render("home");
});
app.get("/legal/terms-condition", function(req, res) {
res.render("legal/terms-condition");
});
app.listen(3000, function(){
console.log("Server started on port 3000.");
});
home.ejs
<%- include("common/header") -%>
<div class="box">
Terms and Condition
</div>
<%- include("common/footer") -%>
terms-condition.ejs
<%- include("../common/header") -%>
<div class="container">
<div class="row">
<div class="col-6">
<h1>This is a sample</h1>
</div>
<div class="col-6">
<p>Why ejs not load the logo in the navbar?</p>
</div>
</div>
</div>
<%- include("../common/footer") -%>
here the link to my project on GitHub
You need to prefix the images/Stack_Overflow_icon.svg with / i.g. /images/Stack_Overflow_icon.svg. In your code, did you notice that the styles.css loading correctly because you've prefix it with /.
You're facing this issue because the file terms-condition.ejs is within a folder whereas home.ejs not.
P.S. You should always put node_modules in .gitignore file.

local host not responding when ejs templates are added

local host is not loading when partials(ejs templates) are added to the pages.The page loads at first if the partials are not added.But once the partials are added the page no longer loads.Also no error is also being reported.The page keeps on loading and finally shows unable to reach the adress.
var express = require("express");
var app = express();
var bodyparser = require("body-parser");
app.use(bodyparser.urlencoded({extended: true}));
app.set("view engine", "ejs");
app.get("/", function(req , res){
res.render("landing");
});
app.get("/campgrounds", function(req,res){
res.render("campgrounds",{campgrounds:campgrounds});
});
app.post("/campgrounds",function(req,res){
var name = req.body.name;
var image = req.body.image;
var newCamp = {name: name, image:image}
campgrounds.push(newCamp)
res.redirect("/campgrounds");
});
app.get("/campgrounds/new", function(req, res){
res.render("new.ejs");
});
app.listen(3000, function(){
console.log("Yelp camp server has started");
});
when the headers are added to the the following page the page no longer loads
<%- include('partials/header.ejs') %>
<h1>landing page</h1>
view all campgrounds
<p>asdasdasda</p>
<%- include('partials/footer.ejs') %>
Please help!!!!
also here is the code for the header
<!DOCTYPE html>
<html>
<head>
<title>YELPCAMP</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
</head>
<body>
<p>header tabs</p>
You're missing a - from the closing tag:
<%- include('partials/header.ejs') -%>
...
<%- include('partials/footer.ejs') -%>
Thanks for the help ,
The problem was occurring because of an incorrect bootstrap cdn and the partials declaration.
Fixed those issues and the app is now working fine.

How do I inject a variable into an EJS template with Node.js + Express3?

I'd like to be able to use Underscore.js from within my EJS templates, like this:
<% _.each(articles, function(article){ %>
<section>
<h2><%= title %></h2>
<%= body %>
</section>
<hr/>
<% }) %>
I could inject it for every single route like so...
var _ = require('underscore');
exports.index = function(req, res){
res.render('index', { _: _, articles: app.allArticles() });
};
But that's tedious and prone to human error. Is there a general solution for this, to inject it for all views, all of the time?
You can do this whith app.locals.
var _ = require('underscore');
var express = require('express');
var app = express();
app.locals._ = _;
// some code
app.listen(3000);

Upgrading Express 2.0 to 3.0 project

I am somewhat new to node programming and trying to follow some tutorials. They're almost all written for 2.5.x. I've read the migration page for Express but there are no clear working examples for a newbie. My question is addressing the following areas:
req.flash()
layouts and partials
dynamicHelpers
for 'old way' vs. 'new way' examples and not just snippets or additional modules to make the older version code still work as I'd like to work with the new style of working with Express. Thanks in advance.
As you found the old-way examples already, here are the 'new' ways:
'new' req.flash:
// insert in app.js as middleware, after express.static
app.use(function(req, res, next) {
var msgs = req.session.messages || [];
res.locals({
messages: msgs,
hasMessages: !! msgs.length
});
req.session.messages = [];
next();
});
// save a message
res.message('error', 'message');
// output
<% if (hasMessages) { %>
<ul id="messages">
<% messages.forEach(function(msg){ %>
<li class="<%= msg.type %>"><%= msg.msg %></li>
<% }) %>
</ul>
<% } %>
'new partials':
// install
npm install express-partials
// app.js
var partials = require('express-partials');
app.use(partials());
// usage
<%- body %>
'new' dynamicHelpers:
// middleware
app.use(function(req, res, next) {
res.locals.user = req.user;
next();
});
// usage
<%= user %>

Resources