I am attempting to do a very simple page with Handlebars and Express with NodeJS, however I am running into difficulty getting it to display css. It seems that the browser is receiving the CSS file given the feedback and the 200 code I'm getting in my Node window, but no effect is shown on the actual page.
file structure
app.js
/public
/stylesheets
style.css
/views
/layouts
main.handlebars
home.handlebars
app.js
var express = require('express');
var exphbs = require('express-handlebars');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/', express.static(path.join(__dirname, '/public')));
var person = {
name:"Clay",
age:"20",
attr:["tall","handsome","wearing a red sweater"]
}
app.get('/', function (req, res, next) {
res.render('home', {layout: false, people: person});
});
module.exports = app;
main.handlebars
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Database</title>
<link rel="stylesheet" href="stylesheets/style.css" />
</head>
<body>
{{{body}}}
</body>
</html>
home.handlebars
<h1>Example App: Home</h1>
hello world
style.css
body {
background-color: red;
}
node console
Related
I do frontend so I am sometimes lost when I am trying to do something on server.
I have this server.js file
const express = require('express');
const http = require('http');
const path = require('path');
const logger = require('morgan');
const renderPage = require('./layout');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const admin = require("firebase-admin");
var index = require('./routes/index');
// Initialize the Express App
const app = express();
// Apply body Parser and server public assets and routes
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.resolve(__dirname, 'public')));
app.use('/', index);
app.use((req, res, next) => {
res
.set('Content-Type', 'text/html')
.status(200)
.end(renderPage());
});
var server = http.createServer(app);
// start app
server.listen(3000);
module.exports = app;
..and this string template
const renderPage = (initialState) => {
return `
<!DOCTYPE html>
<html>
<head>
<link href="public/css/main.css"/>
<script src="some external javascript"/>
</head>
<body>
<div id="app"></div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initialState)};
</script>
</body>
</html>
`;
};
module.exports = renderPage;
When I start the server, it works, but css and script file do not work
Can you see what I am doing wrong?
Assuming your server.js file and your public directory exist at the same level, the path.resolve(__dirname, 'public') will build the full path to the public directory where all of your static resources should exist. When you reference these files inside your HTML pages you specify the path relative to the public directory.
<link href="css/main.css"/>
This should be enough to find the file. Assuming that file exists at ../public/css/main.css.
I run ExpressJS and installed Handlebars as a template engine. I'm using AdminLTE and split it up to 6 hbs files in /views/layouts. I put AdminLTE template in public folder.
views/layouts
-- base.hbs // as defaultLayout
-- footer.hbs
-- head.hbs
-- js.hbs
-- nav.hbs
-- sidebar.hbs
I get the following error on node console everytime when i try to access localhost:3000
Error: The partial head could not be found
Here is my app.js setup:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var flash = require('express-flash');
var session = require('express-session');
var mongoose = require('mongoose');
var validator = require('express-validator');
var override = require('method-override');
var hbs = require('express-handlebars');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.engine('hbs', hbs({extname: 'hbs', defaultLayout: 'base', layoutDir: __dirname + '/views/layouts'}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({secret: "1234"}));
app.use(flash());
app.use(validator());
app.use(override(function(req, res) {
if (req.body && typeof req.body == 'object' && '_method' in req.body) {
var method = req.body._method;
delete req.body._method;
return method;
}
}));
[...]
And this is my base.hbs file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
{{> head}}
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
{{> nav}}
{{> sidebar}}
<div class="content-wrapper">
{{{ body }}}
</div>
{{> footer}}
<div class="control-sidebar-bg"></div>
{{> js}}
</div>
</body>
</html>
You need to register the path to partials directory while configuring express-handlebars and move your partials to that folder.
app.engine('hbs', hbs({
extname: 'hbs',
defaultLayout: 'base',
layoutsDir: path.join(__dirname, 'views/layouts'),
partialsDir : [
// path to your partials
path.join(__dirname, 'views/partials'),
]
}));
[const hbs = require('hbs');
//this required before view engine setup
hbs.registerPartials(__dirname + '/views/partials');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
]1
use in app.js/index.js
hbs.registerPartials(__dirname + '/views/layouts');
use proper syntax in template hbs files Example: {{> header}}
I have fixed the issue by providing the id in HTML DOM. This part I missed in html.
<div class="modal-footer" id="btn-group"></div>
This is my js part
var templateBtnGroup = Handlebars.getTemplate("btn-group", "btn-group.html");
Handlebars.registerPartial("btn-group", templateBtnGroup());
var templateBtnGroupScript = Handlebars.compile($('#handlebars-btn-group').html());
$("#btn-group").append(templateBtnGroupScript());
Please check the folder names case. "Public" folder may present and you are referring to lowercase "public" will not render the css/images/client side js
You should create a subfolder for partials, and after that point to that folder with partialsDir:
app.engine('hbs', hbs({
extname: 'hbs',
defaultLayout: 'base',
layoutDir: __dirname + '/views/layouts',
partialsDir: path.join(__dirname, 'views/partials'),
}));
Make sure to use
extName to extname in viewEngine object for partials
var options = {
viewEngine: {
extname: '.hbs',
layoutsDir: 'views/layouts/',
defaultLayout : 'template.hbs',
partialsDir : 'views/partials/'
},
viewPath: 'views/emails/',
extName: '.hbs'
};
Directory
=> views/layouts/template.hbs
=> views/emails/forgot-password.hbs
=> views/partials/header.hbs
/footer.hbs
In template.hbs
<html>
<body>
<div class="container">
{{>header}}
{{{body}}}
{{>footer}}
</div>
</body>
</html>
i am new in mean stack i want to remove the hash in URL of the browser.i successfully do this but when i refresh the page at that time 'Network error 404 not found' comes so please help me to solve this problem.
below i show the code of index.html file.
<script>
var base = document.createElement('base');
base.href = 'http://localhost:3000/';
document.getElementsByTagName('head')[0].appendChild(base);
</script>
below is the code of the config.router.js
angular.module('app')
.config(
['$stateProvider', '$urlRouterProvider','$locationProvider', 'MODULE_CONFIG',
function ($stateProvider, $urlRouterProvider,$locationProvider, MODULE_CONFIG) {
$locationProvider.html5Mode(true).hashPrefix('!');
below is the code of the server.js file of the node.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var routes = require('./routes/index');
var country = require('./routes/country');
var category = require('./routes/Category');
var attributes = require('./routes/Attribute');
var subscription = require('./routes/subscription');
var mall = require('./routes/mall');
var http = require('http');
var user = require('./routes/user');
var app = express();
//var cors = require('cors');
// view engine setup
//app.use(cors());
app.set('views', path.join(__dirname, '../app'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true }));
app.use(bodyParser.json({limit: '50mb'}));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
app.use(cookieParser());
//app.use(bodyParser({limit: '50mb'}));
app.use(express.static(path.join(__dirname, '../app/')));
/*allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length');
next();
};
app.use(allowCrossDomain);*/
app.use(express.static(path.join(__dirname, '../app/')));
app.use('/', routes);
app.use('/api/user', user);
app.use('/api/country', country);
app.use('/api/city', country);
app.use('/api/state', country);
app.use('/api/mall', mall);
app.use('/api/category', category);
app.use('/api/attributes', attributes);
app.use('/api/subscription', subscription);
app.set('port',3000);
mongoose.connect('mongodb://52.39.244.83 /deals');
var db = mongoose.connection;
db.on('error',erroroccured);
db.once('open',startserver);
function erroroccured(){
console.log('error');
}
function startserver(){
// mongoose.set( "debug", true );
var server = app.listen(app.get('port'), function() {
console.log('Server listening on port ' + server.address().port);
});
}
module.exports = app;
so please help me to come out from this problem thanks to all in advance.
Because you have defined the hashPrefix('!') config, your URLs will now be
index.html#!/path
If you want a plain HTML5 mode style, like
index.html/path
Just don't define the hashPrefix. It defaults to ''.
Additionally you can also get rid of the base tag, but that might create issues with are going to define a base tag, define it as
<head>
<base href="/">
</head>
Instead of localhost:3000 as this would fail on your server.
I think just use this should be fine
$locationProvider.html5Mode(true);
And in html
<head>
<base href="/">
</head>
My project is nodeJs + angularJs + html.
main.html
<html>
<head>
<script src="angularJs.js"></script>
<script src="ui-router.js"></script>
</head>
<body ng-app="myApp">
<div ui-view></div>
</body>
<script>
var myApp = angular.module('myApp',['ui.router']).config(
function($stateProvider,$urlRouterProvider,$httpProvider){
$stateProvider.state('index',{
url:'/child',
templateUrl: '/child'
}
)});
</script>
</html>
MyProject/routes/index.js
var express = require('express');
var router = express.Router();
router.get('/child',function(req, res, next) {
res.render('back/childPage', { title: 'Express' });
});
MyProject/views/back/childpage.html
<div>
fsdfsfsafsfsa214324234234##
</div>
<script type="text/javascript">alert(1);</script>
MyProject/app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var ejs = require('ejs');
// view engine setup
app.engine('.html', ejs.__express);
app.set('view engine', 'html');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static('public'));
var routes = require('./routes/index');
app.use('/', routes);
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
when I access page(http://localhost:3000/#/child) ,the javascript code in childPage.html will not work.
if I just access nodeJs's router page(http://localhost:3000/child) ,the javascript code work well .
if anybody know that ,please answer to me . if you need more code in my project ,just tell me. thank you.
hahahhaahaha ,I get the answer ,just add a controller.
var myApp = angular.module('myApp',['ui.router']).config(
function($stateProvider,$urlRouterProvider,$httpProvider){
$stateProvider.state('index',{
url:'/child',
templateUrl: '/child'
controller:function(){
//you can operate element in childPage.html
}
}
)});
My application does not load templates in ng-view inside the index.thml.
I let my code here because i am lost.
app.js
var express = require('express');
var app = express();
var path = require('path');
var bodyParser = require('body-parser');
// var $ = require('jquery');
// global.jQuery = $;
// var bootstrap = require('bootstrap');
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', __dirname + 'views');
app.set('view engine', 'html');
var routes = require('./routes');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.get('/', function(req, res) {
res.sendFile(__dirname + "/public/views/index.html");
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
console.log('Started Success http://localhost:' + server.address().port);
});
And angular route
angular.module('geradorContrato', ['ngRoute'])
.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/contrato', {
templateUrl: '/public/views/contrato.html',
controller: 'ContratoController'
})
.when('/contratante', {
templateUrl: '/public/views/contratante.html',
controller: 'ContratanteController'
})
.when('/contratada', {
templateUrl: '/public/views/contratada.html',
controller: 'ContratadaController'
})
.when('/bemvindo', {
templateUrl: 'public/views/bemVindo.html',
});
});
But when i access http://localhost:3000/#/bemvindo
The page index.html loading success, but ngview not load and showing the message Cannot GET /public/views/bemVindo.html into console network chrome
Below is my index.html
<!DOCTYPE html>
<html ng-app="geradorContrato">
<head>
<meta charset="UTF-8">
<base href="/">
<link rel='stylesheet' href='/stylesheets/dist/css/bootstrap-theme.css'>
<link rel='stylesheet' href='/stylesheets/dist/css/bootstrap.css'>
<link rel="stylesheet" type="text/css" href="/stylesheets/mainStyle.css">
<script src="/javascript/lib/angular.js"></script>
<script src="/javascript/lib/angular-route.js"></script>
<script src="/javascript/lib/jquery.js"></script>
<script src="/javascript/lib/bootstrap.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-animate.js"></script>
<script src="/javascript/main.js"></script>
<script src="/javascript/ContratoController.js"></script>
<title>Cadastro</title>
<head>
<body>
<div class="container">
<ng-view></ng-view>
</div>
</body>
</html>
and below is my page simple bemVindo.html
OLÁ SEJA VEM VINDO!
This is base structure my app
Structure
Sorry guys, if you do not understand something tell me pl
sorry for my english
Suggestions
deek:
var express = require('express');
var app = express();
var path = require('path');
var bodyParser = require('body-parser');
app.use(express.static(path.join(__dirname, 'public')));
var routes = require('./routes');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use('/', express.static(path.join(__dirname, '/public/views/index.html')));
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
console.log('Started Success http://localhost:' + server.address().port);
});
Error Cannot GET /
path you have given must be wrong, check for the path where your file resides, try to console the path in the javascript console and provide the right path. "Cannot GET /public/views/bemVindo.html" means that the file bemVindo.html is not in the folder /public/views. It is not able to find the file hence showing this error.
Get rid of :
app.set('views', __dirname + 'views');
app.set('view engine', 'html');
Not needed....view engine html is default. Views folder isn't used.
EDIT: remove this too:
app.use(express.static(path.join(__dirname, 'public')));
Change this:
app.get('/', function(req, res) {
res.sendFile(__dirname + "/public/views/index.html");
});
To this:
app.use('/', express.static(path.join(__dirname, '/public/views/index.html')));
Let's express know this is a static directory where the html and supporting files are.
Express will treat it like a normal html directory and try to find an index file. From your index file, the angular will take over routing.
If you wanted to utilize express and templates for routing, the way you did it is best.
You set views folder if you want express to load template files from it but you have none.
You can mix and match with angular too.