I'm working on NodeJs application.
I created route for admin page also made a layout for it.
app.js
app.engine('.hbs', expressHsb({defaultLayout: 'default', extname: '.hbs'}));
app.set('view engine', '.hbs');
/* configure express */
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use(express.static(path.join(__dirname, '/public')));
/* routes */
const adminRoutes = require('./routes/adminRoutes');
app.use('/admin', adminRoutes);
app.use('/posts', adminRoutes);
My app folder structure looks like this:
Also the admin page has a part for creating posts which is in admin/posts/create route.
adminControllers.js
module.exports = {
index: (req, res) => {
res.render('admin/index');
},
createPosts: (req, res) => {
res.render('admin/posts/create');
}
};
adminRoutes.js
router.route('/')
.get(adminController.index);
router.route('/posts')
.get(adminController.getPosts)
.post(adminController.submitPosts);
router.route('/posts/create')
.get(adminController.createPosts);
When I start my app and I go to admin page everything works fine but when I enter create post part that has form my stylesheets and js files can't be reached.
On page there is html structure but no functionalities or style and when I view source code in browser and for example click on link like
<link href="css/sb-admin-2.min.css" rel="stylesheet">
I get following error:
Cannot GET /admin/posts/css/sb-admin-2.min.css
Like it's searching css folder in post folder and not in public.
Admin layout looks like this:
{{> admin/admin-header }}
<body id="page-top">
<!-- Page Wrapper -->
<div id="wrapper">
<!-- Sidebar -->
{{> admin/admin-sidebar}}
<!-- End of Sidebar -->
<!-- Content Wrapper -->
<div id="content-wrapper" class="d-flex flex-column">
<!-- Main Content -->
<div id="content">
<!-- Topbar -->
{{> admin/admin-topNav }}
<!-- End of Topbar -->
<!-- Begin Page Content -->
<div class="container-fluid">
{{{body}}}
</div>
<!-- /.container-fluid -->
</div>
<!-- End of Main Content -->
<!-- Footer -->
{{> admin/admin-footer}}
<!-- End of Footer -->
</div>
<!-- End of Content Wrapper -->
</div>
<!-- End of Page Wrapper -->
Everything works fine for admin page but if I go to link on admin page
<a class="collapse-item" href="/admin/posts/create">Create new Post</a>
It's just not loading as already mentioned stylesheets or js files, like that part of code doesn't belong as body to admin layout.
I am not sure why is this happening any advice highly appreciated.
css/sb-admin-2.min.css is a relative link. Change it to /css/sb-admin-2.min.css.
Technically it is still a relative link, since it doesn't include protocol or host, but the important part in this case is that the path is absolute
Related
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,
This is my first project with Angular. I'm still in the process of figuring out how to do things with Angular, so I'd like to apologize if my questions sound stupid.
My Questions
Why are my views not showing up when i navigate to index?
How can I fix this?
Overview
So, my index file shows the views I have used in the ui.router library. form.html contains my template header and footer. Within that file, I then have another...
<div id="form-views" ui-view></div>
... that should inject all my nested views.
However, when I go to index, I'm just getting a blank page and no errors!
Source code
app.js
angular.module('MyFirstAngularApp', ['ngAnimate', 'ui.router']);
config.js
angular.module('MyFirstAngularApp', ['ngAnimate', 'ui.router'])
// configuring our routes
// =============================================================================
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show our basic form (/form)
.state('form', {
url: '/form',
templateUrl: 'views/form.html',
controller: 'formController'
})
// nested states
// each of these sections will have their own view
// url will be nested (/form/signup)
.state('form.signup', {
url: '/signup',
templateUrl: 'views/form-signup.html'
})
// url will be /form/select
.state('form.select', {
url: '/select',
templateUrl: 'views/form-select.html'
})
// url will be /form/type
.state('form.type', {
url: '/type',
templateUrl: 'views/form-type.html'
});
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/form/signup');
});
Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- CSS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootswatch/3.1.1/darkly/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/override.css">
<!-- JS -->
<!-- load angular, nganimate, and ui-router -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.min.js"></script>
<script src="js/app.js"></script>
<script src="js/config.js"></script>
<script src="js/controller.js"></script>
</head>
<!-- apply our angular app -->
<body ng-app="MyFirstAngularApp">
<div class="container">
<!-- views will be injected here -->
<div ui-view></div>
</div>
</body>
</html>
form.html
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-container">
<div class="page-header text-center">
<h1>Mock up Maker</h1>
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".signup"><span>1</span> Sign Up</a>
<a ui-sref-active="active" ui-sref=".select"><span>2</span> Select</a>
<a ui-sref-active="active" ui-sref=".type"><span>3</span> Type</a>
<a ui-sref-active="active" ui-sref=".end"><span>4</span> End</a>
</div>
</div>
<!-- use ng-submit to catch the form submission and use our Angular function -->
<form name="myForm" id="signup-form" class="col-sm-8 col-sm-offset-2" ng-submit="processForm()">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
<!-- show our formData as it is being typed -->
<pre class="col-sm-12 ng-binding">
{{ formData }}
</pre>
</div>
File structure
I don't see why its not working. Any help is very much appreciated!
The snippet
angular.module("moduleName", [])
defines a new module with the required dependencies in the array. If you want to further define components of this module, you need to define them using
angular.module("moduleName")
.controller(...)
.directive(...)
.config(...)
.run(...);
The latter is a getter syntax of angular module and doesn't define the module again.
Your current code defines the module MyFirstAngularApp two times. That should be the root of your problem.
You probably want:
angular.module('MyFirstAngularApp').config( ...
in your config.js
This avoids duplicating the module, instead it gets the instance already created in app.js and adds configuration on it. The same approach should be used in your controllers and other code.
I think you have a typo in your Views template folder. In the file structure directory you are having Views Folder whereas you are using lowercase views name in routing.
I am building a single page web application using Angular and UI-Router. In my index.html page, I currently have these three elements, a navbar directive, a ui-view and a footer directive as shown below:
<body>
<div class="container-fluid">
<div class="row">
<cep-navbar></cep-navbar>
</div>
<ui-view></ui-view>
<div class="row">
<cep-footer></cep-footer>
</div>
</div>
<!-- All the bower script dependencies-->
<!-- build:js js/lib.js -->
<!-- bower:js -->
<!-- endbower -->
<!-- endbuild -->
<!-- All the custom script dependencies-->
<!-- build:js js/app.js -->
<!-- inject:js -->
<!-- endinject -->
<!-- inject:template:js -->
<!-- endinject -->
<!-- endbuild -->
</body>
Module which contains the navbar directive defines the route as follows:
(function() {
'use strict';
angular.module('CEPAdmin.base.components')
.config(['$stateProvider', routeConfig]);
function routeConfig($stateProvider) {
$stateProvider.state('search', {
url: '/search',
templateUrl: 'src/app/pages/search/search.html',
controller: 'SearchController'
});
}
})();
I load in the search state by clicking on one of the links in navbar directive which injects of the search.html page in ui-view on the index.html page. But the problem is the script inside the script tag never executes. Here is my search.html page.
<script type="text/javascript">
console.log('Test me');
window.alert('Test me bro');
</script>
<h1>Hello World!!</h1>
Why is it that the script inside of scripts tag in search.html page not getting executed whenever my search state is loaded?
Link to plunk : https://plnkr.co/edit/RaX5Jsd5zqAfbwGE0i8o
Upon investigating it further, I got to know that stripped down version of jquery that angular uses (jQLite) has some DOM limitations which prevents it from executing a script file in partial view.
Solution
Reference a jQuery script before referencing Angular in your index.html. This makes angular to use jQuery instead of jQlite. Just doing this solved my problem.
Very new to MEAN Stack and I'm using Brackets to edit .ejs views for a simple form app using Express tutorial. I'm trying load a static image and it just won't load. I'm getting GET /public/ggcbear.jpg 404 from app.js (terminal). I also created a image.ejs views to handle the load...but thats not working. My .jpg is listed in the folder: public. What syntax is wrong in my code/.ejs files?
Part of my app.js
var http = require("http");
var path = require("path");
var express = require("express");
var logger = require("morgan");
var bodyParser = require("body-parser");
// Make an express app
var app = express();
app.set("views", path.resolve(__dirname, "views"));
app.set("view engine", "ejs");
//adding static functionality for images
app.use(express.static('public'));
// Renders the "image" page (at views/index.ejs) when GETing the URL
app.get("/image", function(request, response) {
response.render("image");
});
//etc...
my header.ejs
<!-- This header will appear at the top of every page -->
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Express Guestbook</title>
<!-- Loads Twitter's Bootstrap CSS from the Bootstrap CDN -->
<!-- http://getbootstrap.com/ -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body class ="container">
<!-- my image tag -->
<div>
<img src="/public/ggcbear.jpg">
</div>
<h1>
Express Guestbook
<a href="/new-entry" class="btn btn-primary pull-right">
Write in the guestbook
</a>
</h1>
</body>
</html>
my image.ejs
<% include header %>
<div>
<h3><img src="/ggcbear.jpg", alt="Testing Image")</h3>
</div>
<% include footer %>
Using the following static middleware:
app.use(express.static('public'));
and the following folder structure:
.
├── app.js
├── public
│ └── images
│ └── ggcbear.jpg
└── view
├── header.ejs
└── image.ejs
your ggcbear.jpg will serve from /images/ggcbear.jpg:
<img src="/images/ggcbear.jpg">
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>