I'm working in a new web portal. So far using the express and node.js i have a server and some ejs files.
The body structure of my site is like this:
- node modules
- public
--javascript
---myScript.js
-views
--pages
---index.ejs
---about.ejs
--partials
---footer.ejs
---head.ejs
---header.ejs
package.json
server.js
server.js
var express = require('express');
var app = express();
app.set('view engine', 'ejs'); // set the view engine to ejs
app.get('/', function(req, res) {res.render('pages/index');}); // index page
app.get('/about', function(req, res) { res.render('pages/about');}); // about page
app.listen(8080);
console.log('Portal is listening to port 8080 ');
and the index.ejs
<html lang="en">
<head>
<% include ../partials/head %>
</head>
<body class="container">
<header>
<% include ../partials/header %>
</header>
<main>
<div class="jumbotron">
<h1>MyPortal</h1>
<button>Press</button>
<% var test = 101; %>
</div>
</main>
<footer>
<% include ../partials/footer %>
</footer>
</body>
</html>
In the partials i want to call and use an external .js file /public/javascript/myScript.js so i can use variable from it in my ejs page or send a variable.
my js file have a simple function (just to see if it's working) that print in console if the button (in index.ejs) is pressed.
myScript.js
$(function() {
$("button").on("click", function () {
console.log("button pressed");
});
});
I'm trying to call the external js in head.ejs (or in index.ejs)...
<!-- views/partials/head.ejs -->
<meta charset="UTF-8">
<title>MyPortal</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<style>body { padding-top:50px; } </style>
<script type="text/javascript" src="/pubic/javascript/myScript.js"></script>
but i'm getting this error (in console)
Loading failed for the <script> with source “http://localhost:8080/pubic/javascript/myScript.js”.
Any idea why this happens and how to solve it?
Since you are trying to load client-side JavaScript, the fact you are using EJS is irrelevent. A standard HTML script element is all you need in the template, and you have that.
You do, however, need to provide a URL (with the src attribute) that the web browser can use to fetch the script … and your script has no URL.
You are getting the message Loading failed for the with source “http://localhost:8080/pubic/javascript/myScript.js”. because it is a 404 Error.
You should use the static module to provide the JS file with a URL.
app.use("/public", express.static('public'))
Add this to your server.js file,
app.use(express.static(__dirname + "/public");
And to link the js file with your ejs file,
Related
I am developing a web server with node.js. But I got a problem just now.
Below code is my HTML code.
<%
var tagID = 'something';
%>
...
I know that if I use 'javascript:' inside a HTML tag. then it can execute javascript code. but it did not work when I checked it on my browser.
Or should I use DOM to do this?
You can use javascript: in a href. Like so
Hi
There are 3 ways to do what you are asking:
Using a single page application like angular, reacts ...
Use your own custom design pattern that will replace whatever you want to replace
var global = this;
global.id1 = 10;
global.id2 = 30;
document.querySelectorAll("*").forEach(function(dom) {
[...dom.attributes].forEach(function(attr) {
if (attr.value.startsWith("javascript:")) {
dom.setAttribute(attr.name, global[attr.value.replace("javascript:", "")]);
}
});
});
<div id="javascript:id1">Div 1</div>
<div id="javascript:id2">Div 2</div>
Do the update manually
document.getElementById("1").id = "10";
document.getElementById("2").id = "20";
<div id="1">Div 1</div>
<div id="2">Div 2</div>
If you are creating a big app then I would reccomand using a single page application (though it might take some time getting to know how it works if you are familiar with it).
If you are feeling adventurous or don't want to bother learning or using an SPA you could create your own framework/design pattern.
If the example you have shown is not a common occurence (and you don't expect it to be more common in the future), easiest solution would be to just manually update the dom.
You can use https://www.npmjs.com/package/ejs
// server.js
// load the things we need
var express = require('express');
var app = express();
// set the view engine to ejs
app.set('view engine', 'ejs');
// use res.render to load up an ejs view file
// index page
app.get('/', function(req, res) {
res.render('pages/index');
});
// about page
app.get('/about', function(req, res) {
res.render('pages/about');
});
app.listen(8080);
console.log('8080 is the magic port');
you can embed javascript like this
<ul>
<% drinks.forEach(function(drink) { %>
<li><%= drink.name %> - <%= drink.drunkness %></li>
<% }); %>
</ul>
<!DOCTYPE html>
<html lang="en">
<head>
<% include ../partials/head %>
</head>
<body class="container">
<header>
<% include ../partials/header %>
</header>
<main>
<div class="jumbotron">
<h1>This is great</h1>
<p>Welcome to templating using EJS</p>
</div>
</main>
<footer>
<% include ../partials/footer %>
</footer>
</body>
</html>
I want to navigate to next page using link but i'm facing 404 error
I'd changed my template from jade to ejs
<html>
<body>
<div>
<ul style="color:white; float: right;" class="nav navbar-nav">
<li>Login </li>
<li>Sign Up </li>
</ul>
</div>
</body>
</html>
#Asad, in order for you to go to /login, you must have this route declared in your server side. Something like:
app.get('/login', (req, res) => {
res.render('login');
});
Otherwise, you will always have 404.
Using the following dependencies NPM:
"dependencies": {
"body-parser": "^1.19.0",
"ejs": "^3.0.1",
"express": "^4.17.1",
"mongoose": "^4.13.20"
In app.js file:
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
In Ejs File:
<a class="btn btn-dark btn-sm" href="/someFile" >Link to some EJS File</a>
your file structure:
project
node modules
public
views
index.ejs
someFile.ejs
By setting the view engine to ejs in the app.js file and setting the static file folder in the same app.js you may be able to call out to other ejs files in the same directory utilizing "/" for href. Hope this helps. This is my first answer on Stackoverflow so take it easy on me.
"Image for Navigating Different Web Pages"
As illustrated in the image above, the best way to navigate different web pages using ejs template is to ensure you create a folder called "partials" in your project's "views folder directory" where you have your other ejs files.
1) Then in that "partials folder" create 2 separate ejs files called header.ejs & footer.ejs.
2) Then go to your home.ejs or index.ejs file depending on how you have named your starting ejs file, and then cut ("All contents including the css and probably the bootstrap links in the boiler plate down to the opening body tag <body> and paste in the header.ejs file in the partials folder").
3) Also cut ("All contents from the closing body tag </body> of the "home or index.ejs " file to the footer.ejs file in the partials folder"). Then instead of repeating the header and footer sections for the subsequent pages i.e about.ejs or contact.ejs just link them to the header.ejs and footer.ejs files in the partialss folder as below:
//Sample page of the about.ejs file
Visual Illustration:
<%- include("partials/header"); -%>
<h1> About Page </h1>
<p> This is an about page </p>
<%- include("partials/footer"); -%>
//Do same for other pages.
Finally, following the image above, link the navigation to the different pages at the anchor tags in the header.ejs file which is located in the partials folder using:
"/" ----- To Home Page.
"/about" ------ To About Page.
"/contact" ------ To Cntact Page.
I hope this helps. Please let me know your views.
Something similar to this should be on your login.ejs page. Also, pay attention to spellings and all.
...
In server file
app.get('/login', (req, res) => {
res.render('login');
});
I faced the same issue and that's how I got it fixed.
And the login file should actually be created.
App js.
const express = require("express");
const ejs = require("ejs");
const startingContent = "Home Page";
const aboutContent ="About Us Page";
const app = express();
app.set('view engine', 'ejs');
app.use(express.urlencoded({extended: true}));
No Need for body parser, express handles that already, by using : app.use(express.urlencoded({extended: true})); .
app.use(express.json());
app.use(express.static("public"));
app.get("/", (req, res)=>{
res.render("home", {homeStart: startingContent});
});
app.get("/about", (req, res)=>{
res.render("about", {aboutStartingText: aboutContent});
});
app.listen(3000, ()=> {
console.log("Server started on port 3000");
});
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>My Site</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/styles.css">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<p class="navbar-brand">My Site</p>
</div>
<ul class="nav navbar-nav navbar-right">
<!-- 6 -->
<li id="home">HOME</li>
<li id="about">ABOUT US</li>
</ul>
</div>
</nav>
<body>
<div class="container">
Header.ejs
Best practice is to have your header and footer in a folder partials
Example :
views
partials
header.ejs
footer.ejs
home.ejs
about.ejs
Then you render in your ejs file.
<%- include("partials/header") -%>
<h1>Home</h1>
<p><%= homeStart %></p>
<%- include("partials/footer") -%>
For example:
Routes in *.js:
app.get("/", function (req, res) {
res.render("home", { contentHome: homeStartingContent});
});
app.get("/about", function (req, res) {
res.render("about", { contentAboutpage: aboutContent });
});
app.get("/contact", function (req, res) {
res.render("contact", { contentContactpage: contactContent });
});
Links in HTML:
<li id="home">HOME</li>
<li id="about">ABOUT US</li>
<li id="contact">CONTACT US</li>
I have a problem loading external files into my index.html. My stylesheet as well as my JS files do not show up at all (Error 404 - Not Found). My directory structure is as follows.
My index.html is:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Orders and Customers</title>
<link rel="stylesheet" type="text/css" href="./assets/css/stylesheet.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular-route.min.js"></script>
<script src="./../app/app.js" type="text/javascript"></script>
<script src="./../app/controllers/customer/CustomerController.js"></script>
<script src="./../app/controllers/order/OrderController.js"></script>
<script src="./../app/services/customer/CustomerService.js"></script>
<script src="./../app/services/order/OrderService.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
This is what Chrome shows:
My server.js is:
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
require('./server/config/mongoose.js');
require('./server/config/routes.js')(app);
app.use(express.static(path.join(__dirname, './views')));
app.listen(8000, function() {
console.log('Listening on Port 8000');
})
Any help is greatly appreciated!
Try this
in server.js
var router = express.Router();
router.use(express.static(path.resolve(__dirname, "../app")));
in index.html
<script src="/app.js" type="text/javascript"></script>
<script src="/controllers/customer/CustomerController.js"></script>
<script src="/controllers/order/OrderController.js"></script>
<script src="/services/customer/CustomerService.js"></script>
<script src="/services/order/OrderService.js"></script>
Router is middle-ware for capture * path.
For example, /service/* matches all requests under service path.
so I changed your code as to handle all resources under "/app" folder. (eg: /app/app.js, etc)
path.resolve changes path from relative to absolute.
it means that you can add another current working directory.
path.resolve(__dirname, "../app") add "/app" from current working directory (views). it parsed from "views/../app" to "/app"
(Reference) Path.resolve
The relative paths
<script src="./../app/app.js" type="text/javascript"></script>
etc, are pointing to the wrong directory.
Use the Network tab in your browser developer tools, to check what exact requests are going out.
If the whole app directory is public (Which, in my opinion, should not be the case), "./../" will refer to the views directory.
Single . refers to the current directory, which in this case is, the one containing your index.html. Double .. refers to the directory above it, which here is views.
Rather than
<script src="./../app/app.js" type="text/javascript"></script>
Try using the full path:
<script src="/app/app.js" type="text/javascript"></script>
<script src="/app/controllers/order/OrderController.js"></script>
Try this
app.use(express.static(path.join(__dirname, 'views')));
and just use
<link rel="stylesheet" type="text/css" href="assets/css/stylesheet.css">
Thanks to SeongHyeon, I was able to figure out the solution to my problem. I really appreciate your guys' help. I'd like to elaborate more on this just for my own reference.
When declaring your static path in express, you don't need to reference anything relative to the file that you're trying to import from. Instead, you simply reference the file from the static path that you've declared.
When I render my .ejs file the href and the src attributes are not referencing my local files. I am using node.js and express.
Here is the relevant part of the .ejs template.
<head>
<title></title>
<link rel='stylesheet' href='../public/stylesheets/styles.css' />
<script src="../us-map-1.0.1/lib/raphael.js"></script>
<!-- <script src="scale.raphael.js"></script> -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"></script>
<script src="../us-map-1.0.1/color.jquery.js"></script>
<script src="../us-map-1.0.1/jquery.usmap.js"></script>
<script>
</head>
This is router that renders the template
router.get('/submit', function(req, res, next) {...});
And this is what a typical query looks like
http://localhost:3000/submit?leftHashtag=dog&rightHashtag=cat
Any help on why this is happening would be greatly appreciated.
The problem was that I wasn't defining my static content serving.
To fix this I added an app.use statement to my app.js file
app.use('/submit', express.static(__dirname + '/public'));
So now any routes that begin with /submit will use this directory local to the app
__dirname/public
With __dirname being the current directory the app.js file is located in
If you would like to know more this blog goes into more detail about what is happening
http://blog.modulus.io/nodejs-and-express-static-content
Lets say I have a simple view
<html>
<head>
<title>something</title>
</head>
<body>
<%= param %>
</body>
<script type="text/javascript" src="myscript.js"></script>
</html>
And here's myscript.js
$(function() {
var p = <%= param %>
}
Can I make express rendering engine (in this case ejs) render inside myscript.js ?
I don't believe express will touch your static files. You could make this a view that gets rendered and served from a route, as in:
app.get('/js/myscript.js', function(req, res) {
res.render('myscript');
});
With regex routes, you could do this with anything ending in .js. (Before anyone downvotes, note that I said could, not should.)
You probably would be better off with static javascript being served to the browser that uses JSON data served from Express, though.