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

htmlr

v0.1.8

Published

DSL for html generation in the browser or templates on the server

Downloads

3

Readme

htmlr TravisCI

  • Htmlr is a template language for Express.
  • Htmlr is an easy way to create DOM elements in the browser.
  • Htmlr is a Domain Specific Language (DSL) in javascript for generating HTML.

Htmlr can be used on the server or in the browser. In the browser it can generate HTML text for use with .innerHTML or it can generate document fragments for use with .appendChild. Template files use a .htmlr extension and can be a javascript expression or a function that returns an Htmlr object.

Installation

npm install htmlr

For command line usage, install globaly:

npm install htmlr -g

Browser Usage

For use in the browser, include the following script tag:

<script src="lib/htmlr.js"></script>

Then create your dynamic elements in the browser:

with (Htmlr) {
  var template = div({class: 'person'},
    'Name: ', span('{name}'), br,
    'Email: ', span('{email}')
  );
}

var data = {name: 'Scott', email: '[email protected]'};

// html text generation
document.getElementById('my_div').innerHTML = template.render(data);

// DOM object generation
document.getElementById('my_div').appendChild( template.renderDOM(data) );
<div class="person">
Name: <span>Scott</span><br />
Email: <span>[email protected]</span>
</div>

Express Usage

Create the following 2 template files to mimic the default express jade templates and put them in the views directory:

  • layout.htmlr

    doctype()
    .html(
      head(
        title('{title}'),
        css('/stylesheets/style.css')
      ),
      body('{content}')
    )
  • index.htmlr

    extend('layout', {
    
    content:
      h1('{title}')
      .p('Welcome to {title}')
            
    })
  • error.htmlr

    extend('layout', {
    
    content:
      h1('{message}')
      .h2('{error.status}')
      .pre('{error.stack}')
            
    })

Then modify the app.js file to change the default rendering engine to htmlr:

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'htmlr');         // <=== put 'htmlr' right here
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

Command Line Usage

Htmlr can also be used on the command line to test templates without an express application running. Create a filed called template.htmlr and a file with json data called data.json:

  • template.htmlr

    doctype()
    .html(
      head({lang: 'en'},
        meta({charset: 'utf-8'}),
        title('{title}'),
        css('style.css'),
        javascript('script.js')
      ),
      body(
        h1("Hello World!"),
        comment("woot!"),
        div({id: 'content'}, '{content}')
      )
    )
  • data.json

    {"title": "My Title", "content": "My Content"}

Then run the following command:

htmlr template -d data.json -l
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="utf-8" />
    <title>My Title</title>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body>
    <h1>Hello World!</h1>
    <!--woot!-->
    <div id="content">
      My Content
    </div>
  </body>
</html>
  • Use the with statement to prevent pollution of the global namespace in the browser. ( with is forbidden in strict mode :( )

    with (Htmlr) {
      var template = div();
    }    
    var html = template.render();
    <div />

Features

  1. Use an object literal as the first parameter to set attributes

    with (Htmlr) {
      var template = div({id: 'mydiv', class: 'awesome'});
    }    
    var html = template.render();
    <div id="mydiv" class="awesome" />
  2. Use any other data type for the first parameter and all data types afterward for child nodes

    with (Htmlr) {
      var template = div('Literal String', br, 1337);
    }   
    var html = template.render();
    <div>Literal String<br />1337</div>
  3. Chain objects together to create siblings

    with (Htmlr) {
      var template = div().div();
    }
    var html = template.render();
    <div /><div />
  4. Create templates that can be reused. Pass data structures to templates to ease variable generation

    with (Htmlr) {
      var template = div({id: '{id}', class: '{class}'},
        '{content}'
      )
    }
        
    var data1 = {id: 'one', class: 'first second', content: 'Hello'};
    var data2 = {id: 'two', class: 'third', content: 'World!'};
        
    var html = template.render(data1) + template.render(data2);
    <div id="one" class="first second">Hello</div>
    <div id="two" class="third">World!</div>
  5. Use substitution syntax for creating templates that can be fed data, either objects or arrays

    with (Htmlr) {
      var template1 = div('{name}');
    }
    var data1 = {name: 'Scott'};
    var html1 = template1.render(data1);
    <div>Scott</div>
    with (Htmlr) {
      var template2 = div('{0}');
    }
    var data2 = ['Scott'];
    var html2 = template2.render(data2);
    <div>Scott</div>
  6. Loop through data structures, objects or arrays, using the each construct

    with (Htmlr) {
      var template1 = (
        ul(each()(
          li('{0}')
        ))
      );
    }
    var data1 = ['one', 'two', 'three'];
    var html1 = template1.render(data1);
    <ul>
      <li>one</li>
      <li>two</li>
      <li>three</li>
    </ul>
    with (Htmlr) {
      var template2 = (
        ul(each()(
          li('{key}: {value}')
        ))
      );
    }
    var data2 = {1: 'one', 2: 'two', 3: 'three'};
    var html2 = template2.render(data2);
    <ul>
      <li>1: one</li>
      <li>2: two</li>
      <li>3: three</li>
    </ul>

    each can also take a static list:

    with (Htmlr) {
      var template = (
        select(each(['North', 'South', 'East', 'West'])(
          option('{0}')
        )
      );
    }    
    var html = template.render();
    <select>
      <option>North</option>
      <option>South</option>
      <option>East</option>
      <option>West</option>
    </select>
  7. Includes the ability to extracts parts of the data object

    with (Htmlr) {
      var template1 = div(extract('error')(
        'Error',
        span('{number}'),
        ': ',
        span('{message}')
      ));
    }
    var data1 = {error: {number: 42, message: 'unknown question'}};
    var html1 = template1.render(data1);
    <div>Error <span>42</span>: <span>unknown question</span></div>

    extract can reach into multiple levels of data structure

    with (Htmlr) {
      var template2 = extract(1, 0)(div('{0}'));
    }
    var data2 = [[[0, 1], [2, 3]], [[4, 5], [6, 7]]];
    var html = template2.render(data2);
    <div>4</div>

Known Issues

None yet. We need more testers!