shannonmoeller / gulp-hb

A sane Gulp plugin to compile Handlebars templates. Useful as a static site generator.

Home Page:http://npm.im/gulp-hb

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue loading in handlebars-layouts

spacedawwwg opened this issue · comments

I'm trying to combine gulp-hb and handlebars-layouts

It seems in v2, handlebars-layouts was somehow bundled in and simply worked without the need to load it in as a helper.

My guessing, since the upgrade to v3, handlebars-layouts isn't working this way and needs to be registered with the gulp-hb version of handlebars.

I'm just wondering what the best way to register this is, the example below does not seem to work.

Thanks for any help in advance.

"use strict";
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var frontMatter = require('gulp-front-matter');
var extname = require('gulp-extname');
var hb = require('gulp-hb');
var hbLayouts = require('handlebars-layouts');
// register layout helpers
hbLayouts.register(hb.handlebars);

var config = require('../config');
var handleError = require('../misc/handleError');

gulp.task('markup--compile', function () {
   return gulp.src(config.inputFiles.pages)
    .pipe(plumber({
      errorHandler: handleError
    }))
    .pipe(frontMatter({
      property: 'front',
      remove: true
    }))
    .pipe(extname())
    .pipe(hb({
      data: config.inputFiles.data,
      partials: config.inputFiles.templates,
      helpers: config.inputFiles.helpers,
      bustCache: true
    }))
    .pipe(gulp.dest(config.basePaths.dist));
});

currently getting

{ [Error: Missing helper: "extend"]
  description: undefined,

This is one of the v3 breaking changes. The every time hb() is run, it will get a new instance of handlebars. This solved issues #24 and #29.

The solution is to leverage another of the breaking changes. Specifically, the ability to register things in separate groupings using the fluent API. Give this a try:

"use strict";
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var frontMatter = require('gulp-front-matter');
var extname = require('gulp-extname');
var hb = require('gulp-hb');

var config = require('../config');
var handleError = require('../misc/handleError');

gulp.task('markup--compile', function () {
   return gulp.src(config.inputFiles.pages)
    .pipe(plumber({
      errorHandler: handleError
    }))
    .pipe(frontMatter({
      property: 'front',
      remove: true
    }))
    .pipe(extname())
    .pipe(hb()
      .data(config.inputFiles.data)
      .partials(config.inputFiles.templates)
      .helpers(config.inputFiles.helpers)
      .helpers('../node_modules/handlebars-layouts/index.js')
    )
    .pipe(gulp.dest(config.basePaths.dist));
});

The new API allows you to call .helpers() multiple times, where each call can have it's own globs and options.

This use case gives me an idea for an additional feature to make the whole ../node_modules... bit cleaner by accepting .helpers(require('handlebars-layouts')). Working on it!

Thanks, this has fixed the missing helper issue!

...BUT (I'm really sorry @shannonmoeller !!), I'm now getting [Error: Missing partial: 'layouts/layout--master'] errors.

My partials are simply "src/templates/**/*.hbs"

Is "src/templates/*/.hbs" a typo? Would expect "src/templates/**/*.hbs".

You are correct * Blushes *

No worries!

Ok. If you update to the just-released v3.1.0, you should be able to do this:

.helpers(require('handlebars-layouts'))

Hello. It's been a while since I used this (love it by the way), but I just updated to the latest version and am running into the same error message referenced above:

Missing helper: "extend"

I think I'm following your examples correctly... and I started a clean gulpfile.js with only the necessary code but it's not working for me. I hope it's not a silly little oversight on my part, but if you could help me out I'd appreciate it. Here is my gulpfile.js:

/** Grab modules */
var gulp = require('gulp');
var hb = require('gulp-hb');


/**
 * Handlebars compilation
**/
gulp.task('hbs', function () {
    return gulp
        .src('./src/**/*.html.hbs')
        .pipe(hb()
            .data('./data/**/*.json')
            .partials('./src/components/**/*.hbs')
            .partials('./src/layouts/**/*.hbs')
            .helpers(require('handlebars-layouts'))
        )
        .pipe(gulp.dest('./build'));
});

My package.json only has a few dependencies:

"devDependencies": {
    "gulp": "github:gulpjs/gulp#4.0",
    "gulp-hb": "^3.1.2",
    "gulp-load-plugins": "^1.2.0",
    "handlebars-layouts": "^3.1.3"
  },

Thank you much!

At first glance that looks like it should work. I'll setup a test case and dig a little deeper.

@thezimmee This turned out to be an issue with handlebars-wax. That has been resolved and published, so I updated the deps here and released as v3.2.0.

Awesome. I will test tomorrow to confirm. Thank you!

I'm still having a lot of issues with v3.x

I still get the Missing partial issue no matter what I change my paths to and the Missing helper issue when I try

.helpers(require('handlebars-layouts'))`

I find it confusing, as I haven't changed anything from the previous version other than registering things in separate groupings (as per your example above)

I'm going to stick with v2 for my current projects until I've had chance to experiment.

@spacedawwwg As I've been testing more I've run into similar issues. It seems to be related to how Handlebars implements the require.extensions hook for loading .handlebars and .hbs files.

All of the helpers and partials are now registered properly, but when attempting to use a partial that was compiled with the global instance of Handlebars (as is the case with that require hook), it fails to locate registered helpers.

Sorry for the back and forth on this. Thanks for sticking with me.

@spacedawwwg @thezimmee The require.extensions issue is resolved. I've updated my personal site as an end-to-end test case using partials and handlebars-layouts and it's working as expected. Released as v3.2.1. Thank you, both.

https://github.com/shannonmoeller/shannonmoeller.com/blob/develop/gulpfile.js#L25

@shannonmoeller, sorry for the delay, but I just did a quick check and confirmed it works for me. Thanks for your help with this!!!

Im still unable to get v3 working.

gulpfile.js

var requireDir = require('require-dir');

// recursively define gulp tasks
requireDir('build', {
  recurse: true
});

build/config.js

var basePaths = {
  src: 'src/',
  dist: 'dist/'
};

var inputFiles = {
  pages: basePaths.src + 'pages/**/*.hbs',
  data: basePaths.src + 'data/**/*.{json,yml}',
  templates: basePaths.src + 'templates/**/*.hbs',
  helpers: basePaths.src + 'helpers/*.js'
};

build/markup/markup--compile.js

"use strict";
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var extname = require('gulp-extname');
var hb = require('gulp-hb');
var hbLayouts = require('handlebars-layouts');

var config = require('../config');
var handleError = require('../misc/handleError');

gulp.task('markup--compile', function () {
   return gulp.src(config.inputFiles.pages)
    .pipe(plumber({
      errorHandler: handleError
    }))
    .pipe(extname())
    .pipe(hb()
      .data(config.inputFiles.data)
      .partials(config.inputFiles.templates)
      .helpers(config.inputFiles.helpers)
      .helpers(hbLayouts)
    )
    .pipe(gulp.dest(config.basePaths.dist));
});

src/pages/01_landing.hbs

{{#extend "layouts/layout--master"}}
  {{#content "master__body"}}
    {{> components/hero}}
    {{> components/section--standout}}
    {{> components/section--improve}}
    {{> components/section--exams}}
    {{> components/section--testimonials}}
    {{> components/section--experts}}
    {{> components/section--video}}
    {{> components/section--support}}
    {{> components/section--contact}}
    {{> components/modal--signup}}
  {{/content}}
{{/extend}}

error
screen shot 2016-02-18 at 11 30 28

file structure
screen shot 2016-02-18 at 11 31 03

@spacedawwwg Try setting cwd:

hb({ cwd: process.cwd() })

Thats was it, @shannonmoeller!

dancingdrunk_ron

@spacedawwwg The underlying lib handlebars-wax is using __dirname as a default instead of process.cwd(). I think it would make sense for gulp-hb to default back to process.cwd() as that's how gulp.src works. Thoughts?

I don't think handlebars-wax should change at all.

But I do think, as this is a gulp plugin, changing the default in gulp-hb to follow the same pattern as gulp's defaults (i.egulp.src), for simplicities sake and ease of integration, would probably be more beneficial to developers like myself.

Though, its not a massive task to add this setting now I know about it (so maybe a note in the README may suffice?)

It's an easy change to make gulp-hb use cwd() without having to change the underlying libs and I like the consistency it would bring. I'm going to make that change and release v4. Thanks again for all your help bug squashing v3.

v4 released.

@spacedawwwg @thezimmee This thread is getting pretty long, so I'm going to lock it down. I'll gladly help solve any other issues you may encounter, but would ask that they be reported in a new issue. Thanks!