npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

templatify

v0.0.2

Published

Middleware for browserify to load non-js files template as precompiled handlebar template

Downloads

11

Readme

templatify

Middleware for browserify to load non-js files as precompiled handlebars (or underscore) templates.

Build Status

Most of the code base and featureset ot this plugin is based and inspired on require-handlebars-plugin.

Usage

var templatify = require('templatify');

var bundle = browserify()
  .use(templatify('./', {
    files: ['**/*.html'],
    helpers: ['**/*.js']
  }))
  .bundle();

console.log(bundle);

// write output to `templates.js`
require('fs').writeFileSync('./templates.js', bundle);

// Use underscore adapater instead of handlebars default one
var bundle = browserify()
  .use(templatify('./', { adapter: templatify.adapters.underscore }))
  .bundle();

console.log(bundle);

Write a template ( path: app/template/one.html ):

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{ body }}

    {{! To include a partial: }}
    {{! Use underscores instead of slashes in your path, }}
    {{! and leave off the extension. }}

    {{> app_template_partial }}

  </div>
</div>

Here's the partial (optional) ( path : app/template/partial.html )

<div>
  {{! This can obviously have it's own partials, etc, etc }}
  I am a partial
</div>

Then require your templates like so:

var tmpl = require('app/template/one');
document.body.innerHTML = tmpl({ title: 'templatify', body: '☺' });

And then the output into body would be as follows:

<div class="entry">
  <h1>templatify</h1>
  <div class="body">
    ☺
    <div>
      I am a partial
    </div>
  </div>
</div>

Partials

To include a partial, use underscore instead of slashes in the path without file extension.

{{> app_template_partial }}

will include the app/template/partials.html file which might have it's own partials, etc, etc

Helpers

Just put your helpers in dirname/**/*.js and they'll automagically get pulled in as long as you write them as modules.

// dirname/yeller.js
var Handlebars = require('handlebars');

// exports so that we can require the helper function in our own code
var yeller = module.exports = function yeller(context, options) {
  // Assume it's a string for simplicity.
  context = context || '';
  return context.toUpperCase();
};

// and register as an handlebar helper.
Handlebars.registerHelper('yeller', yeller);

Then in your templates, you can just do:

{{yell maoow}}

The system will:

  • make sure these modules are pulled in automatically from the dirname directory
  • register each module as an handlebars helper.
  • register each module as a browserify module available through helper:basename
var yeller = require('helper:yeller'),
  assert = require('assert');

assert.equal(yeller('maoow'), 'MAOOW');

It's just a module that happens to register itself.

Meta Data

Any template that begins with a comment, with only a valid json object in it will be read in as meta data for the template.

This is advised to list the name of the template and give a description, though these aren't strictly necessary.

Introspection

In dev mode a few properties are added to your function (an object in javascript) as a helper with debugging and as a testing plug-point.

Those variables look like the following:

var tmpl = require('app/template/one');
console.log([
  'Variables referenced in this template: '                       + tmpl.vars.join(', '),
  'Vars/Partials/templates that this file directly depends on: '  + JSON.stringify(tmpl.deps),
  'Helpers that this template directly depends on: '              + JSON.stringify(tmpl.helpers),
  'Partials that this template directly depends on: '             + JSON.stringify(tmpl.partials),
  'The metadata object at the top of the file (if it exists): '   + JSON.stringify(tmpl.meta)
].join('\n'));

// Output..

// Variables referenced in this template: title, body
// Vars/Partials/templates that this file directly depends on: {"vars":["title","body"],"helpers":[],"partials":["app_template_partial"]}
// Helpers that this template directly depends on: []
// Partials that this template directly depends on: ["app_template_partial"]
// The metadata object at the top of the file (if it exists): {}

Note: All of these go away after a build if the debug options is set to false (defaults to true)

Options

var browserify = require('browserify'),
  templatify = require('templatify');

templatify(dirname, options);

dirname is the base working directory. Defaults to $cwd.

files

Glob pattern as string or array of strings for template files within dirname. Each match is then registered as an handlebar template and available through require('path/to/template').

Defaults to **/*.html.

helpers

Glob pattern as string or array of strings for handlebars helpers within dirname.

Defaults to **/*.js

ext

File extension to register, should match the files option.

Defaults to .html

compile

Function to call when templates are precompiled.

Defaults to Handlebars.compile.

parse

Function to call when templates are parsed, should return a list of node for ast traversal.

Defaults to Handlebars.parse.

tmpl

Base template to use for templates registered as commonjs module.

Defaults to:

var Handlebars = require('handlebars');

$helpers
$partials

var t = module.exports = Handlebars.template($body);

$debugProps

Handlebars.registerPartial('$partial', t);

debug

Indicate wheter or not introspection should be turned off. true will attach vars, helpers, partials and meta as function property.

Defaults to true.

glob

Configuration object to use for when using glob.sync. Refer to glob documentation for further details.

Defaults to {}.

Motivation

How templates are used within a webapp is an important question. That's usually done by fetching templates from the DOM with inline <script type="text/template" id="template-foo">...</script>, or from remote files with XHR. Both are the most common used ways to fetch template from client-side JavaScript.

Using AMD and requirejs, this is slightly better with the txt! plugin which allow templates to be located in their own file while inlined for production.

Another elegant approach used by Jammit is to use a JST variable (or any other namespace) to inline tamplates in a hash object relying on a build process to process the files. This is also the technique used in backbone-boilerplate.

Using browerify, node-fileify which is a really neat tool can be used to achieve that, however it simply returns html strings into an hash object with keys as filename.

Ideally, I'd like these template files to be compiled into handlebars precompiled template and try to be as close as possible to all the really cool features that require-handlebars-plugin offers (like18n helpers, partials, custom helpers, metadata, introspection...).

Other Templating Languages

If you'd like to implement this for your templating language of choice, you'll need:

  • A pre-compile type functionality.
  • If it has some concept of partials, that you can register them externally
  • For any of the meta-data, you'll need some fancy regex or an AST to walk through.

Other templates might be implemented by droping a folder into lib/templates which name is the template adapter to use. This folder must be a valid npm package, either by droping here an index.js or a complete package with its own package.json.

Install

npm install templatify

Append a -g flag if you intend to use the cli tool described below.

CLI Usage

Usage: 

   templatify files* [options]


Options:
   -o, --output    Output file, output to stdout if ommited
   -h, --helpers   Glob patterns for helper inclusion, usually js files (**/*.js)
   -c, --compress  Uglify bundle output (false)
   -a, --adapter   Template adapter to use, handlebars or underscore (handlebars)
   --help          You're starting at it

Tests - Build Status

npm tests

Credits

And special thanks to

  • @SlexAxton: Most of the inspiration for this package and the code base for ast traversal is based off the fantastic AMD plugin require-handlebars-plugin.

  • @substack: Reading through node-fileify sources was super handy. And of course, for creating browserify :p