A lightweight, powerful and highly extensible templating engine. In the browser or on Node.js, with or without jQuery.

Overview

JsRender: best-of-breed templating

Simple and intuitive, powerful and extensible, lightning fast

For templated content in the browser or on Node.js (with Express 4, Hapi and Browserify integration)

JsRender is a light-weight but powerful templating engine, highly extensible, and optimized for high-performance rendering, without DOM dependency. It is designed for use in the browser or on Node.js, with or without jQuery.

JsRender and JsViews together provide the next-generation implementation of the official jQuery plugins JQuery Templates, and JQuery Data Link -- and supersede those libraries.

Documentation and downloads

Documentation, downloads, samples and API docs and tutorials are available on the www.jsviews.com website.

The content of this ReadMe is available also as a JsRender Quickstart.

JsRender and JsViews

JsRender is used for data-driven rendering of templates to strings, ready for insertion in the DOM.

It is also used by the JsViews platform, which adds data binding to JsRender templates, and provides a fully-fledged MVVM platform for easily creating interactive data-driven single page apps and websites.

JsRender installation

jsrender.js is available from downloads on the jsviews.com site.

CDN delivery is available from the cdnjs CDN at cdnjs.com/libraries/jsrender.

Alternatively:

Using JsRender with jQuery

When jQuery is present, JsRender loads as a jQuery plugin and adds $.views, $.templates and $.render to the jQuery namespace object, $ (or window.jQuery).

Example HTML page: JsRender with jQuery

Using JsRender without jQuery

When jQuery is not present, JsRender provides its own global namespace object: jsrender (or window.jsrender)

The jsrender namespace provides the same methods/APIs as with jQuery, so if jQuery is not present you can still use all the API examples, by simply writing:

var $ = window.jsrender;

// Now use code as in samples/examples, with $.views... $.templates... $.render...

(Note: If jQuery is not loaded, then passing a jQuery selector to $.templates() will only work for the ID selector)

Example HTML page: JsRender without jQuery

JsRender on Node.js

JsRender can be used to render templates on the server (using Node.js) as well as in the browser. JsRender on Node.js has all the features and APIs of JsRender in the browser, plus some additional ones specific to Node.js.

It also provides built-in Express, Hapi and Browserify integration -- which makes it easy to register templates as simple .html files on the file system, and then load and render them either server-side, client-side or both.

Learn more: JsRender Node.js Quickstart and JsRender APIs for Node.js.

Code samples: See JsRender Node Starter for running code examples of Node.js scenarios, including with Express, Hapi and Browserify.

JsRender usage

Define a template

From a string:

var tmpl = $.templates("Name: {{:name}}");

From a template declared as markup in a script block:

<script id="myTemplate" type="text/x-jsrender">
Name: {{:name}}
</script>

then, somewhere in your script:

var tmpl = $.templates("#myTemplate"); // Pass in a jQuery selector for the script block

On Node.js, from an .html file containing the template markup:

var $ = require('jsrender'); // returns the jsrender namespace object
var tmpl = $.templates("./templates/myTemplate.html");

Learn more...

Render a template

tmpl.render(object) (or shortcut form: tmpl(object)) renders the template with the object as data context.

var tmpl = $.templates(" Name: {{:name}}<br/> ");

var person = {name: "Jim"};

// Render template for person object
var html = tmpl.render(person); // ready for insertion, e.g $("#result").html(html);

// result: "Name: Jim<br/> "

tmpl.render(array) (or tmpl(array)) renders the template once for each item in the array.

var people = [{name: "Jim"}, {name: "Pedro"}];

// Render template for people array
var html = tmpl.render(people); // ready for insertion...

// result: "Name: Jim<br/> Name: Pedro<br/> "

Learn more...

Register a named template - and render it

// Register named template - "myTmpl1
$.templates("myTmpl1", "Name: {{:name}}<br/> ");

var person = {name: "Jim"};

// Render named template
var html = $.templates.myTmpl1(person);

// Alternative syntax: var html = $.render.myTmpl1(person);

// result: "Name: Jim<br/> "

Learn more...

Template tags

Template tag syntax

  • All tags other than {{: ...}} {{> ...}} {{* ...}} {{!-- --}} behave as block tags

  • Block tags can have content, unless they use the self-closing syntax:

    • Block tag - with content: {{someTag ...}} content {{/someTag}}
    • Self-closing tag - no content (empty): {{someTag .../}}
  • A particular case of self-closing syntax is when any block tag uses the named parameter tmpl=... to reference an external template, which then replaces what would have been the block content:

    • Self-closing block tag referencing an external template: {{someTag ... tmpl=.../}} (This lets you do template composition. See example.)
  • Tags can take both unnamed arguments and named parameters:

    • {{someTag argument1 param1=...}} content {{/someTag}}
    • an example of a named parameter is the tmpl=... parameter mentioned above
    • arguments and named parameters can be assigned values from simple data-paths such as address.street or from richer expressions such as product.quantity * 3.1 / 4.5, or name.toUpperCase()

Learn more...

Built-in tags

{{: ...}} (Evaluate)

{{: pathOrExpr}} inserts the value of the path or expression.

var data = {address: {street: "Main Street"} };
var tmpl = $.templates("<b>Street:</b> {{:address.street}}");
var html = tmpl.render(data);

// result: "<b>Street:</b> Main Street"

Learn more...

{{> ...}} (HTML-encode)

{{> pathOrExpr}} inserts the HTML-encoded value of the path or expression.

var data = {condition: "a < b"};
var tmpl = $.templates("<b>Formula:</b> {{>condition}}");
var html = tmpl.render(data);

// result: "<b>Formula:</b> a &lt; b"

Learn more...

{{include ...}} (Template composition - partials)

{{include pathOrExpr}}...{{/include}}evaluates the block content against a specified/modified data context.

{{include ... tmpl=.../}} evaluates the specified template against an (optionally modified) context, and inserts the result. (Template composition).

var data = {name: "Jim", address: {street: "Main Street"} };

// Register two named templates
$.templates({
  streetTmpl: "<i>{{:street}}</i>",
  addressTmpl: "{{:name}}'s address is {{include address tmpl='streetTmpl'/}}."
});

// Render outer template
var html = $.templates.addressTmpl(data);

// result: "Jim's address is <i>Main Street</i>"

Learn more...

{{for ...}} (Template composition, with iteration over arrays)

{{for pathOrExpr}}...{{/for}}evaluates the block content against a specified data context. If the new data context is an array, it iterates over the array, renders the block content with each data item as context, and concatenates the result.

{{for pathOrExpr tmpl=.../}} evaluates the specified template against a data context. If the new data context is an array, it iterates over the array, renders the template with each data item as context, and concatenates the result.

<script id="peopleTmpl" type="text/x-jsrender">
  <ul>{{for people}}
    <li>Name: {{:name}}</li>
  {{/for}}</ul>
</script>
var data = {people: [{name: "Jim"}, {name: "Pedro"}] };
var tmpl = $.templates("#peopleTmpl");
var html = tmpl.render(data);

// result: "<ul> <li>Name: Jim</li> <li>Name: Pedro</li> </ul>"

Learn more...

{{props ...}} (Iteration over properties of an object)

{{props pathOrExpr}}...{{/prop}} or {{props pathOrExpr tmpl=.../}} iterates over the properties of the object returned by the path or expression, and renders the content/template once for each property - using as data context: {key: propertyName, prop: propertyValue}.

<script id="personTmpl" type="text/x-jsrender">
  <ul>{{props person}}
    <li>{{:key}}: {{:prop}}</li>
  {{/props}}</ul>
</script>
var data = {person: {first: "Jim", last: "Varsov"} };
var tmpl = $.templates("#personTmpl");
var html = tmpl.render(data);

// result: "<ul> <li>first: Jim</li> <li>last: Varsov</li> </ul>"

Learn more...

{{if ...}} (Conditional inclusion)

{{if pathOrExpr}}...{{/if}} or {{if pathOrExpr tmpl=.../}} renders the content/template only if the evaluated path or expression is 'truthy'.

{{if pathOrExpr}}...{{else pathOrExpr2}}...{{else}}...{{/if}} behaves as 'if' - 'else if' - 'else' and renders each block based on the conditions.

<script id="personTmpl" type="text/x-jsrender">
  {{if nickname}}
    Nickname: {{:nickname}}
  {{else name}}
    Name: {{:name}}
  {{else}}
    No name provided
  {{/if}}
</script>
var data = {nickname: "Jim", name: "James"};
var tmpl = $.templates("#personTmpl");
var html = tmpl.render(data);

// result: "Nickname: Jim"

Learn more...

Other built-in tags

For details on all the above built-in tags, as well as comment tags {{!-- ... --}} and allow code tags {{* ... }} and {{*: ...}}, see the tags documentation on jsviews.com.

Custom tags

Creating your own custom tags is easy. You can provide an object, with render method, template, event handlers, etc. See samples here and here on jsviews.com. But for simple tags, you may only need a simple render function, or a template string.

For example the two following definitions for a {{fullName/}} tag provide equivalent behavior:

As a render function:

$.views.tags("fullName", function(val) {
  return val.first + " " + val.last;
});

Or as a template string:

$.views.tags("fullName", "{{:first}} {{:last}}");

Either way, the result will be as follows:

var tmpl = $.templates("{{fullName person/}}");
var data = {person: {first: "Jim", last: "Varsov"}};
var html = tmpl.render(data);

// result: "Jim Varsov"

Helpers

For details on helpers, see the Helpers documentation topic on jsviews.com.

Here is a simple example. Two helpers - a function, and a string:

var myHelpers = {
  upper: function(val) { return val.toUpperCase(); },
  title: "Sir"
};

Access the helpers using the ~myhelper syntax:

var tmpl = $.templates("{{:~title}} {{:first}} {{:~upper(last)}}");

We can pass the helpers in with the render() method

var data = {first: "Jim", last: "Varsov"};

var html = tmpl.render(data, myHelpers);

// result: "Sir Jim VARSOV"

Or we can register helpers globally:

$.views.helpers(myHelpers);

var data = {first: "Jim", last: "Varsov"};
var html = tmpl.render(data);

// result: "Sir Jim VARSOV"

Learn more...

Converters

Converters are used with the {{:...}} tag, using the syntax {{mycvtr: ...}}}.

Example - an upper converter, to convert to upper case:

$.views.converters("upper", function(val) { return val.toUpperCase(); });

var tmpl = $.templates("{{:first}} {{upper:last}}");
var data = {first: "Jim", last: "Varsov"};
var html = tmpl.render(data);

// result: "Jim VARSOV"

Learn more...

Logic and expressions

JsRender supports rich expressions and logic, but at the same time encapsulates templates to prevent random access to globals. If you want to provide access to global variables within a template, you have to pass them in as data or as helpers.

You can assign rich expressions to any template arguments or parameters, as in:

{{:person.nickname ? "Nickname: " + person.nickname : "(has no nickname)"}}

or

{{if ~limits.maxVal > (product.price*100 - discount)/rate}}
  ...
{{else ~limits.minVal < product.price}}
  ... 
{{else}}
  ... 
{{/if}}

Documentation and APIs

See the www.jsviews.com site, including the JsRender Quickstart and JsRender APIs topics.

Demos

Demos and samples can be found at www.jsviews.com/#samples, and throughout the API documentation.

(See also the demos folder of the GitHub repository - available here as live samples).

Comments
  • Provide a tool for pre-compiling templates

    Provide a tool for pre-compiling templates

    Is it possible to make a tool available for precompiling templates (using node, for instance)?

    This could be integrated in an assets builder setup or using tools like Guard.

    I'm hoping this could improve performance under production.

    Thanks for considering the idea.

    opened by rosenfeld 25
  • unicode characters in template expressions

    unicode characters in template expressions

    We have some autogenerated code and for whatever reasons we have javascript objects with property names using non english characters such as åäö. When we want to print a property from such an object we would type something like this in our template: {{:myObj.someÅpropÄerty}}

    This doesn't work because the javascript generated from this template expression is invalid. +((v=data.myObj.someÅdata.propÄdata.erty)!=null?v:"");

    I managed to track down the problem to a couple of regexes using \w character class, which doesn't support anything but ascii characters.

    I made the following changing in jsrender.js - we use the separate files Lines 54-57:

        uW = "\\w\\u00E4\\u00E5\\u00F6\\u00C4\\u00C5\\u00D6",
    
        //rPath = /^(!*?)(?:null|true|false|\d[\d.]*|([\w$]+|\.|~([\w$]+)|#(view|([\w$]+))?)([\w$.^]*?)(?:[.[^]([\w$]+)\]?)?)$/g,
        rPath = new RegExp("^(!*?)(?:null|true|false|\\d[\\d.]*|([" + uW + "$]+|\\.|~([" + uW + "$]+)|#(view|([" + uW + "$]+))?)([" + uW + "$.^]*?)(?:[.[^]([" + uW + "$]+)\\]?)?)$", "g"),
        //        not                               object     helper    view  viewProperty pathTokens      leafToken
    
    
        //rParams = /(\()(?=\s*\()|(?:([([])\s*)?(?:(\^?)(~?[\w$.^]+)?\s*((\+\+|--)|\+|-|~(?![\w$_])|&&|\|\||===|!==|==|!=|<=|>=|[<>%*:?\/]|(=))\s*|(!*?(@)?[#~]?[\w$.^]+)([([])?)|(,\s*)|(\(?)\\?(?:(')|("))|(?:\s*(([)\]])(?=[.^]|\s*$|[^([])|[)\]])([([]?))|(\s+)/g,
        rParams = new RegExp("(\\()(?=\\s*\\()|(?:([([])\\s*)?(?:(\\^?)(~?[" + uW + "$.^]+)?\\s*((\\+\\+|--)|\\+|-|~(?![" + uW + "$_])|&&|\\|\\||===|!==|==|!=|<=|>=|[<>%*:?\\/]|(=))\\s*|(!*?(@)?[#~]?[" + uW + "$.^]+)([([])?)|(,\\s*)|(\\(?)\\\\?(?:(')|(\"))|(?:\\s*(([)\\]])(?=[.^]|\\s*$|[^([])|[)\\]])([([]?))|(\\s+)", "g"),
    

    Seems kinda ugly to hard code the extra non-english characters like this. Perhaps you could make this user configurable or give unicode more generic support?

    Even if using non-english characters for property names seem like a bad idea it's still valid javascript and as such I feel the same expression should be valid inside the template.

    As a workarround I know we can type {{:myObj["someÅpropÄerty"]}} but this is ugly.

    What's your take on the whole?

    Feature request After V1? Resolved 
    opened by johan-ohrn 21
  • Consider allowing block tags immediate access to parent variables

    Consider allowing block tags immediate access to parent variables

    I understand that the current implementation of JsRender treats each block tag as essentially its own view. This means that if you have a variable accessible to the main template, it is no longer accessible to the block:

    {{!-- called with {foo: 'bar', baz: [1, 2, 3]} --}}
    {{: foo}}
    {{for baz}}
      {{: foo}} {{!-- error, can't find it--}}
    {{/for}}
    

    I know there are ways around this, either by using #parent.parent.data or passing variables in explicitly. However, it seems unintuitive to have to do this every time you open a for block. Just based on experience with pretty much every programming language in existence, a simple block does not lose all access to parent variables - it's not like using an external template, which would be more akin to a new function with new local scope.

    I also understand that this is due to JsRender's (rather odd, IMO) decision to only "work" on a single data item at once and all normal accesses would be properties of that item. But we could at least attach the parent item's properties as helper objects, for example, so they could be easily accessed as ~variables without having to explicitly declare them for every single block.

    Feature request Resolved 
    opened by dorner 21
  • IE8 exception thrown and not caught

    IE8 exception thrown and not caught

    We are using jsrender informal pre beta commit counter: 21 without jsviews. When using templates on the page, everything works fine in all browsers. When we use Pappa's method to load templates, we get the "exception thrown and not caught" error line 670 only in IE8. Is this something you might be able to provide guidance on?

    opened by 2ndCharter 18
  • memory leaking

    memory leaking

    My application is struggling with memory leakage.

    To find the cause of any memory leaking I broke the whole application into parts and tested them individually.

    When testing jsrender I found memory leaks when wrtiting to .html() over and over again. I also tried very similar code in handlebars and found the memory is being hadnled much more efficiently.

    jsrender

    jsrender

    handlebars

    handlebars

    My Jsrender code

    <script>
            var data = {
                forms: [
                    {
                        title: "Form 1",
                        subforms: [
                           {
                            title: "Subform 1",
                            groups: [
                                   {
                                    title: "Group1",
                                    fields: [
                                        {
                                            title: "Field1",
                                            data: { name: "A", surname: "Smith" }
                                        },
                                        {
                                            title: "Field2",
                                            data: { name: "B", surname: "Smith" }
                                        }
                                    ]
                                   }
                            ]
                           }
                        ]
    
                    }
                ]
            }
            $(function () {
                var repeatIsOn = false;
                window.render = function() {
    
                    //console.time("Render");
                    $("#target").html($("#formTmpl").render(data));
                    //console.timeEnd("Render");
    
                    if (repeatIsOn) {
                        setTimeout("render()", 10);
                    }
                }
    
                $("#repeatBtn").on("click", function () {
                    $(this).toggleClass('on');
                    repeatIsOn = !repeatIsOn;
                })
                $("#renderBtn").on("click", render);
            });
        </script>
    
        <button id="repeatBtn">Repeat</button>
        <button id="renderBtn">Render</button>
        <div id="target"></div>
    
        <script id="formTmpl" type="text/x-jquery-tmpl">
            <ul>
                {{for forms}}
                <li>{{:title}}
                <ul>
                    {{for subforms}}
                    <li>{{:title}}
                    <ul>
                        {{for groups}}
                        <li>{{:title}}
                        <ul>
                            {{for fields}}
                            <li>{{:title}}
                            {{:data.name}}
                            </li>
                            {{/for}}
                        </ul>
                        </li>
                        {{/for}}
                    </ul>
                    </li>
                    {{/for}}
                </ul>
                </li>
                {{/for}}
            </ul>
        </script>
    
    

    Can you suggest a way to prevent / clean up this memory leaking?

    Or is there an issue with the source code?

    opened by blowsie 17
  • Feature Request - Switch / Case Statement.

    Feature Request - Switch / Case Statement.

    Im often writing templates where, if i was writing javascript I would be writing a Switch / Case statement. http://www.w3schools.com/js/js_switch.asp

    It would be nice if jsrender offered this functionality, for readability and possibly performance?

    Example of my template

    {{if ~getvar('renderType') == "email"}}
            code
    {{else ~getvar('renderType') == "company"}}
            code
    {{else ~getvar('renderType') == "file"}}
            code
    {{else ~getvar('renderType') == "itemType"}}
            code
    {{/if}}
    

    Suggested markup, updated to incorporate {{break}} (Thanks @coolbloke1324 )

    {{switch ~getvar('renderType')}}
        {{case 'email'}}
        {{case 'email2'}}
            code
            {{break}}
        {{case 'file'}}
            code
            {{break}}
    {{/switch}}
    
    Feature request After V1? 
    opened by blowsie 17
  • Fix nested helper functions.

    Fix nested helper functions.

    The following templates will not work as expected

    {{ ~helperFoo ( ~helperBar() ) }}
    {{if ~helperFoo( ~helperBar() ) > 0 }} something  {/if}
    

    This is because the compiler does not recognize nested helper functions and will rather concat them (i.e. the compilation result for the above would include view.hlp('helperFoo')( view.hlp('helperBar' ) )

    opened by Thinkscape 17
  • Hi,

    Hi,

    I have been using jsrender template in one of my project.

    Its working fine when there is less than 200 items to be rendered. But when i try to render 2000 items, it sucks up all the memory and browser freezes, any suggestion how to improve performance in this scenario Here is template

    <script id="assetTmpl" type="text/x-jsrender">
    {^{for assets}}
    <div data-link="class{:IsSelected?'asset colored':'asset'}rid{:AssetID}name{:FriendlyName}reg{:Registration}time{:TimeTicks}vsp{:VehicleStatusParked}vsd{:VehicleStatusDriving}vsi{:VehicleStatusIdle}vsx{:VehicleStatusXIdle}vrd{:RemainingDrive}" onclick="colorMe(this);">
        <div class="asset-header">
            <div onclick="toggleBody(this);" class="asset-body-toggle">
                {^{if IsBodyVisible}}
                <i class="fa fa-caret-square-o-up fa-2x"></i>
                {{else}}
                <i class="fa fa-caret-square-o-down fa-2x"></i>
                {{/if}}
            </div>
    
            <div style="width: 135px; display: inline-block;">
                {^{if (AssetType.indexOf('CAM') > -1)}}<i class="fa fa-video-camera"></i>&nbsp;{{/if}}
                {^{if (AssetType.indexOf('VEH') > -1)}}<i class="fa fa-truck"></i>&nbsp;{{/if}}
                {^{:Registration}}
            </div>
            {^{if (Camera_SDCardError)}}<i class="fa fa-wrench faa-wrench animated" style="color: #CE1717;" data-link="rid{:AssetID}" onclick="SDCardErrorClicked(this);" title="Camera Error">&nbsp;</i>{{/if}}
            {^{if (Camera_PanicEvent)}}<i class="fa fa-warning faa-flash animated" style="color: #CE1717;" data-link="rid{:AssetID}" onclick="PanicEventClicked(this);" title="Panic Alert">&nbsp;</i>{{/if}}
            {^{:FriendlyNameShort}}<br />
    
            <div style="width: 135px; display: inline-block;">
                {^{if TachoWorkState.length > 0}}<img data-link="src{:TachoWorkState}title{:TachoWorkStateDesc}" />{{/if}}
                {^{if (TachoDriverNameShort != null && TachoDriverNameShort.length > 0 && TachoDriverNameShort.indexOf('[') > -1)}}<span data-link="title{:TachoDriverName}id{:TachoDriverName}" style="font-weight: normal;" onclick="UpdateDriverTagFromAssetList(this.id);">{^{:TachoDriverNameShort}}</span>{{/if}}
                {^{if (TachoDriverNameShort != null && TachoDriverNameShort.length > 0 && TachoDriverNameShort.indexOf('[') <= -1)}}<span data-link="title{:TachoDriverName}" style="font-weight: normal;">{^{:TachoDriverNameShort}}</span>{{/if}}
            </div>
    
            {^{if (AssetType == 'VEH' || AssetType == 'CAMVEH' || AssetType == 'NCM')}}
            {^{if (IsXIdle)}}<img src="images/list_icons/xidle.png" alt="XIdle" title="XIdle" />
            {^{else (IsIdle)}}<img src="images/list_icons/iddle.png" alt="Idle" title="Idle" />
            {^{else (IsInJourney)}}<img src="images/list_icons/driving.gif" alt="In Journey" title="In Journey" />
            {^{else}}<img src="images/list_icons/parking.png" alt="Parked" title="Parked" />{{/if}}
            {{/if}}
            {^{if (IsInJourney && Speed > 0)}}
                Spd: <strong>{^{if (RoadMaxSpeed != null && RoadMaxSpeed > 1 && Speed > RoadMaxSpeed)}}<span style="color: red;">{^{:SpeedRounded}} {^{:Units}}</span>{{else}}{^{:SpeedRounded}} {^{:Units}}{{/if}}</strong>
            {{/if}}
        </div>
        <div data-link="class{:IsBodyVisible?'asset-body':'asset-body ai-hidden'}">
            <div style="display: table;">
                <div class="asset-body-left">
                    {^{if (headingInsteadOfAssetIcon)}}<img data-link="src{:AssetIcon}" style="width: 24px;" />
                    {^{else}}<img data-link="src{:AssetIcon}" style="width: 36px;" />{{/if}}
                    {^{if (IsInJourney && RoadMaxSpeed != null && RoadMaxSpeed > 1)}}<br />
                    <span style="margin-top: 2px; display: inline-block; background-image: url('images/RoadMaxSpeed.png'); background-repeat: no-repeat; width: 24px; height: 24px; font-weight: bold; font-size: 10px; text-align: center; vertical-align: middle; padding-top: 5px;">{^{:RoadMaxSpeed}}</span>{{/if}}
                </div>
                <div class="asset-body-right">
                    {^{if (IsInJourney)}}<img data-link="src{:HeadingImage}" />&nbsp;{{/if}}&nbsp;{^{:LastUpdateString}}<br />
                    {^{:Location}}
                    <br />
                    {^{if (Latitude == 0 && Longitude == 0 && LatitudeValid != 0 && LongitudeValid != 0)}}
                    <a style="cursor: pointer;" onclick="colorMeValid(this);" data-link="rid{:AssetID}"><i class="fa fa-map-marker fa-2x"></i></a>
                    {{/if}}
                    {^{if (FuelLevel > 0.01)}}<i class="zmdi zmdi-local-gas-station" title="Fuel Level"></i>: {^{:FuelLevel}} %{{/if}}
                    {^{if (OdometerRounded > 0)}}{^{if (FuelLevel > 0.01)}}&nbsp;{{/if}}<i class="fa fa-tachometer" title="Odometer"></i>: {^{:OdometerRounded}} {^{:OdometerDistance}}{{/if}}
                    {^{if (AssetType == 'VEH' || AssetType == 'CAMVEH' || AssetType == 'NCM')}}
                    <div style="font-size: 140%;">
                        <i class="zmdi zmdi-my-location" data-link="rid{:AssetID}" onclick="GPSJReportClicked(this);" title="Journey Report"></i>&nbsp;
                        <i class="icon icon-proximity" data-link="rid{:AssetID}" onclick="ProximityAssetClicked(this);" title="Proximity"></i>
                        <i class="fa fa-globe" data-link="rid{:AssetID}" onclick="TodaysMapPlotClicked(this);" title="Today's journeys"></i>
                    </div>
                    {{/if}}
                </div>
            </div>
            <div onclick="toggleDetail(this);" class="asset-detail-toggle">
                {^{if IsDetailVisible}}
                <i class="zmdi zmdi-upload zmdi-hc-2x"></i>
                {{else}}
                <i class="zmdi zmdi-download zmdi-hc-2x"></i>
                {{/if}}
            </div>
        </div>
        <div data-link="class{:IsDetailVisible?'row asset-detail':'row asset-detail ai-hidden'}">
            <img src="images/loader-01.gif" style="margin-left: 100px;" />
        </div>
    </div>
    {{/for}}
    </script>
    
    opened by hoshoo21 15
  • Precompile jsrender templates to avoid unsafe-eval

    Precompile jsrender templates to avoid unsafe-eval

    For implementing our Content Security Policy I would like to avoid any code that uses eval() or new Function, so that I don't have to add unsafe-eval to the CSP. However, JsRender uses new Function to compile templates.

    Is there a way to avoid this or work around it? Is it on the JsRender roadmap?

    Note: I was thinking of solving this by precompiling our templates on the server (something like http://handlebarsjs.com/precompilation.html), so that I only need to render on the client. When I examine the code, it looks like I could make it work by serializing the compiled template (i.e., the result of calling compileTmpl), including all its subtemplates, to a JSON-string on the server, putting that in a <script> tag and then use that to render.

    One of the issues I'm running into with this approach, is that the compiled templates also contain a reference to a render function, which is internal to JsRender. I would have to expose it to be able to use it on the client, I think.

    Feature request After V1? 
    opened by robbertbrak 14
  • How to deal with JsRender error exceptions during server-side compiling or rendering?

    How to deal with JsRender error exceptions during server-side compiling or rendering?

    Hi, I have the following structure (forget the twig extension, its left from my nunjucks tests):

                var appData ={};
                res.render('layout', appData, function(err, html) {
                   res.send(html);
                });
    
    test
    
    {{include tmpl='./_includes/footer.html'}} 
    //if i remove the import, the template get rendered and shows 'test'
    
    

    I get no errors , just a white page.

    How to apply this on the server :

            $.views.settings.debugMode(true);
    

    Is this correct :

    jsrender.views.settings.debugMode(true)
    

    Whats missing please?

    opened by daslicht 14
  • Safari 6.0 Error - Type Issue: Attempted To Assign To Readonly Value

    Safari 6.0 Error - Type Issue: Attempted To Assign To Readonly Value

    Hi,

    I am getting an error with jsrender when I try to render a template. The error occurs in the "theStore" function on line "if(item){ item._is = storeName; }" line number 811. I am not sure what is causing this error because I use jsrender on almost every page of my website and it does not cause an error. It actually renders two templates before it says it cannot assign to a readonly value (item._is = storeName). Any help on this situation would be much appreciated. It works perfectly on safari 5.1 and all other modern browsers.

    Chris

    Bug Resolved 
    opened by ChrisHB 14
  • Create a NuGet package

    Create a NuGet package

    I would create a NuGet package build utility for this project if you would accept a pull request for it and publish to NuGet.

    The publish to NuGet process would be simple each time a release is made. 0) potentially update nuspec description field (not required each build)

    1. run release.cmd
    2. login to http://NuGet.org/
    3. upload the generated nupkg file.

    Here is a project showing what that addition would look like:

    https://github.com/michael-lang/jquery-auto-async

    files: Release.cmd .nuget** (2 config files, 1 exe - from Nuget.org) NuGet\jsrender.nuspec Build** (various standard build support files, 5 text, 1 dll; Nothing custom to project)

    Note, I am updating the jquery-auto-async project to use jsRender.

    After V1? 
    opened by michael-lang 12
Releases(v1.0.12)
A super-lightweight, highly configurable, cross-browser date / time picker jQuery plugin

Zebra Datepicker A super-lightweight, highly configurable, cross-browser date/time picker jQuery plugin Zebra_Datepicker is a small yet and highly con

Stefan Gabos 391 Dec 29, 2022
Tiny and powerful JavaScript full-text search engine for browser and Node

MiniSearch MiniSearch is a tiny but powerful in-memory fulltext search engine written in JavaScript. It is respectful of resources, and it can comfort

Luca Ongaro 2k Jan 3, 2023
A powerful, extensible, customizable & rapidly develop hacking framework.

YourN3xt(Beta) A powerful, extensible, customizable & rapidly develop hacking framework. Installations Github: https://github.com/OTAKKATO/YourN3xt N

OTAK 4 Nov 21, 2022
Open, extensible, small and simple behaviour-graph execution engine

Behave-Graph Behave-Graph is a standalone library that implements the concept of "behavior graphs" as a portable TypeScript library with no external r

Ben Houston 167 Dec 29, 2022
Pintora is an extensible javascript text-to-diagrams library that works in both browser and Node.js.

Pintora Documentation | Live Editor Pintora is an extensible javascript text-to-diagrams library that works in both browser and Node.js. Expressing yo

hikerpig 652 Dec 30, 2022
Type Identity - a powerful and highly customizable authentication and authrozation and access-control framework

Type Identity is a powerful and highly customizable authentication and authrozation and access-control framework. It is the de-facto standard for securing Type Script api beta release

Saeed Mohammed Al-abidi 2 Jan 1, 2023
UAParser.js - Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment.

UAParser.js JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data with relatively small footprint (~17KB m

Faisal Salman 7.4k Jan 4, 2023
Calculating Pi number without limitation until 10k digits or more in your browser powered by JS without any third party library!

PI Calculator Web JS (Online) Calculating Pi number without limitation until 10k digits or more in your browser powered by JS without any third party

Max Base 6 Jul 27, 2022
Node WebStation is a powerful tool designed for developers allowing them to create advanced web sockets for any use all without having the requirement to code.

Node WebStation Node WebStation is a powerful tool designed for developers to use to create an advanced WebStation for any use all without not having

null 2 Jun 4, 2022
A simple Node.js code to get unlimited instagram public pictures by every user without api, without credentials.

Instagram Without APIs Instagram Scraping in August 2022, no credentials required This is a Node.js library, are you looking for the same in PHP? go t

Francesco Orsi 28 Dec 29, 2022
The project integrates workflow engine, report engine and organization authority management background, which can be applied to the development of OA, HR, CRM, PM and other systems. With tlv8 IDE, business system development, testing and deployment can be realized quickly.

介绍 项目集成了工作流引擎、报表引擎和组织机构权限管理后台,可以应用于OA、HR、CRM、PM等系统开发。配合使用tlv8 ide可以快速实现业务系统开发、测试、部署。 后台采用Spring MVC架构简单方便,前端使用流行的layui界面美观大方。 采用组件开发技术,提高系统的灵活性和可扩展性;采

Qian Chen 38 Dec 27, 2022
Highly customizable checkboxes and radio buttons (jQuery & Zepto)

iCheck plugin 1.0.3 Highly customizable checkboxes and radio buttons for jQuery and Zepto. Refer to the iCheck website for examples. Note: iCheck v2.0

Dar Gullin 7.4k Dec 25, 2022
Highly customizable checkboxes and radio buttons (jQuery & Zepto)

iCheck plugin 1.0.3 Highly customizable checkboxes and radio buttons for jQuery and Zepto. Refer to the iCheck website for examples. Note: iCheck v2.0

Dar Gullin 7.5k Aug 24, 2022
jQuery easy ticker is a news ticker like plugin, which scrolls the list infinitely. It is highly customizable, flexible with lot of features and works in all browsers.

jQuery Easy Ticker plugin jQuery easy ticker is a news ticker like plugin which scrolls a list infinitely. It is highly customizable, flexible with lo

Aakash Chakravarthy 208 Dec 20, 2022
CSS is powerful, you can do a lot of things without JS.

You Don't Need JavaScript Please note these demos should be considered as CSS "Proofs of Concepts". They may have serious issues from accessibility po

You Don't Need 17.9k Jan 4, 2023
A lightweight extension to automatically detect and provide verbose warnings for embedded iframe elements in order to protect against Browser-In-The-Browser (BITB) attacks.

Enhanced iFrame Protection - Browser Extension Enhanced iFrame Protection (EIP) is a lightweight extension to automatically detect and provide verbose

odacavo 16 Dec 24, 2022
⚡️ Fast, lightweight and powerful development server for esbuild ⚡️

esbuild-server ⚡️ Fast, lightweight and powerful development server for esbuild ⚡️ Zero dependencies besides esbuild API proxy support Live reload SPA

Joel Arvidsson 22 Sep 14, 2022
An extensible HTML DOM window manager with a professional look and feel

Wingman An extensible HTML DOM window manager with a professional look and feel. Installation Wingman only requires two files: wingman.css and wingman

nethe550 1 Jan 21, 2022
Lexical is an extensible JavaScript web text-editor framework with an emphasis on reliability, accessibility and performance

Lexical is an extensible JavaScript web text-editor framework with an emphasis on reliability, accessibility and performance. Lexical aims to provide a best-in-class developer experience, so you can easily prototype and build features with confidence.

Meta 12.7k Dec 30, 2022