displaying images in a .handlebars/html - html

I'm trying to link images to my .handlebars/html files in my views directory. I've created a public folder as I discovered was necessary, but still can't get the linked images to appear when I open my web page.
Here is my node.js code...
var express = require('express');
var session = require('express-session');
var request = require('request');
var app = express();
var handlebars = require('express-handlebars').create({defaultLayout: 'main'});
var bodyParser = require('body-parser');
app.use(session({secret:'secretSauce'}));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('port', 3021);
app.get('/', function (req, res, next) {
res.render('index');
});
app.get('/setup', function (req, res, next) {
res.render('setup')
});
app.use(function(req,res){
res.status(404);
res.render('404');
});
app.use(function(err, req, res, next){
console.error(err.stack);
res.type('plain/text');
res.status(500);
res.render('500');
});
app.listen(app.get('port'), function(){
console.log('Express started on http://localhost:' + app.get('port') + '; press Ctrl-C to terminate.');
});
And this is a page I've tried to load images on:
<h1>
Getting a Mailjet Account, an API, and Misc. Set Up
</h1><br>
<p>
This first part is going to their website and signing up to get an account. The sign up page looks like this. You can click on the image to take you there.
</p>
<img src="/public/images/mailjet signup.jpg" alt="sign up page">
<br>
<p>
Once you take care of business there, you can head to your account page and click on the link circled in the image below. That link will take you to where your private and public API keys are stored.
</p>
<img src="/public/images/mailjet APIKey.jpg" alt="account page">
<br>
<p>
Awesome, so the last major thing to think about is if you want to add a domain name to your account. Typically your emails that you use at sign up will be autamically set up as a sender, and it will make it look like emails are coming from that account. However, you may have multiple senders on a company domain. In that case you'll want to head over to the accuont settings and add that domain. This way in the future if employees send something it will automatically allow senders from the domain. This is really more of a logistical matter than anything, and it doesn't directly affect using this How to Guide.
</p>
<ul>
<li>Prev </li>
<li>Next</li>
</ul>

To get the images on the handlebars page or HTML we need to set the path on the index.js file or app.js file, it depends on you what is your starting page.
Index.js
app.use(express.static('views/images'));
promotionapplication\views\images - This is my folder structure, my index.js file is in promotionapplication, and i have kept my pics in the images folder. You can keep any of the structure of the folder but you should mention it in accordingly in app.use.
So now i can use any of the pics in the folder, by using the following code in handlebars page-
first.handlebars
<img src="bckground.jpg" alt="piooop" />
Remember to reload the page after the changes made.
It works perfectly fine. If any questions please comment, i will try to give an answer.

Use attachments in nodemailer options. LInk image src in your .hbs file to the unique cid in your attachment description like so:
src="cid:unique#unique"
const mailOptions = {
from: 'xxxxx',
to: x,
subject: `xxxx`,
template : 'xxx',
attachments: [
{
filename: 'xx.png',
path: __dirname +'/images/xx.png',
cid: 'unique#unique'
},]

Related

Trying to load my html file using nodejs to create login page

I am trying to use node.js to run a html file. I already have a login.html and styles.css for for the login page but now I don't know how to use the node js file to run my login.html page. I follow this youtube tutorial to make the a login authentication. It seems to have everything needed but now I dont know how to use it in my login.html file.
I need help modifying this so that I can run my login.html file.
index.js file
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const postRoute = require('./routes/posts');
//Import Routes
const authRoute = require('./routes/auth');
dotenv.config();
//Connect to DB
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true, useUnifiedTopology: true },
() => console.log('Connected to DB')
);
//Middleware
app.use(express.json());
//Routes Middlewares
app.use('/api/user', authRoute);
app.use('/api/posts', postRoute);
// start listening
app.listen(3000, () => console.log('Server up and running port:3000'));
I am new to node.js and am completely lost on how to solve this problem.
you can solve it in two ways, first you can install view engine like ejs and use res.render (if you want more about it i can explain)
Second you can response with the HTML file like this: (works only with express and you have express)
app.get('/yourRotue', function(req, res, next){
res.sendFile(__dirname + '/yourPath/htmlFile.html');
});
How to use EJS (basic):
First please install EJS with npm install ejs install body parser npm install body-parser
now you need to create two folders on the root folder, public and views.
inside views you can create a folder auth and put your EJS files there.
then on your app.js (or index.js, the main file) add view engine middleware:
(*notice that you dont need to require ejs, also notice you dont need to install path its built in with node)
//import body parser on top (to parse json/urlencoded/text..
const bodyParser = require('body-parser');
//import path so you can use it for the public folder
const path = require('path');
//this line makes public folder public so you can store js/css/image...
app.use(express.static(path.join(__dirname, 'public')));
//use the body parser as middleware
app.use(bodyParser.json({ limit: '200mb' }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.text({ limit: '200mb' }));
//this line tells node js to use ejs
app.set('view engine', 'ejs');
//this line make sure that the views folder is the folder with the ejs files
app.set('views', 'views');
//now your route will look like this:
app.get(/routeName, (req,res,next) => {
let example
//you return response with render, to render the file you want.
// you dont write the views folder name, only the file name without .ejs
// elso you can run functions here and later send the response to the front end
function(){
example = 1 + 1 * 5
}
// *very often the function above is to find something in the db
return res.render('auth/ejsFileName', {
pageTitle: 'some page title for the example',
exampleKey: example
})
})
I can suggest you to use mvc (models, views, controllers) structor, if you want to know more about it you can open new question or to search about it.
EJS:
put your css and js in public folder, you can create js folder and css folder inside the public folder and then put the css in js in their folder.
*notice you dont need to write ./public in the route.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/someCssFile.css">
<!-- here is the title that comes from the back end -->
<title><%= pageTitle %></title>
</head>
<main>
<h1>Here you can see the example with the function<%= exampleKey %></h1>
</main>
<script src="/js/someJsFile.js"></script>
</body>
</html>
the file look like html but it has .ejs
there is many things you can do with ejs like to loop through values.. i would suggest to learn a bit more.
this is the basic it should work.
For the post request i need to know if you are posting a form as urlEncoded or json. so i can show you how it should look like.
You can try to use some template engines like Handlebars. https://youtu.be/1srD3Mdvf50 You can try to follow this tutorial in order to load some html from the server side. Then you can use different selectors in order to interact with DOM elementa

nodejs sendfile html page

I have this code that allows me to open a HTML page from specific folder, if I use server.js to open that HTMLpage so the page it is generating with all the css and jquery files but if I try to move the get statement to the routes folder then the page is generated but without any css and jquery files and I don't know why !
what I did in the server.js for the generation of the HTML page is below which is working perfectly :
const folderPath = __dirname + '/public/AppTemplate/src'
app.use(express.static(folderPath))
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/public/AppTemplate/src/index.html'));
});
but what I'm trying now is to get the html page from routes.js :
step 1 :
I implemented this statement in server.js
app.use('/users', require('./backend/routes/profile.routes.js'));
step2 :I tried this statement in routes.js with simple modification :D :
router.get('/profile', function (req, res) {
const dirname = __dirname;
console.log(dirname)
const newpath = dirname.length - 14;
const newP = dirname.substring(newpath, dirname.lastIndexOf("/"));
console.log(newP);
res.sendFile(path.join(newP+ '/public/AppTemplate/src/02-ProfilePage.html'));
});
the step 2 is working but I couldn't get all the associated files (jquery css ...) which are located in
/public/AppTemplate/src
the image of the output is below :
hope I mentioned everything,
Best Regards,
It's because of the content in the 02-ProfilePage.html has an incorrect path.
Check the path in the script tags. If there is a slash it means that it's already in the /public/AppTemplate/src which you specified.
For example, /js/file.js will actually point to /public/AppTemplate/src/js/file.js
Perhaps try adding a / in front of your path in the script tag.
Example:
/css/x/y/z/ instead of css/x/y/z
You will have to append a / to all the routes in your script/link tag to be able to successfully load the local resources.
You can use the find and replace functionality in your code editor or IDE to speed up the process if possible.

Call ExpressJS as Rest API for HTML page

I am creating web page with a button to load data from the server using Rest API build through ExpressJS, NodeJs.
var express=require('express');
var mysql=require('mysql');
var app=express();
var server=app.listen(3000,function(){
console.log("Express is running on port 3000");
});
app.get('/search',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.end(JSON.stringify(data));
});
});
HTML page for this application looks like below
<button >Load from server</button>
<div></div>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','button', function(){
$.ajax({
url: "http://localhost:3000/search"
}).done(function() {
$('div').append("done !!! - ");
});
});
});
</script>
When I run http://localhost:3000/search in browser it gives me output with "name" from the database. But how can I see the index.html page and make it load on button click.
Update:
OP Asks:
"my question is not what code say....my question is how to change the
code so that expressjs works as RESTful API and not rendering engine"
In order to use express as a RESTful API here, you first need to serve up a static page.
Said another way, here are the steps:
1. Get your express server to serve up a static page.
2. Then get the button on that page to make a GET request to your api endpoint at /search (when clicked).
1 is explained in the 2nd part of my answer.
2 should already work, you just need to serve the page and click the button!
I explain why this doesn't work in the first part of my answer. You can't simply navigate to /search. I think that is what you mean by "not use it as a render engine".
Original Answer:
To understand what is happening here, it might be a good idea to look at how you're handling requests in your serverside code:
When I run http://localhost:3000/search in browser it gives me output with "name" from the database.
That code is:
app.get('/search',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.end(JSON.stringify(data));
});
});
This means that whenever a GET request goes to your route (in this case, the path /search on localhost:3000), the callback function executes. Essentially, when you access localhost:3000/search, your browser sends a GET request, Express checks* the request for a match with each route, and finally going "ok, that's the GET request I need to respond to, let's start searching!".
So it's behaving as expected. Of course, that is not what you want...
But how can I see the index.html page and make it load on button click
Try something like this:
app.get('/', function(req,res) {
res.sendfile('public/index.html');
});
It might not work as is, depending on where your html is defined and what you've named it. Remember to send the right file.
A simpler way to reason about this would be to let express know you're serving up static html.**
That could be done with
app.use("/", express.static(__dirname)); But again, make sure the html defined above is in a file in the proper root folder (probably named server or something similar), with the name index.html (and that there is only one of them).
(See the links on how express middleware works, and serving static HTML, at the bottom)
To wrap up, you implement the second half this answer first, so that you can go directly to localhost:3000 to load your index page. That page will have a button. Then, you'll be able to click the button and make a request to your /search route, without redirecting. The contents of name should come back to the browser now (instead of being served as a new page).
*More on how requests get checked/processed here.
**More info on serving static html. This blog on express fundamentals may also be useful.
1-You have to add routing for index.html
app.get("/index", function(req, res) {
res.render(index.html);
});
And then in your ajax code you can redirect to /index using window.location
2- you can directly render index.html.
Something like this
app.get("/search", function(req, res) {
res.render(search.html,{});
});
app.get('/index',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.render(index.html,{data:data});
});
});
then redirect to page on /index when clicking button.
The problem you have is that you are using Express as a render FrameWork. If you want to build an app with REST/API, the framework should not render the views or templates. The webpage navigation should be separate (e.g Angular JS). In your case, when you call /search you are actually only calling something in the server without any rendering instruction. That is why you see a response JSON object instead of your html template.
So, what to do?.. You need to make a navigation app on your client side, just navigating through templates with nothing out of normal, and program your button to do its request to some api url (something like: localhost:3000/api/search) and with the contents of the response do something: like filling a table, showing them somehow or whatever..
I recommend you to give a try to Angular JS. I am sure it can help you
Cheers
Here is the code I use when I am wanting to use a simple index.html page for test some front-end code.
app.get("/", function(req, res) {
res.sendFile( __dirname + '/index.html')
});
This will map the root path to your index.html. The __dirname assumes the index.html file is in the same directory as your initial server/app file for express. If you want to make it more generic you can do something like the following but then you will need to manually add the index.html to the address bar in your browser but it also lets you load any other static files you want.
app.get(/^(.+)$/, function(req, res){
res.sendFile( __dirname + req.params[0]);
});
<button >Load from server</button>
<div></div>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','button', function(){
$.ajax({
url: "http://localhost:3000/search"
}).done(function(data) {
$('div').append(data);
});
});
});
</script>
you can read the documentation about $.ajax() from jquery api documentation
http://api.jquery.com/jQuery.ajax/

node.js code to open a page in browser with localhost URL

I have written a simple server using node.js. At the moment the server responds by writing "hello world" to the browser.
The server.js file looks like this:
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8080);
I use this URL in the browser to trigger the "hello world" response:
http://localhost:8080/
I want to be able to open a basic html page when I pass a URL like this:
http://localhost:8080/test.html
I have looked through many tutorials and some stackoverflow posts but there was not much out there on this specific task. Does anyone know how to achieve this with a simple modification to the server.js file?
If you wish to open .html file through nodejs with the help of "http://localhost:8080/test.html" such url, you need to convert .html page to .jade format.Use rendering engine with the help of expressjs framework.Express rendering engine will help you to render .jade file on nodejs server.
It is better to use a front end javascript frameworks such as Angular, React or Vue to route to different pages. Though, if you want to do it in Node, you could do something like this using express:
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.sendFile('views/index.html', { root: __dirname })
});
app.get('/test', function(req, res) {
res.sendFile('views/test.html', { root: __dirname })
});
app.listen(8080);
This is an ok solution for static pages. Express is very useful for writing REST API's.

Express routing returns undefined randomly

I am trying to learn Express with NodeJS and would like to render my views with plain HTML. I hacked together a webserver based on the Express API documentation and several Stack questions, particularly the answer by Andrew Homeyer in this question which states
You can have jade include a plain HTML page:
in views/index.jade
include plain.html in views/plain.html
... and app.js can still just render jade:
res.render(index)
My directory structure looks like this
Project
*web.js
Public
img
js
lib
gallerific
*jquery.opacityrollover.js
*jquery.gallerific.js
angular
theme
views
partials
*index.html
*index.jade
and my server looks like this.
var express = require('express'),
jade = require('jade');
var app = module.exports = express();
app.configure(function(){
app.set('views', __dirname + '/public/views');
app.use("/public/lib", express.static(__dirname + "/public/lib"));
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.set('view engine', 'jade')
app.use(express.bodyParser());
});
app.get('/', function(req, res) {
res.render('index');
});
app.get('/partials/:name', function(req, res){
var name = req.params.name;
res.render('/public/partials/' + name);
});
app.get('/public/data/:name', function(req, res){
var name = req.params.name;
res.json('/public/data/' + name)
});
app.listen(3000, function(){
console.log("Express app listening on port %d in %s mode", this.address().port, app.settings.env);
});
What I am seeing is that certain files fail to load from directories in which everything else loads just fine. For example, my Gallery page fails to load the jquery.gallerific.js javascript file from my lib/gallerific directory while it does load the jquery.opacityrollover.js. I have poked around with Chrome Developer Tools and see the following
I had this site working with the Angular Bootstrap webserver so it doesn't seem to be a javascript error with the client side code. Does anyone know what I might doing that would cause this problem?
The source is available at https://github.com/jamesamuir/express-simple-html.git
I figured it out. It turns out I had to resolve paths that I had forgotten about so that Express could render them correctly. It wasn't that the Gallerific javascript library didn't load, it was throwing an error on the image source of undefined for my gallery images (I am pulling them from a JSON file).
Once I put the appropriate paths in for the images and the data file, everything started working again. Thanks to everyone who provided a suggestion for me. It really helped me to work through the problem.