While Ejs file doesn't see css style? - css

Have problem in my express app. Have some ejs templates, where css style file applied correctly. For example "localhost***/page", but when i go to "localhost***/page/secondpage" my ejs doesn't see style even if i apply it.
A little bit of code
app.js
app.use(express.static(path.join(__dirname, 'public')));
//some code
app.use('/', require('./routes/index'));
app.use('/events', require('./routes/events'));
some routes
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
let query = *db query*;
res.locals.connection.query(query, function (error, results, fields) {
if (error) throw error;
res.render('index', { title: 'Events', data: results });
});
});
router.get('/:id', function (req, res) {
let query = *db query*;
res.locals.connection.query(query, function (error, results, fields) {
if (error) throw error;
res.render('singleevent', { title: 'Event', data: results });
});
});
Head of localhost***/events page and of next page localhost***/events/singleevent
<head>
<meta charset="UTF-8">
<title>
<%= title %>|Minsk Events</title>
<link rel="stylesheet" href="css/style.css">
</head>
There are my dirs

You asked for css file related to the html file.
So if html file is placed under events, then css file should be at:
/events/css/style.css
etc.

Related

404 page for different route doesn't work

I have created a site, that have root, help and 404 paths and pages in hbs format. The issue is that when I run localhost:3000/wrong it shows the site correctly but when I run localhost:3000/help/wrong the css part doesn't get applied to that 404 page as it should, because there is not route /help/wrong.
I run the code using node app.js or nodemon app.js.
Folder Structure:
public
css
styles.css
templates
partials
animal.hbs
info.hbs
views
404.hbs
help.hbs
index.hbs
app.js
package.json
package-lock.json
package.json
"dependencies": {
"express": "^4.17.1",
"hbs": "^4.1.1"
},
"devDependencies": {
"nodemon": "^2.0.7"
}
app.js
const express = require("express");
const hbs = require("hbs");
const app = express();
app.set('view engine', 'hbs');
app.set('views', './templates/views');
hbs.registerPartials('./templates/partials');
app.use(express.static('./public'));
const animal = 'Tiger';
app.get('', (request, response, next) => {
response.render('index', {
title: 'Root',
animal
});
})
app.get('/help', (req, res) => {
res.render('help', {
title: 'Help',
animal
})
})
app.get('/help/*', (req, res) => {
res.render('404', {
title: '404',
animal,
error: 'Help Page Not Found!'
})
})
app.get('*', (req, res) => {
res.render('404', {
title: '404',
animal,
error: 'Page Not Found!'
})
})
app.listen(3000, () => {
console.log("Server is on port 3000");
})
index.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<title>Root</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
{{>info}}
{{>animal}}
</body>
</html>
help.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<title>Help</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
{{>info}}
{{>animal}}
</body>
</html>
404.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<title>404</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
{{>info}}
{{error}}
{{>animal}}
</body>
</html>
animal.hbs
<p>Animal is {{animal}}</p>
info.hbs
<h1>{{title}}</h1>
Root
Help
styles.css
body {
background-color: teal;
}
I have tried explaining the question as best as possible. Please do comment if anything is not clear. Thank you so much.
app.get('/help*', (req, res) => {
res.render('404', {
title: '404',
animal,
error: 'Help Page Not Found!'
})
})
Does removing the / before the * do the trick?

Express-handlebars not filling out {{{body}}}

Using express-handlebars#5.2.0 and express#4.17.1 using node on windows and still cant get it to render in the body:
File Setup:
testapp.js
[views]
main.handlebars
[views][layouts]
test.handlebars
//testapp.js
const express = require('express');
const exhbr = require('express-handlebars');
const app = express();
const port = 3031;
app.engine('handlebars', exhbr({}));
app.use(express.static('public'));
app.set('view engine', 'handlebars');
app.get('/', (req, res) => {
res.render('main', { layout: 'test' });
});
app.listen(port, () => console.log(`App listening to port ${port}`));
<!--test.handlebars-->
<h1>Test</h1>
<!-- main.handlebars -->
<!DOCTYPE html>
<html lang="en">
<body>
{{{body}}}
</body>
</html>
Only <h1>Test</h1> is returned and hasn't been inserted into the body.
I have also tried the following just to make sure its looking in the right spots.
res.render('doesnt_exist');
Error: Failed to lookup view "doesnt_exist" in views directory "c:\wamp\www\rethinkdb_rest\views\"
res.render('main', { layout: "doesnt_exist" });
Error: ENOENT: no such file or directory, open 'c:\wamp\www\rethinkdb_rest\views\layouts\doesnt_exist.handlebars'
Looks like I was putting the main.handlebars and test.handlebars in the wrong directories.
File Setup should be:
testapp.js
[views]
test.handlebars
[views][layouts]
main.handlebars
And the render function in testapp.js should be:
//testapp.js
const express = require('express');
const exhbr = require('express-handlebars');
const app = express();
const port = 3031;
app.engine('handlebars', exhbr({}));
app.use(express.static('public'));
app.set('view engine', 'handlebars');
app.get('/', (req, res) => {
res.render('test', { layout: 'main' }); //<----fixed
});
app.listen(port, () => console.log(`App listening to port ${port}`));

trouble rendering view in deno/oak

I'm using deno, oak, and view_engine.
Here is my file structure:
server.ts
routes
user.ts
view
index.ejs
/user
index.ejs
On my server.js this code works as expected:
router
.get("/", (context: any) => {
context.render("view/index.ejs");
});
But, in my routes/user.ts, the following code does NOT work:
router
.get("user/", (ctx: any) => {
ctx.render("../view/user/index.ejs")
});
Inside render, I tried:
${Deno.cwd}"/../view/student/index.ejs"
"/../view/user/index.ejs"
and out of desperation:
"/view/user/index.ejs"
I'm sure there's a super easy, most obvious thing I'm missing here.
Here is workaround,
import { Application, send, Router } from "https://deno.land/x/oak/mod.ts";
import { viewEngine, engineFactory, adapterFactory, ViewConfig } from 'https://deno.land/x/view_engine/mod.ts';
const ejsEngine = engineFactory.getEjsEngine();
const oakAdapter = adapterFactory.getOakAdapter();
const app = new Application();
app.use(viewEngine(oakAdapter, ejsEngine, {
viewRoot: "./view",
viewExt: ".ejs",
}));
const router = new Router();
app.use(router.routes());
app.use(router.allowedMethods());
router
.get('/', async (ctx, next) => {
ctx.render("index", { data: { name: "Nikhil" } });
});
await app.listen({ port: 8000 });
Inside the view folder i have index.ejs
Run files as,
deno run --allow-net --allow-read server.ts
index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>EJS HOLA</h1>
Hobbies of <%=data.name%>
</body>
</html>
For more resource to add, you can look at view_engine

Node.js can't use external css file

I recently start learning node.js, and I got problem. I use express to acces my public file, everything work fine except css files. I did some research on the topic, and use everthing i found, but it dose not work.
My folder structure
app.js
pub
index.html
style.css
This is my html:
<!DOCTYPE html>
<html >
<head>
<title> Curriculum Vitae </title>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css"/>
</head>
<body>
...
</body>
</html>
And my app.js file:
var http = require('http');
var url = require('url');
var fs = require('fs');
var express = require('express')
var app = express();
var path = require('path');
app.use(express.static(path.join('pub', 'public')));
http.createServer(function (req, res) {
var q = url.parse(req.url, true);
var filename = "." + q.pathname;
fs.readFile(filename, function(err, data) {
if (err) {
res.writeHead(404, {'Content-Type': 'text/html'});
return res.end("404 Not Found");
}
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
return res.end();
});
}).listen(8080);
I think your problem is on this line :
app.use(express.static(path.join('pub', 'public')));
You are setting "/pub/public" as public folder, and you just need to set "/pub"
Can you try with something like this ?
app.use(express.static(__dirname + '/pub'));
Hope it helps.

Using AVA with jsdom, load and execute remote scripts

I'm writing a test with AVA and jsdom.
This works:
const rp = require('request-promise-native')
const jsdom = require('jsdom')
const {JSDOM} = jsdom
const url = 'http://localhost:8000'
rp(url).then((body) => {
const options = {
url: url,
resources: 'usable',
runScripts: 'dangerously',
}
let dom = new JSDOM(body, options)
dom.window.document.addEventListener('DOMContentLoaded', () => {
setImmediate(() => {
console.log(dom.serialize()) // works, prints <html><head></head><body><h1>Hello world!</h1></body></html>
})
})
})
An external script adds an h1 to the document body.
// external.js
document.addEventListener('DOMContentLoaded', () => {
document.write('<h1>Hello world!</h1>')
})
This is the markup at http://localhost:8000:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSDOM test</title>
<script src="external.js"></script>
</head>
<body>
</body>
</html>
When I try the same thing in a test:
const rp = require('request-promise-native')
const test = require('ava')
const jsdom = require('jsdom')
const {JSDOM} = jsdom
const url = 'http://localhost:8000'
test('Check custom CSS', t => {
return rp(url).then((body) => {
const options = {
url: url,
resources: 'usable',
runScripts: 'dangerously',
}
let dom = new JSDOM(body, options)
dom.window.document.addEventListener('DOMContentLoaded', () => {
setImmediate(() => {
console.log(dom.serialize()) // nothing gets printed
})
})
t.pass('passed')
})
})
console.log isn't called. I would expect <html><head></head><body><h1>Hello world!</h1></body></html> to get printed, rather than there being no output.
In summary, I want to:
Grab the response body from a url
Create a new jsdom object from it
Execute the scripts linked to in the response body's head tags
Let the scripts change the markup
Print the resulting modified markup
What is the best way of going about doing this?
Here's a minimum working example: https://github.com/cg433n/jsdom-test

Resources