Coder Social home page Coder Social logo

borismoore / jsrender Goto Github PK

View Code? Open in Web Editor NEW
2.7K 2.7K 342.0 7.69 MB

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

Home Page: http://www.jsviews.com

License: MIT License

HTML 0.44% CSS 0.01% JavaScript 98.80% TypeScript 0.75%

jsrender's People

Contributors

abdulhannanali avatar alexstory avatar borismoore avatar orthographic-pedant avatar tiesont avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsrender's Issues

nested templates without a specified data object

In jQuery templates, one could call a nested template without specifying a data object (example: {{tmpl '#myTemplate'}}), which was useful. In jsrender, this does not appear to work and fails with the error 'current is undefined'. I've seen this in two places:

  1. A plain template call: {{tmpl='#myTemplate'}}
  2. In an {{else}} tag. In your 'helper functions' demo, you show an example of calling a nested template from an {{if}} tag (line 19 and 22), which is cool. Unfortunately, doing this with an {{else}} tag (equivalent of 'elseif') gives the 'current is undefined' error.

Thanks for all your great work, Boris!

Documentation

If this is supposed to be a serious replaced for jQuery templates then you need real documentation and not just a set of examples for me to make wild guesses about

Using appendTo vs. html

I usually list the field names in the table and then fill the table using jquery templates. With jsrender the appendTo doesn't seem to be working. Maybe I'm going about it wrong?

This works but removes my table header row:
$("#tblMostActiveUsers").html($("#MostActiveUsersTemplate").render(data.d));

This doesn't work in jsrender:

$("#tblMostActiveUsers").appendTo($("#MostActiveUsersTemplate").render(data.d));

Thanks for any help!
Craig

activeViews with <col> fails without <colgroup>

If creating a table template with <col> tags without <colgroup>, the browser will force to add a <colgroup> around <col>.

The active view comments get messed up causing a JavaScript error, not able to find the correct data for the template.


<table>
{{each columns tmpl=templateCol}}

</table>

templateCol is:
<col />

The output on the page is:
<!--tmpl() _0-->
<table>
<!--tmpl($data.columns) _1-->
<!--item-->
<colgroup>
<col>
<!--/item-->
<!--item-->
<col>
<!--/item-->
<!--/tmpl-->
</colgroup>
</table>
<!--/tmpl-->

How to access $value with new syntax

In jQuery templates, I could use $value to get the value of an item in a list, for example. I can't manage to figure out how to do that with the jsRender templates.

For example, given this list:
['dogs', 'cats', 'monkeys']

and this template:

<script id="log-tags-tmpl" type="text/x-jquery-tmpl">
  • {{=$value }}
  • </script>

    What should go instead of {{=$value }}?

    I've looked through the demos but don't think I saw an example using a flat list. Thanks!

    Demo for dynamic tempaltes

    I have an ajax request that fetches the templates along with the data...

    response{
    templates{...},
    data{....}
    }

    in your demos there are already predfined templates in a script element.. can you make a demo example with templates loaded from an external json file or at least from a js string variable?

    $.views is undefined

    Sorry I can't provide code to back this issue... I was testing with an ajax call which returned an object that was preprocessed and then passed to render... This problem appeared (under FF7)... The template was OK, as well as the variables... Do you know if there are known bugs where this can happen?

    common js compliant lib

    I was wondering if it would be possible to make a common js compliant jsrender.js file (something that doesn't use window.views or whatnot outside of the main method).

    I have a small wrapper I wrote around jsrender for nodejs:
    https://github.com/shtylman/node-jsrender

    and it would make bringing in jsrender code changes much easier :)

    (If you accept patches for this I would be happy to provide one).

    optionally remove formatting

    Hello,

    I am working on a fork / port for jsrender for nodejs. Would it be possible to bake in support in option form for maintaining whitespace formatting for the scripts output?

    Thanks

    Question on Numbers

    HI Boris,

    BTW Very cool library:

    If I had data like { name:"just_dog", age:7 }

    How could age (as a number) be used in a template:

    Age: {{=age}}

    All the best
    Chris

    Template is not rendered for null value in array

    I have many templates like this:

    <script id="stats-table-foodtypes-data-tmpl" type="text/x-jquery-tmpl">
    {{#each dates}}
      {{#if data}}
       {{=$data}}
      {{else}}
        ?
      {{/if}}
    {{/each}}
    </script>
    

    They expect an array of values, and they render one thing if the value is there and another thing if it is not. This worked in jQuery templates, but in jsRender, it appears that it does not call the template code at all for a null value. Is this the expected behavior?

    On < IE9 rendering engines, SCRIPT1010: Expected identifier, jquery.render.js, line 341 character 2

    Trying to render the following on IE9 in IE8, IE7 rendering modes:

        <script id="tableChangeLog_template" type="text/x-jquery-tmpl"> 
            <div class="logrow logheader">
                <div class="logcell">Time</div>
                <div class="logcell">User</div>
                <div class="logcell">Action</div>
                <div class="logcell">Old Value</div>
                <div class="logcell">New Value</div>
                <div class="logcell">Change Reason</div>
            </div>
            {{each($index, line) data}}
            <div class="logrow">
                <div class="logcell logdate">{{= line.time}}</div>
                <div class="logcell">{{= line.user}}</div>
                <div class="logcell">{{if line.action.indexOf("&shy;") == -1}}{{= line.action}}{{else}}{{html line.action}}{{/if}}</div>
                <div class="logcell">{{if line.old.indexOf("&shy;") == -1}}{{= line.old}}{{else}}{{html line.old}}{{/if}}</div>
                <div class="logcell">{{if line.new.indexOf("&shy;") == -1}}{{= line.new}}{{else}}{{html line.new}}{{/if}}</div>
                <div class="logcell">{{if line.reason.indexOf("&shy;") == -1}}{{= line.reason}}{{else}}{{html line.reason}}{{/if}}</div>
            </div>
            {{/each}}
        </script>
    

    Calling as such:

            $('#tableChangeLog_anchor').html(
                $('#tableChangeLog_template').render(my_data)
            )
    

    Yields the following error in the console:

    SCRIPT1010: Expected identifier
    jquery.render.js, line 341 character 2

    Tested against code circa Sept 13, commit c6daa48

    Same rendering engine renders other (simpler, a few string replacements and simple each loop) templates just fine on the same page. Just blows up on the above template.

    Small syntax errors

    Been giving this a little try and found 2 small syntax errors:

    Changed:
    tmpl = buildTmplFn(tmpl)
    
    To:
    tmpl = buildTmplFn(tmpl);
    
    And:
    content = self.tmpl($, self);
    
    To:
    var content = self.tmpl($, self);
    

    Will come back for some question, tho now i gotta get back to work :)

    Robert

    Carriage return char not escaped in Internet Explorer

    I had an issue where a carriage return character was finding its way into the parsed template and in Internet Explorer I'd get an error at line 545 complaining of an unterminated string which on inspection turned out to be a " followed by an unescaped \r.

    My workaround was chnaging line 406 to the following:

    content.push( markup.substr( loc, shift ).replace( rNewLine,"\n").replace("\r", "\n"));

    Unfortunately I haven't had time to replicate this small-scale yet but I'm posting an issue in case it's something obvious that you can fix.

    Error: Unterminated string constant in IE7

    Hi Boris,

    When I run the current version of JSRender's 01_inserting-data.html page I get an Error: Unterminated string constant exception due to newlines in the generated function javascript. I fixed it by changing the end of the buildTmplFunction function to

    try {
        ret = new Function("$data, $view", (code.slice(0, -1) + ";return result;\n\n}catch(e){return views.err(e);}").replace(/\n|\r/g, " "));
    } catch(e) {
    

    ...but this might not be the best way to fix it!

    Cheers

    Jason

    Why not just a single notation {{... and with /}} for no block tag

    Right now, {{#... is for block tags, and {{... is for not block tag, but why not having just one notation {{... and when there is no content, we just end it with /}}.

    I think that this notation would be more familiar to developers (as it is similar to xml), and will simplify the notation.

    rendering takes ages under Chrome with big List

    I tested the rendering in IE7-9 and from a few hundreds rows until a few thousand, it goes extremly fast, even in IE7. In Firefox, it's ok but it takes more time, specially the difference between IE and firefox grows when the data are bigger and bigger, but well it's still acceptable.
    But in Chrome, it takes 2-3 seconds by 1000 lines, 10-15 by 2000 rows and almost 1 minute by 3000 while it takes at most one second for IE7 for exactly the same data. I guess there is somewhere something wrong.

    ignore CDATA

    in order to avoid validation conflicts i use a CDATA section, see example below:

      <![CDATA[
      /\* template goes here */
      ]]>
    </style>
    
    

    when compiling the template, the markup needs cleaning:

      markup = markup.replace(/\]\]>/, "" );
    

    access iteration index

    it would be nice to have access from within a template to the current iteration index, e.g. {{=$ctx.index}}

    some use cases:

    • output a numbered data list
    • limit to the top 10
    • enable pagination for data tables (only show entries from 1-3, 4-6, etc.)

    the index could always be stored in the data before hand, but there should not be a correlation between display position and data, e.g. a filtered data table, whose first result may not be the first data entry.

    Unterminated string constant in IE8

    It looks like the latest version causes an error in IE8 resulting in the following error: "Unterminated string constant." The error seems to occur in the function buildTmplFunction at this line:

       try {
                ret = new Function("$data, $view", code.slice(0, -1) + ";return result;\n\n}catch(e){return views.err(e);}");
            } catch (e) {
                ret = function () {
                    return viewsNs.err(e);
                };
            }

    This error is visible in all the demos.

    Thanks!

    object['key'] syntax in templates

    I have to deal with a key with a period in the name ("Scope.Name") and it would be great to access it within a template like this.

    Attributes["Scope.Name"].value 
    

    in the meantime i'm using this to get the job done.

    {{#each Assets}}
        {{* var $row = $view.parent.data[$view.itemNumber-1]; }}
            <li>{{=$itemNumber}}</li>
            <li>{{=Attributes.Name.value}}</li>
            <li>{{* result += $row.Attributes["Scope.Name"].value; }}</li>  
    {{/each}}
    

    Rendering Templates Inside of Templates

    Unless I have overlooked it, I have not seen an example of how to render a template inside of another template. Would it require the creation of a new tag?

    Calling functions within Template

    I'm switching from jquery templates and have it almost working.

    I'm currently getting this error:

    Error: $data.formatScheduleDateTime is not a function.

    Here is my code:

    {{=dateFormat(formatScheduleDateTime(DatePublished), 'dddd, mmmm dS, yyyy, h:MM TT') }}

    Is there something special I need to do to call the function? i know the function exists.

    Thanks,
    Craig

    Error when nesting #each

    A common use is nesting two or more #each.
    I you have a JSON like

    
    {
        "name": "m-form",
        "id": "m-form",
        "action": "",
        "method": "post",
        "elements": [{
            "type": "div",
            "class": "m-form-div-email",
            "elements": [{
                "type": "label",
                "for": "m-form-mail",
                "html": "E-mail"
            }, {
                "name": "mail",
                "id": "m-form-mail",
                "type": "text"
            }]
        }, {
            "type": "div",
            "class": "m-form-div-country",
            "elements": [{
                "type": "label",
                "for": "m-form-country",
                "html": "País"
            }, {
                "type": "select",
                "id": "m-form-country",
                "name": "country",
                "options": {
                    "US": "USA",
                    "ES": {
                        "selected": "true",
                        "value": "ES",
                        "html": "Spain"
                    },
                    "FR": "France",
                    "PT": "Portugal",
                    "UK": "United Kingdom"
                }
            }]
       }]
    }
    
    

    And have the following templates,
    formTemplate:

    
    <script id="formTemplate" type="text/x-jquery-tmpl">
    
        

    Lorem ipsum

    {{#each elements tmpl="#elementTemplate"}} </script>


    elementTemplate:

    
    <script id="elementTemplate" type="text/x-jquery-tmpl">
    {{#if type == 'div'}}
        
    my div {{#each elements tmpl="#inputTemplate"}}
    {{/if}} </script>


    inputTemplate:

    
    <script id="inputTemplate" type="text/x-jquery-tmpl">
    {{#if type == 'label'}}
    {{=html}}
    {{/if}}
    </script>
    

    The result should be a:

    FORM
        DIV
            ...elements
        DIV
            ...elements
    

    But instead I get nested elements as:

    FORM
        DIV
            ...elements
            DIV
                ...elements
    

    Hope I'm clear and you can fix it.

    Do a check for old versions of jquery templates

    A small thing but I spent an hour trying to figure out why JSRender was not working for me. It was because I was still loading Jquery Templates in the page. Might want to spit out a console error if JSRender is called when JQuery templates also exists.

    Suggestion: More intuitive syntax for simple if comparisons

    The syntax for implementing simple comparisons is overly complex and I think there should be simpler method for adding simple comparisons to your template code.

    For example, in jquery.tmpl, you could do:

    <div class="base{{if varName == 'None'}} none{{/if}}">${varName}</div>
    

    However, this simple comparison is much more difficult in the new engine. First, you've got to set:

    $.views.allowCode = true;
    

    And then your template ends up looking something like this:

    <div class="base{{* if($view.data.varName == 'None'){ result += ' none';  } }}">{{=varName}}</div>
    

    This is quite a bit more complicated to implement and much more difficult to interpret.

    Any chance of being able to implement something like:

    <div class="base{{#if equals(varName, 'None')}} none{{/if}}">{{=varName}}</div>
    

    Where we have some functional helpers like equals(), not(), gt(), lt(), gte(), lte()--and with the potential to define more helper functions.

    I can understand dropping to code view for more complex operations, but it seems like there should be a way to at least perform some simple comparisons w/out having to drop to the overly complex code syntax.

    Looping through Key-value pairs

    I have an object like this:

    "GoodStuff": {
    1: "Chimay",
    2: "Orval"
    3: "Westmalle"
    }

    I would expect that if I say ...
    {{#each GoodStuff}}

  • Beer {{=$itemNumber}}

  • {{/each}}
    ... it shows me 3 items, but it only shows 1 single item.

    I created a workaround by changing the object to
    "GoodStuff": [
    {
    "Key": 1,
    "Value": "Chimay"
    },
    {
    "Key": 2,
    "Value": "Orval"
    },
    {
    "Key": 3,
    "Value": "Westmalle"
    }
    ]

    Thanks for your work, really love working with the project!

    newly rendered input:submit button in form does not fire submit in Google Chrome

    I guess this is chrome issue, but worth to mention here.

    I had situation when rendered template replaced content in of whole form element content, including initial input:submit button, which caused form not submiting to server regular (without giving it hand with additional javascript code) form submit was not mention to be ajaxified, just plain old HTTP post.

    Issue only occurs in Google Chrome, Firefox is not suffering from it.

    Current workaround is to attach event handler like:

    $("form").on("click", "input:submit", function(){ this.form.submit(); });

    expression eval's missing and/or

    Boris,
    I'm not sure it's an issue rather than a request... :)

    Nevertheless, it would be nice to be able to do a
    {{#if varOne==1 && varTwo==2 }}

    and Merry Xmas ! ;)

    No way of rendering enumerated objects

    Sometimes you get an JSON object like this (copied from firebug):

    link [Object { title="Inicio", url=""}, Object { title="Ciudad", url="ciudad.php", sublink=[11]}, Object { title="Tramites", url="#"}, 3
    0 Object { title="Inicio", url=""}
    1 Object { title="Ciudad", url="ciudad.php", sublink=[11]}
    2 Object { title="Tramites", url="#"}
    3 Object { title="Noticias", url="#"}
    4 Object { title="Calendario", url="#"}
    5 Object { title="Sobre Nosotros", url="#"}

    Where you get an index for an object instead of the object itself. In order to access the properties of the object, you need to reference this index.

    I dont know if there is a way to get the length of the object and iterate it.

    What are your comments.

    no value when variable undefined

    Is there a way to use a variable with {{=my_var}} and have it not print anything when that variable in undefined?

    I am trying to do something like:
    <input name="form_field" type="text" value={{=previous}} />

    And the page is showing "undefined" as the value. I would prefer to not see any text.

    Possibly settle on a different script type in examples?

    I'm just throwing this thought out there as a suggestion because I feel a little weird still using the script type x-jquery-tmpl as seen in the examples.

    jsrender's syntax is different than jquery-tmpl. Also, there is no jQuery dependency.

    text/x-jsrender?

    Clarify license

    jquery-tmpl was dual-licensed via the MIT and GPL2 licenses. I'm guessing that your code is also, but I think it would be good to clarify this point. Will you add a license to the code?

    Consider adding templateLoaded event

    I have found when working with jquery templates that there are a number of things that need to be bound after the template is rendered, for example click events or loading masks/watermarks on inputs. My solution to this was to wrap the template load call in a function which inserts the template name as an attribute to target DOM element and pass the original arguments, then use .live() to wire these behaviors if the template and event appears. For example:

    $("[template*=#navigation]").live("template_loaded", function(e,templateName) {  }
    

    Is there an existing/different way to do this sort of behavior binding after template load that i may have missed? is firing some events off that we can subscribe to something you could consider in the future.

    slashes url encoded

    <img src="{{if photo}}${photo}{{else}}/media/no_photo.png{{/if}}" class="photo" alt="${slashes_title}" />

    not working... getting

    <img alt="Soraya" class="photo" src="%7B%7Bif%20photo%7D%7D$%7Bhtml%20photo%7D%7B%7Belse%7D%7D/media/no_photo.png%7B%7B/if%7D%7D">

    $.template returns an object instead of a function

    Everything works perfectly on the main page, but when I browse the contact page the plugin does not work:

    Error message in console (contact page):

    Uncaught TypeError: object is not a function
    jquery.tmpl.js:329

    Uncaught Template command not found: getDay
    js:2000

    The tag is registered! I have nothing unusual about the contact page (no javascript nothing but jsrender)

    See images: http://imgur.com/a/LwXDn#0

    See the complete question: http://stackoverflow.com/questions/8084036/template-returns-an-object-instead-of-a-function

    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.

    jsrender.js overrides $ (incompatible with Zepto)

    I'm porting away from jQuery to Zepto.js, so I was happy to see that jsrender is a non-jQuery dependent version of jQuery templates. However, it overrides $ if jQuery isn't present, which means it overrides Zepto's use of $. I think I've resolved this for now by adding this to jsrender.js:
    if (Zepto) {

    $ = Zepto;
    $.isArray = Array.isArray || function( obj ) {
            return Object.prototype.toString.call( obj ) === "[object Array]";
    };
    $.noConflict = function() {
            if ( window.$ === JsViews ) {
                window.$ = _$;
            }
            return JsViews;
    }
    

    }

    But there's probably a better way - perhaps if it finds something else using $, it could just add to it, not redefine it? Thanks!

    Character entities are escaped

    Hi, given a JSON snippet like:

    [{"title":"Cat 1 &amp; Cat 3 Title 2","body":"<p>Lorem ipsum
    (I escaped the source so it looks correct in preview)

    The ampersand is being escaped so that it is rendered like: &amp;amp; -- Some way to fix in the current build? (just cloned a few minutes ago). On line 244, I see:

        encoders: tmplEncode = {
            "none": function( text ) {
                return text;
            },
            "html": function( text ) {
    

    ...
    How do I trigger "none"?

    The less than and greater than for the p is rendered correctly (i.e. as an open p tag).

    My template looks like:

    <script id="pf-video-teaser-tmpl" type="text/x-jquery-tmpl">
  • {{=program}}

    {{=title}}{{#if length}} {{=length}}{{/if}}

  • </script>

    and I call it like (your sample demos):

    $ul.html($teaser_tmpl.render(videos));

    Array of Data w/o Full Template Duplication

    As demonstrated in Demo 1 (https://github.com/BorisMoore/jsrender/blob/master/demos/step-by-step/01_inserting-data.html), when an array of data is passed to a template that template gets duplicated. Is it possible to simply iterate through the data and only duplicate part of the template?

    Example

    Using Demo 1 as a basis, something like...

    <script id="movieTemplate" type="text/x-jquery-tmpl">
    <ul>
        {{#each}}
        <li>
            {{=$itemNumber}}: <b>{{=Name}}</b> ({{=ReleaseYear}})
        </li>
        {{/each}}
    </ul>
    </script>

    $.views.setDelimiters bug...

    Hi Boris,

    just noticed that if I set the delimiters with 2 different characters, like for example "<%" and "%>", it doesn't work.

    the problem is probably located on line 170-171

        setDelimiters: function( openTag, closeTag ) {
            // Set or modify the delimiter characters for tags: "{{" and "}}"
            var firstCloseChar = closeTag.charAt( 1 ),
                secondCloseChar = closeTag.charAt( 0 );
            openTag = "\\" + openTag.charAt( 0 ) + "\\" + openTag.charAt( 1 );
            closeTag = "\\" + firstCloseChar + "\\" + secondCloseChar;
    

    I presume you wished to type:
    var firstCloseChar = closeTag.charAt( 0 ),
    secondCloseChar = closeTag.charAt( 1 );

    with this little fix, it works.

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. 📊📈🎉

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google ❤️ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.