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>
Related
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
I am a newbie to use express and as a result am bungling my way through making this web app.
I have my routes in a different file called route.js inside a module.export, and I manage all this inside app.js and I want to be able to serve a HTML page and keep it in the module. I've done so using sendFile but it doesn't serve the CSS and JS as well. What can I do to fix this?
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 index = require('./routes/index');
var users = require('./routes/users');
var app = express();
var port = process.env.PORT || 3000;
var mongoose = require('mongoose');
var flash = require('connect-flash');
var passport = require('passport');
var session = require('express-session');
var path = require('path');
//db
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
require('./config/passport')(passport);
// view engine setup
//app.set('views', path.join(__dirname, 'views'));
//app.set('view engine', 'jade');
app.set('view engine', 'ejs');
//routes
//app.use('/', index);
//app.use('/users', users);
// 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(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//passport
app.use(session({secret: 'secret'}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
//routes
require('./app/routes.js')(app, passport);
// catch 404 and forward to error handler
/*app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});*/
// error handler
/*app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});*/
module.exports = app;
//launch
app.listen(port);
console.log('Website starting on port ' + port);
routes.js
module.exports = function(app,passport) {
...
//--timesheet section---
app.get('/timesheet', function(req, res) {
var path = require('path');
res.sendFile(path.resolve('public/timesheet.html'));
});
...
}
You want to use a view engine and a static directory. You have some of the code already.
Your view engine using .ejs:
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
And you can define your static and specify a path prefix:
app.use('/assets', express.static(path.join(__dirname, 'public')));
In your views directory, put your htmls with .ejs extension, such as timesheet.ejs. You can then create an assets directory for your css/js/image files and reference them in your timesheet.ejs using /assets/style.css.
Finally, in your route, you'll want to render the template:
res.render('timesheet')
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.
I'm trying to load this helper on my Express / Handlebars project, but, I can't manage to make it work...
Here is my app.js
var express = require('express'),
exphbs = require('express-handlebars');
var app = express();
app.engine('handlebars', exphbs({
defaultLayout: 'main',
helpers: require('handlebars-form-helpers').helpers
}));
app.set('view engine', 'handlebars');
app.get('/', function (req, res) {
res.render('home');
});
app.listen(3000);
And here is the page when I try to load it
Kind of new with Handlebars integration with Express, so, I can't manage to figure it out...
This should work:
var exphbs = require('express-handlebars'),
handlebars = require('handlebars'),
helpers = require('handlebars-form-helpers').register(handlebars);
var hbs = exphbs.create({
helpers: helpers,
defaultLayout: 'main'
});
app.engine('.hbs', hbs.engine);
app.set('view engine', '.hbs');
You can find more info here: https://github.com/ericf/express-handlebars/blob/master/examples/advanced/server.js