简体   繁体   中英

How to Solve The partial head could not be found Handlebars

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM