Socket
Book a DemoInstallSign in
Socket

@unic/estatico-handlebars

Package Overview
Dependencies
Maintainers
3
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@unic/estatico-handlebars

Transforms `Handlebars` to `HTML`.

latest
Source
npmnpm
Version
0.0.11
Version published
Maintainers
3
Created
Source

@unic/estatico-handlebars

Transforms Handlebars to HTML.

Installation

$ npm install --save-dev @unic/estatico-handlebars

Usage

const gulp = require('gulp');
const path = require('path');
const env = require('minimist')(process.argv.slice(2));

/**
 * HTML task
 * Transforms Handlebars to HTML
 *
 * Using `--watch` (or manually setting `env` to `{ watch: true }`) starts file watcher
 * When combined with `--skipBuild`, the task will not run immediately but only after changes
 *
 * Using `-LLLL` will display debug info like the data used for every template
 */
gulp.task('html', () => {
  const task = require('@unic/estatico-handlebars');
  const estaticoWatch = require('@unic/estatico-watch');
  const { readFileSyncCached } = require('@unic/estatico-utils');

  const instance = task({
    src: [
      './src/*.hbs',
      './src/pages/**/*.hbs',
      './src/demo/pages/**/*.hbs',
      '!./src/demo/pages/handlebars/*.hbs',
      './src/modules/**/!(_)*.hbs',
      './src/demo/modules/**/!(_)*.hbs',
      './src/preview/styleguide/*.hbs',
      '!./src/preview/styleguide/colors.hbs',
    ],
    srcBase: './src',
    dest: './dist',
    watch: {
      src: [
        './src/**/*.hbs',
        './src/**/*.data.js',
      ],
      name: 'html',
      dependencyGraph: {
        srcBase: './',
        resolver: {
          hbs: {
            match: /{{(?:>|#extend)[\s-]*["|']?([^"\s(]+).*?}}/g,
            resolve: (match /* , filePath */) => {
              if (!match[1]) {
                return null;
              }

              let resolvedPath = path.resolve('./src', match[1]);

              // Add extension
              resolvedPath = `${resolvedPath}.hbs`;

              return resolvedPath;
            },
          },
          js: {
            match: /require\('(.*?\.data\.js)'\)/g,
            resolve: (match, filePath) => {
              if (!match[1]) {
                return null;
              }

              return path.resolve(path.dirname(filePath), match[1]);
            },
          },
        },
      },
      watcher: estaticoWatch,
    },
    plugins: {
      clone: null,
      handlebars: {
        partials: [
          './src/**/*.hbs',
        ],
      },
      // Wrap with module layout
      transformBefore: (file) => {
        if (file.path.match(/(\\|\/)modules(\\|\/)/)) {
          return Buffer.from(readFileSyncCached('./src/preview/layouts/module.hbs'));
        }

        return file.contents;
      },
      // Relativify absolute paths
      transformAfter: (file) => {
        let content = file.contents.toString();
        let relPathPrefix = path.join(path.relative(file.path, './src'));

        relPathPrefix = relPathPrefix
          .replace(new RegExp(`\\${path.sep}g`), '/') // Normalize path separator
          .replace(/\.\.$/, ''); // Remove trailing ..

        content = content.replace(/('|")\/(?!\^)/g, `$1${relPathPrefix}`);

        content = Buffer.from(content);

        return content;
      },
    },
  }, env);
  
  // Don't immediately run task when skipping build
  if (env.watch && env.skipBuild) {
    return instance;
  }

  return instance();
});

Run task (assuming the project's package.json specifies "scripts": { "gulp": "gulp" }): $ npm run gulp html

See possible flags specified above.

API

plugin(options, env) => taskFn

options

src (required)

Type: Array or String
Default: null

Passed to gulp.src.

srcBase (required)

Type: String
Default: null

Passed as base option to gulp.src.

dest (required)

Type: String
Default: null

Passed to gulp.dest.

watch

Type: Object
Default: null

Passed to file watcher when --watch is used.

plugins

Type: Object

plugins.handlebars

Type: Object
Default:

handlebars: {
  partials: null,
  helpers: null, // NOTE: handlebars-layouts are registered by default
}

Passed to gulp-hb.

Partials and helpers are resolved via handlebars-wax. This is happening outside of the task function, allowing us to export the handlebars instance with partials and helpers already registered. It can be required via require('@unic/estatico-handlebars').handlebars.

A simple helper example:

{
  helpers: {
    link: object => `<a href="${object.url}">${object.text}</a>`,
    foo: bar => `<span>${bar}</span>`,
  },
}

If a helpers needs access to handlebars, a factory has to be used instead (see docs on handlebars-wax):

{
  helpers: {
    register: (handlebars) => {
      handlebars.registerHelper('link', (object) => { // eslint-disable-line arrow-body-style
        return new handlebars.SafeString(`<a href="${object.url}">${object.text}</a>`);
      });

      handlebars.registerHelper('foo', bar => `<span>${bar}</span>`);
    },
  },
}

NOTE: handlebars-layouts) is registered by default

plugins.data

Type: Function
Default:

data: (file) => {
  // Find .data.js file with same name
  try {
    const data = require(file.path.replace(path.extname(file.path), '.data.js'));

    return Object.assign({}, data);
  } catch (e) {
    return {};
  }
}

Setting up data to be used in handlebars compiling. Return value will be assigned to file.data where gulp-hb picks it up.

plugins.prettify

Type: Object
Default:

prettify: {
  indent_with_tabs: false,
  max_preserve_newlines: 1,
}

Passed to gulp-prettify. Setting to null will disable this step.

plugins.clone

Type: Object
Default:

clone: dev ? null : {
  data: {
    env: {
      dev: false,
    },
  },
  rename: filePath => filePath.replace(path.extname(filePath), `.prod${path.extname(filePath)}`),
},

This potentially speeds up CI builds (where the same templates are built with both a dev and prod config) since we only run the expensive task of setting up the data once.

The CI needs to take care of moving & renaming the .prod.html files.

logger

Type: { info: Function, debug: Function, error: Function }
Default: Instance of estatico-utils's Logger utility.

Set of logger utility functions used within the task.

env

Type: Object
Default: {}

Result from parsing CLI arguments via minimist, e.g. { dev: true, watch: true }. Some defaults are affected by this, see above.

License

Apache 2.0.

FAQs

Package last updated on 19 Sep 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts