BorisMoore / jsrender

A lightweight, powerful and highly extensible templating engine. In the browser or on Node.js, with or without jQuery.
http://www.jsviews.com
MIT License
2.68k stars 340 forks source link

Browser does not respect template markup #301

Closed ba1dr closed 8 years ago

ba1dr commented 8 years ago

See https://jsfiddle.net/8vfesbgf/1/

<div id="alltemplates" class="hidden">
<code id="tpl_fieldtype">
    <div class="form-group">
        <label>{{:fieldname}}</label>
        <select class="fieldtype form-control" data-name="{{:fieldname}}">
            {{for allfieldtypes}}
            <option value="{{:ftype}}" {{ if ftype == fieldtype }}selected{{/if}}>{{:ftype}}</option>
            {{/for}}
        </select>
    </div>
</code>
</div>

See 3 commented blocks in the fiddle - nothing of these returns correct content. It seems browser does not process this block as is. I see it as:

 {{for allfieldtypes}}
    <option if}}="" }}selected{{="" fieldtype="" ftype="=" if="" {{="" value="{{:ftype}}">{{:ftype}} </option>
{{/for}} 

How do I render this template?

Ubuntu 15.10: Firefox 46.0.1 / Chromium 50.0.2661.102

grma1 commented 8 years ago

You need to call .render with the data you need on the template.

fielddesc_tpl = $.templates('#tpl_fieldtype');

var tpl_data = {
  fieldname: 'test',
  allfieldtypes: [
    {ftype: 'ft1'},
    {ftype: 'ft2'},
    {ftype: 'ft3'},
    {ftype: 'ft4'}
  ]
}

console.log(fielddesc_tpl.render(tpl_data));

Kind regards.

ba1dr commented 8 years ago

Really? Have you ever tried to do this in jsfiddle? I get these lines:

                <option value="ft1" {{="" if="" ftype="=" fieldtype="" }}selected{{="" if}}="">ft1</option>
gtwilliams03 commented 8 years ago

I would start by removing the space between the {{ and "if" in your template so that the "if" is immediately adjacent to the curly brackets (i.e., {{if x == y}}{{:ftype}}{{/if}}). The browser is converting your "if" to property of a tag if=""

grma1 commented 8 years ago

the main problem was, that the code block is parsed by the html engine.

try the following:

<div id="alltemplates" class="hidden">
    <script type="text/x-jsrender" id="tpl_fieldtype">
        <div class="form-group">
            <label>{{:fieldname}}</label>
            <select class="fieldtype form-control" data-name="{{:fieldname}}">
                {{for allfieldtypes}}
                <option value="{{:ftype}}" {{if ftype === fieldtype}}selected{{/if}}>{{:ftype}}</option>
                {{/for}}
            </select>
        </div>
    </script>
</div>
Paul-Martin commented 8 years ago

If you are doing this in a browser then your template should be in a script tag. And then you need to call render and insert the resulting string in to the dom.

JSRender does not somehow make the browser dom understand it's {{tag}} notation. You place the template in script tag so that the browser will ignore it. Then you use javascript to render the template and insert it into the dom where you would like.

var model = { hello: 'world' };

var rendered = $.template('#helloworld').render(model);

$('body').html(rendered);

On May 27, 2016, at 11:55 AM, Alexey Kolyanov notifications@github.com wrote:

Really? Have you ever tried to do this in jsfiddle? I get these lines:

            <option value="ft1" {{="" if="" ftype="=" fieldtype="" }}selected{{="" if}}="">ft1</option>

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

ba1dr commented 8 years ago

Thanks everybody! The issue is solved, in fact I used <code> instead of <script> tag.. Isn't html became too complex? :) The note about <script> tag should be mentioned in RED BOLD FONT on each page.

BorisMoore commented 8 years ago

Thanks all, for the explanations...

The information about script blocks is in a few places in the docs: http://www.jsviews.com/#search?s=script%20block. (@ba1dr - I'm not sure which topics you had seen).