I'm trying to create a basic blog platform to help me get my feet wet with node. I'm using Express as a framework and ejs as my rendering engine. On my homepage, I'd like to display the last ten blogs. So far, I have:
"use strict";
var mongo = require("mongodb")
, server = new mongo.Server("localhost", mongo.Connection.DEFAULT_PORT, {auto_reconnect: true, safe:true})
, mdb = new mongo.Db("blog", server)
, querystring = require("querystring")
, express = require('express')
, app = express();
app.configure(function() {
app.set('view engine', 'ejs');
});
module.exports = {
home: function home(req, res) {
var blogs;
//Load blogs from db
mdb.open(function(err, db) {
db.collection("blogs", function(err, collection) {
var stream = collection.find({}, {"limit": 10, "sort": {"created": -1}}).stream();
stream.on("data", function(item) {
app.render('blogItem', {title: item.title, content: item.content}, function(err, html) {
if(err) { console.error(err); return; }
blogs += html;
});
});
//Render the finished page
stream.on("end", function() {
res.render('home', {title: "AwesomeBlog", content: blogs});
db.close();
});
});
});
}
};
ejs files:
home.ejs
<!DOCTYPE html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %>!</h1>
<%= content %>
Admin section
</body>
blogItem.ejs
<h4><%= title %></h4>
<p><%= content %></p>
While this technically "works", the rendered HTML per-blog is interpreted as plain text, resulting in
AwesomeBlog!
<h4>Hi</h4> <p>test 123</p> <h4>Awesome title</h4> <p>Awesome text</p> <h4>FIRST</h4> <p>POST!</p> Admin section
How can I fix this in this case?
What's the best practice for what I'm trying to do?
That's a safety feature built-into EJS. It stops your users from embedding html that contains javascript exploits (XSS) in your pages. (They can still submit unsafe strings in form requests, etc, but your template escapes it to prevent browser exploits.)
To turn it off (for HTML content you can trust):
Escapes html by default with <%= code %>
Unescaped buffering with <%- code %>
Simply switch the tags in your template like this:
<h4><%= title %></h4>
<p><%- content %></p>
Related
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!
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 render a page in node (using a router) which just passes a value to the template engine for me to use?
So for instance (this is the real code):
var apiRouter = express.Router();
apiRouter.get('/myPosts', function(req, res){
userPostsModel.findOne({'profileID':req.session.facebookProfileId}, function(err, userPosts) {
if(userPosts) {
res.json({
posts : userPosts.posts
});
} else {
console.log('You do not have any posts');
}
})
})
And the template engine part (html file):
<!doctype html>
<head>
<meta charset="UTF-8">
<title>My Posts</title>
</head>
<body>
<p>Post 1</p>
<p>Post 2</p>
</body>
</html>
I am expecting this to render the page but instead, I am getting this (on the webpage):
{"posts":["12345667"]}
For my template engine, I am using 'hogan-express', as below:
app.engine('html', require('hogan-express'));
app.set('view engine', 'html');
I know the res.json may be wrong here but I am not getting anywhere with this. The documentation for node and the routers is all over the place!
As #Molda has answered in the comments, below, it should be like this:
res.render('template-name', { posts:userPosts.posts});
Tried it and worked for me.
Eh, my third question about API and still cannot manage to work it the way I want... Anyways, I have two files: app.js and index.html.
My index.html is simple form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Steam</title>
</head>
<body>
<form>
Steam User ID: <br>
<input type="text" name="steamid"><br>
<input type="submit" value="PoĊĦalji">
</form>
</body>
</html>
Form is getting Steam User ID and submit button, to submit this form.
My app.js:
//Express
var express = require('express');
var server = express();
//SteamWebAPI
var SteamWebAPI = require('steamwebapi').SteamWebAPI;
SteamWebAPI.setAPIKey('7DB297EBF0D0FC352539B4AF9C7C850B');
//Render - Form
server.get('/user_id', function(req, res) {
app.render('form', function(err, html) {
if(err)
return res.send(err);
else
return res.send(html)
});
});
//Route - Form
server.post('/user_info', function(req, res) {
var _userID = req.body.userId;
//Variable - SteamWebAPI
SteamWebAPI.getRecentlyPlayedGames(_userID, 5, function(req, res) {
return res.json(response.response.games);
});
});
// Localhost
server.listen(3000, function() {
console.log('Server: 3000');
});
Someone correct me if I'm wrong:
-after i require express and steamwebapi, i'm getting informations (in this case steam id) from form,
- then this variable _userID is equal to req.body.userId; and i dont know why...anyways...error im getting is: **ReferenceError: app is not defined
**
Can someone help me with this? Is this Node too hard? Like, It's simple. User enter id in form, server getting form? and returning in json format? What I'm doing wrong???
PS: Doing simple way, when I enter Steam ID, I get in console.log game: CS:GO for example...Is there way to display as icon? Obviously I cannot in console so I need to use angular, ember, or what? Thx folks
Just add this before using app variable:
var app = express();
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 %>