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

render-cli

v0.3.2

Published

Render HTML from Jade, Handlebars, Swig and most other kinds of templates on the command line. Uses the consolidate.js template engine consolidation library for all heavy lifting.

Downloads

199

Readme

Render

Build Status

Render is an advanced command-line interface that renders text or HTML from Jade templates, Handlebars templates, Swig templates and pretty much any other kind of templates you can think of.

Use it to generate your static site, to fill out code skeletons, to populate config files – anything you can think of.

Install with NPM (bundled with node.js):

npm install render-cli -g

Render comes with an ISC license.

Features

  • dynamic output by passing JSON or YAML data (a.k.a. context variables) to your template
  • one to many means you can iterate over context data and render the same template once for each set of data
  • a generic interface so you don't have to learn a different command-line utility for every templating language you'd like to give a try
  • flexible naming with output paths that can vary based on the data, using path placeholders

Context variables

Pass context variables to your templates with --context <file>... for dynamic rendering. Context can be YAML or JSON.

# no context
render page.jade
# context from a single file
render page.jade \
    --input page.json
# context from multiple files which will be 
# merged (if objects) or appended (if arrays)
render page.jade \
    --context globals.json,page.json
# specify globals separately (for clarity)
render page.jade \
    --context page.json \
    --globals globals.json

One-to-one and one-to-many

Render a single page:

# output to `stdout`
render page.jade
# or redirect to wherever you like
render page.jade > hello-world.html

Render a single page with context:

# one template, one rendered html file
render page.jade \
    --context page.json

Pick your own output filename, optionally using information from the context:

render page.jade \
    --context page.json
    --output 'pages/{title}'

Render multiple pages, one for each item in an array:

render tableofcontents.jade \
    --context pages.json
    --output 'pages/{permalink}'
    --many

If you'd like to iterate over the keys and values of an object instead, e.g. a url-to-title mapping, use:

render tableofcontents.jade \
    --context links.json
    --many-pairs

Each key will be available as key, each value as value.

The --many and --many-pairs options both accept an optional key to traverse to before iterating:

render tableofcontents.jade \
    --context pages.json
    --output 'pages/{permalink}'
    --many results.pages

Useful if you don't have control over the input JSON and the array or object to iterate over is not at the root. Note that you can traverse multiple levels using dot notation, e.g. results.data.pages.

Namespacing context data

You can pass more than one file to render. Objects will be merged, arrays will be appended to.

When merging different inputs would result in name clashes, you have the option of namespacing the data from each input file.

Namespaces come in three flavors:

Type | Description | Flag ----------|---------------------------|-------------------------------- explicit | you pick the namespace | --input (namespace):(filename) automatic | the basename of the file | --namespaced automatic | the full path to the file | --fully-namespaced

Explicit namespaces

Explicit namespaces: put globals.json in a globals key rather than at the root of the context object.

render page.jade \
    --context globals:globals.json,page.json
{
    "globals": {
        ...
    }, 
    "title": "data from page.json, not namespaced", 
    ...
}

Automatic namespaces

Automatic namespaces: inside of the context object, globals.json data will be available under globals and page.json data under page.

render page.jade \
    --input globals.json,page.json
    --namespaced
{
    "globals": {
        ...
    }, 
    "page": {
        ...
    }
}

Automatic namespaces using the full path: helpers/globals.json will be accessible at helpers.globals and page.json will be under page.

render page.jade \
    --context helpers/globals.json,page.json
    --fully-namespaced
{
    "helpers": {
        "globals": {
            ...
        }
    }, 
    "page": {
        ...
    }
}

Explicit namespaces take preference over automatic ones, so these globals will be available under globals rather than helpers.globals:

render page.jade \
    --context globals:helpers/globals.json,page.json
    --fully-namespaced
{
    "globals": {
        ...
    }, 
    "page": {
        ...
    }
}

Dynamic output paths

Output paths can contain placeholders that will be interpolated to determine the final path to which to write the HTML for each rendered set of context. Think of your output path as a little template of its own.

If you're a web developer, this is similar to the kind of URL routing you see in web frameworks.

In a path like build/{date}/{permalink}, the date and permalink keys in your data determine where the final HTML ends up. This is especially useful when you ask render to iterate over your context data with --many, which will render and save each set of data separately.

Paths are interpolated using the exact same context data that was used to render your template.

Not just the output path, even the path to your template can be dynamic and based on the data. For example, templates/{layout}.swig will figure out which layout to use by looking for a layout key in your context variables. This means a single render command isn't limited to rendering just a single template.

Output paths that end in a slash will get /index.html tacked on the end.

Pattern | Context | Output -------------------------------|--------------------------|----------------------------- posts/{permalink}.html | permalink: hello-world | posts/hello-world.html posts/{permalink}/ | permalink: hello-world | posts/hello-world/index.html posts/{permalink}/index.html | permalink: hello-world | posts/hello-world/index.html

Supported template languages

By default, Render uses the templating language matching your extension (.swig for Swig, .jade for Jade). You can explicitly specify which renderer to use with the --engine option.

Supported engines include:

Render uses the consolidate.js template engine consolidation library for all rendering. For more information on how to contribute a new template engine wrapper, please take a look at their documentation.

Conditional rendering

If your context data includes a date in ISO format, you're in luck. Using the --newer-than <key> flag, you can tell render to only re-render if the context data is newer than the HTML that's already there.

The key flag indicates where in your data render can find the modified date.

This is particularly useful when iterating over multiple context sets: two or three sets of data might have changed but nothing else, and you shouldn't have to rerender all of it.

Speed

The speed of render will depend on the complexity of your templates, the template engine and the speed of your CPU and hard drive. You can reasonably expect to be able to render about 10 to 20 pages per second.

IO is usually the bottleneck, even on machines with solid state drives, so render processes content serially to avoid filesystem contention.