nunjucks: Error: template not found, Problems with directories - javascript

Sorry if I report with a problem that has been dealt with frequently in the forum.
I get the error message that the template was not found.
Error: template not found: D:\Development\src\nunjucks\pages\templates\text.njk
What am I doing wrong with the directory structure specification?
Is there a way how to generate html files from nunjucks files like gulp? With gulp it works.
This is the script for node.js:
const express = require('express');
const app = express();
const server = require('http').Server(app);
const nunjucks = require('nunjucks');
app.use(express.static('dist'));
nunjucks.configure('src/nunjucks', {
autoescape: true,
express: app,
watch: true
});
app.engine ('njk', nunjucks.render);
app.set('view engine', 'njk');
app.get('/', (req, res) => {
res.render('pages/index2');
console.log("index");
})
server.listen(3010, () => {
console.log('http://localhost:' + 3010);
})
And this is the directory structure:
app.js
gulpfile.js
|-src
| |-nunjucks
| |-pages
| | index.njk
| |-templates
| text.njk
And this is the index.njk file:
<html lang="en">
<head>
<title>Test</title>
<meta charset="utf-8">
</head>
<body>
<h1>Header Test</h1>
{% include "text.njk" %}
</body>
</html>

All your templates will be resolved from the path(s) you a passing to nunjucks.configure.
In your case you should include template with path from src/nunjucks.
E.g.templates/text.njk.

That is the solution in the script for node.js
nunjucks.configure('src/nunjucks', {
autoescape: true,
express: app,
cache: false,
watch: true
});
// app.set('views', 'src/nunjucks/pages');
app.engine ('njk', nunjucks.render);
app.set('view engine', 'njk');
app.get('/', (req, res) => {
res.render('pages/index.njk');
})
app.get('/index.html', (req, res) => {
res.render('pages/index.njk');
})
And the index.html file
<html lang="en">
<head>
<title>Test</title>
<meta charset="utf-8">
</head>
<body>
<h1>Header Test</h1>
{% include "../templates/text.njk" %}
</body>
</html>

Related

How I can append js into a express handlebars template using partial?

In my project I use the following handlebars template (under views/layouts/main.handlebars) :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{title}}</title>
{{{css}}}
{{{js}}}
</head>
<body>
<header>
<!-- some content here -->
</header>
<main>
{{{body}}}
</main>
<footer>
I am footer
</footer>
</body>
</html>
And for my home page I made a simple content named ./views/home.handlebars
<h1>Hello</h1>
In order to render the template I use express handlebars:
const express = require('express');
const path = require('path');
const express_handlebars = require('express-handlebars');
const app = express();
const hbs = express_handlebars.create({
// Specify helpers which are only registered on this instance.
defaultLayout: 'main'
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.set('views',path.join(__dirname,'/../../views'));
app.get('/', (req, res, next) => {
res.render('home');
});
app.listen(3000);
What I want is to place some javascript once I visit http://0.0.0.0:3000 for example:
<script>alert("Hello");</script>
Where I want to be appended is in {{{js}}} partial. Is there a way to do it?
An approach of mine is to make the js section as an array and place a base html5 tag, specifying where each page will find its js:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{title}}</title>
{{{css}}}
{{#each js}}
<script src="{{this}}"></script>
{{/each}}
</head>
<body>
<header>
<!-- some content here -->
</header>
<main>
{{{body}}}
</main>
<footer>
I am footer
</footer>
</body>
</html>
For my application's js I use separate files per page and I do not embed it inside my homepage into a folder named static:
const express = require('express');
const path = require('path');
const express_handlebars = require('express-handlebars');
const app = express();
const hbs = express_handlebars.create({
// Specify helpers which are only registered on this instance.
defaultLayout: 'main'
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.set('views',path.join(__dirname,'/../../views'));
app.use('/static',express.static(path.join(__dirname,'/../static')));
app.get('/', (req, res, next) => {
res.render('home',{
title:'Homepage',
js: [
'/static/js/home.js'
],
baseUrl: `${req.protocol}://${req.get('host')}`
});
});
app.listen(3000);
Then upon static folder I place the necessary js files that will run upon the browser. I found it as an easy-peasy solution and keep client-side js into its own folder.

Can't load/find files on server with node.js, 404 error (not found)

I'm trying to load a script.js and a style.css file on the server. The index.html and index.js work fine, however, there seems to be an error when I try to load the style.css file and script.js file, which I use for backend.
GET http://localhost:4000/script.js net::ERR_ABORTED 404 (Not Found)
All my files are in the same directory, /public.
I already checked the CSS file, and it loads when I display the HTML file when it's not on the server.
This my index.js file:
const express = require('express');
const cors = require('cors');
const fs = require('fs')
const ytdl = require('ytdl-core');
const app = express();
const path = require('path')
app.use('/static', express.static(path.join(__dirname, 'public')))
app.use(cors());
app.listen(4000, () => {
console.log('Server works at port 4000');
});
app.get('/', function(req,res){
res.sendFile(__dirname + '/index.html');
});
app.get('/download', (req,res) => {
var URL = req.query.URL;
res.json({url:URL});
})
The HTML file:
<!DOCTYPE HTML>
<html lang="en">
<head>
<link href="/style.css" rel="stylesheet" type="text/css"/>
<meta charset="UTF-8">
<title>PyTube</title>
</head>
<body>
<h1>PyTube</h1>
<input type="url" name="yturl" class="URL-input" id="yturl" placeholder="https://www.youtube.com/watch?v=" required>
<button class="convert-button">Convert</button>
</body>
</html>
<script src="script.js"></script>
I've tried a bunch of things and trying things with __dirname and paths, but I can't find the issue or fix it.

node js res.render does not work, but res.send does

I am setting up the environment for a node js app. But the views/ejs files are not being rendered.
If i do:
app.get("/", function(req, res){
res.send('Hello');
});
it works.
But if i do:
app.get("/", function(req, res){
res.render("welcome");
});
it doesn't.
my app.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const indexRoutes = require("./routes/index");
const userRoutes = require("./routes/user");
const ejsLayouts = require("express-ejs-layouts");
const path = require("path");
mongoose.connect("mongodb://localhost/userAuth", function(err, res) {
if (err) throw err;
console.log("Connected to database");
});
//EJS
app.set('view engine','ejs');
app.use(ejsLayouts);
app.use(express.static(__dirname + '/public'));
app.set('views',path.join(__dirname+'/views'))
//ROUTES
app.use("/", indexRoutes);
app.use("/user", userRoutes);
app.listen(3000, function() {
console.log("server started");
});
my index.js file (userLogin/routes/index.js)
const express=require("express");
path = require('path');
router= express.Router();
router.get("/",function(req,res){
res.render("welcome");
});
module.exports = router;
my folder structure
userLogin
/..
/routes
/index.js
/views
/welcome.ejs
I have an h1 element olny in welcome.ejs file.
Looking at the code you provided, in index.js you are trying to render a view called check, when the only view you have is called welcome. Your paths and routes look to be correct, rendering the correct view should work.
app.engine('html', require('ejs').renderFile);
if u woudlike to render .html files
then
fs.readFile(path.resolve(__dirname + '/../public/views/logs.html'), 'utf-8', (err, content) => {
let renderedHtml = ejs.render(content, {'user': req.session.db}); //get redered HTML code
res.end(renderedHtml);
})
you should have views/layouts/layout.ejs file if you are using express-ejs-layouts npm
inside app.js :
const ejs =require('ejs');
const ejsLayouts = require("express-ejs-layouts");
app.set('view engine','ejs');
app.use(ejsLayouts);
app.set('layout', 'layouts/layout');
layout.ejs file has common layout that follow all files
if you are using bootstrap then your layout.ejs file would be like :
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<title></title>
</head>
<body>
<?- body ?>
</body>
</html>
so now other ejs pages will only have content to display
like welcome.ejs file is
<h1>Welcome Page</h1>

how to pass variable from nodejs to html directly without using pug?

I need to pass a variable from a NodeJS file to a rendered html file. How to do that?
Here below what I had tried
Nodejs code
const loginRouter= express.Router();
const config= require('../config/config.json');
loginRouter.get('/', (req,res)=>{
res.render(path.dirname(__dirname)+'/views/login.html',{version:config.version});
//res.json('done')
});
HTML Code
<label style="font-size:10px;float: right;"><%= version %></label>
Current Result:-
Nothing is coming
Expected Result:-
<label style="font-size:10px;float: right;">3.9</label>
I have set this version number in my config which I have imported in my login.js, but still, I am not getting the output. Does anyone have any idea about it?
If you don't want to use a templating engine like ejs or pug then you can just send a get request with axios or fetch to your node server and send a response.
Here's a sample on how you can do it. Change it according to your needs.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1 id="title">My page</h1>
<script>
fetch('http://localhost:5000/version').then(function(response) {
return response.json();
}).then(function(myJson) {
document.getElementById('title').innerHTML = myJson;
});
</script>
</body>
</html>
server.js
const express = require('express');
const app = express();
const PORT = 5000;
app.get('/', (req, res) => {
res.sendFile('index.html', {root: __dirname });
});
app.get('/version', (req, res) => {
const myVersion = 'My version is 0.5';
res.json(myVersion);
});
app.listen(PORT, () => {
console.log(`Server running on PORT ${PORT}`);
});

Vue-resource can't load express static file

So, I have a bit of a problem. Here's my server.js
require('dotenv').load();
const http = require('http');
const path = require('path');
const express = require('express');
const app = express();
const server = http.createServer(app).listen(8080, () => {
console.log('Foliage started on port 8080');
});
app.use(express.static(path.join(__dirname, '/public')));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
});
What this does, is that for every /whatever it gives the index.html file. Alongside that, it serves static files from /public Now, my index.html looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Foliage</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/foliage.css" media="screen" title="no title">
<script src="https://use.fontawesome.com/763cbc8ede.js"></script>
</head>
<body>
<div id="app">
<router-view :key="$router.currentRoute.path"></router-view>
</div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script src="js/md5.js"></script>
<script src="js/cookies.js"></script>
<script src="js/dragula.js"></script>
<script src="js/build.js"></script>
</body>
</html>
All of the JS files and the style files are loaded appropriately from public/jsand public/css for this. However, in build.js, which is a webpack-ed vuejs app, I use vue-resource, to load in another file from public/themes/Bareren/templates. That looks like this
page = {};
page.Template = "Index";
this.$http.get('themes/Barren/templates/'+page.Template+'.html').then((response) => {
console.log(response.body);
});
However, this request does not give me the file in public/themes/Barren/templates. It instead gives back the site's own index.html file. How could i fix this?
app.use(express.static(path.join(__dirname, '/public')));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html')); });
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html')); });
Try to console.log(path.join(__dirname, '/public')) and console.log(path.join(__dirname, 'index.html') to see if the path matches what you are expecting.
this.$http.get('themes/Barren/templates/'+page.Template+'.html').then((response)
=> {
console.log(response.body); });
You can also try console logging your get request. Usually I need to play with the pathing to making sure I'm serving the correct files.
One thing you can try is to define a GET route which responds with your template before the wildcard at the bottom.
app.get('/themes', (req, res) => {
// get the theme name
res.sendFile(path.join(__dirname, ... ));
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
});

Categories

Resources