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

mostache

v1.2.0

Published

mo' mustache. A slightly enhanced but backward-safe version of mustache.js to allows easier helper invocation, index injection, and delimiters

Downloads

5

Readme

Mostache == Mo Mustache

What and Why

Mostache has a modest goal: unobtrusively add a few key features to standard mustache templates while changing the original mustache library code as little as possible.

I love mustache, but I felt it could be slightly easier to feed it JSON without re-inventing the wheel or adding dozens of kilobytes of parsing code and while making sure that Mustache performance doesn't suffer from the modification. As a result, virtually any valid mustache template can be used with mostache, so upgrading is easy.

Try online examples at http://danml.com/mostache/

New Features

{INDEX} mini-tag

Note the single-brace. Returns the current index when iterating an Array. {{#persons}}<li> #{INDEX}. {{firstName}} {{lastName}} </li> {{/persons}}

{SEP} mini-section

Note the single-brace. Returns the enclosed block for every value except for the last. {SEP} <br /> {/SEP}

{{!path}} else synax

{{!path}} turns into {{/path}}{{^path}}, for simpler else handling. <p>{{#ok}}Y{{!ok}}N{{/ok}}</p> == <p>{{#ok}}Y{{/ok}}{{^ok}}N{{/ok}}</p>

{{#k=v}} conditionals

Compares are made against a primitive value to the right of the =, no code/path/expressions evaluated. {{#sec=main}}Home{{/sec=main}} turns into Home with {sec:"main"} and nothing with {sec:'about'} . {{#a.length=3}}{{.}}{{/a.length=3}} turns into abc with {a:"abc"} and nothing with {a:'a'} . For performance reasons, long paths are not parsed, only one dot to the left of the equal, but wrapper blocks can drill.

{{#k!=v}} NOT conditionals

Compares are made against a primitive value to the right of the =, no code/path/expressions evaluated. {{#sec=!main}}Home{{/sec=!main}} turns into Home with {sec:"about"} and nothing with {sec:"main"} . {{#a.length!=3}}{{.}}{{/a.length!=3}} turns into abc with {a:"a"} and nothing with {a:'abc'} . For performance reasons, long paths are not parsed, only one dot to the left of the equal, but wrapper blocks can drill.

<@macro@> synax

Using <@ and @> in a template invokes macro mode, where the template is run twice. First, delimeters are switched to <@ and @> and the template is applied with normal data. Then, the result is re-fed as to re-render normally. This can be used for sub-queries, marcos, even UI generation. Mustache.to_html("Selected: {{data.<@selected@>}}", {data:["A","B","C"], selected: 1}) yields Selected: B The internal intermediate template for the above looks like Selected {{data.1}} after the first pass.

{{#obj:key}} object iteration

Iterates over objects using a placeholder name on the section tag, prefixed by ":". Inside the section, the key as a tag will equal the name of the object property's key. {{#a:k}}{{k}}={{.}} {{/a:k}} turns into b=1 c=5 with {a:{b:1,c:5}}

{{__.key}} root synax

{{__.key}} reaches key on the data object given to Mustache, bypassing local conflicts. {{#b}}{{a}}|{{__.a}}{{/b}} turns into 1|123 with {a:123, b:[{a:1}]}

parameters for partials

{{> mailto email}} passes an argument of email to a function partial. This can be used to make more powerful/flexible custom helpers, and help to avoid hard-coding helper to data: {{name}} ({{> mailto email}}) with {name:"Mary", email: "[email protected]"} where

function(method, args, context){
  switch(method){ // values can be          interpolated    -or-  realized now
    case "mailto": return '<a href="mailto:{{'+args[0]+'}}">'+context[args[0]].toUpperCase()+'</a>' ;break;
  } 
}

is the partial yields Mary (<a href="mailto:[email protected]">[email protected]</a>) The original mustache would need email hard-coded into the partial above.

razor syntax

Activated by including {{@@}} inside a template, allows a leaner razor-style syntax It replaces {{ with @ and }} with , allowing leaner {{[#^/]section}} and {{name}} tags It needs a non-letter to the left of the @ so as to avoid emails, but regular mustache works as well. This syntax is enabled via one RegExp replace() on the template before compilation

Mustache.to_html(
  "{{@@}} <ul> @#actors <li>@name  @/actors", 
  { actors: [ 
          { name: "Jeff Bridges" },
          { name: "John Goodman" },
          { name: "Steve Buscemi" }
      ]
}); 

Which is pre-converted internally to the template: <ul> {{#actors}} <li>{{name}} {{/actors}} Which renders html as:

  • Jeff Bridges
  • John Goodman
  • Steve Buscemi

native method detection

Normally mustache passes any functions in the data to a special helper function, which doesn't work with native methods like "".toUpperCase(). Mostache detects natives methods in data and runs them against the data itself. it was always awkward to try to mash in methods to JSON data, but now at least the handy primitive native methods work without fuss.

It's harder to explain than use. ex: {{name.toUpperCase}} now produces the data's name property's value in UPPERCASE, instead of the useless "[object Object]". Regular functions in your data still act as expected, it's only the existing hidden primitive methods in your data that run smarter. Mostly, these are for strings, but {{number.toFixed}} will produce an integer from a number, and {{array.sort}} will sort an array as alphabetical case-sensitive text.

{|helpers}

The biggest improvement: calling helpers from the template instead of the data. Placed after a normal mustache path, filters pass the value to a filter for processing, formatting, or selection. You can use many filters on the same value by separating each one with a pipe ("|"), and the result will be passed left to right through each of the filters. The function is reached by it's gloabl JS path, so any object or function can be used to process, without registering to mustache ahead of time.

Also note that if no value if found by the path/text to the left of the first "|", the path itself as a string (or nothing) will be used instead. That allows a particularly neat way of using JS mid-template: {{location|eval}}, or just injecting function returns: {{|Date}}.

Live Demo of helpers, adapted from handlbars demo

Finally, a special method indicator prefix (".") in front of the method name forces a method of the value to be executed, for example "".toUpperCase() as {{name|.toUpperCase}}.