Neilski
Neilski

Reputation: 4415

Including a template in JsRender

I am using JsRender to construct my HTML page and I would like to be able to achieve the following.

<script id="qtype" type="text/x-jsrender">
   <li class="question-container" data-type="{{:Question.Type}}">
       {{include tmpl="#inner-template"/}}
   </li>
</script>

What I would like to be able to do is to base the inner template inclusion upon some property within the model being rendered. For example, if my model has a property named 'Type' the following, whilst invalid synax, explains the requirement (hopefully)

{{include tmpl=:"#" + Question.Type}}

or, perhaps, using a 'helper' method:

{{include tmpl=~GetTemplateName(Question.Type)}}

I have tried adding the template name to the model, but I couldn't get that to work for the include statement:

{{include tmpl=templateName/}}

Can anyone tell me if this is possible, or perhaps an alternative suggestion?

Thanks.

Upvotes: 0

Views: 1586

Answers (2)

Neilski
Neilski

Reputation: 4415

Build update 27 appears to address my problem. The {{include}} statement has been modified so that I can now define the template name as part of the model and then use the following script.

<script id="qtype" type="text/x-jsrender">
    <li class="question-container" data-type="{{:Question.Type}}">
        {{include tmpl="#templateId" /}}
    </li>
</script>

A more complete discussion can be found at https://github.com/BorisMoore/jsrender/issues/155

Upvotes: 0

Stephen Collins
Stephen Collins

Reputation: 3653

I've been using the most recent builds and this approach works juse fine:

For inline templates:

// given an inline template named 'myTmpl'
{{for myModel.someProperty tmpl="#myTmpl" /}}

For compiled templates:

// given a compiles template named 'myTmpl'
{{for myModel.someProperty tmpl="myTmpl" /}}

I think what you are missing in your code is the quotes. Whether it is a compile template or inline template you still need them. I'm not sure if the "include" keyword is still supported, but using a {{for /}} works just fine whether the model passed into it is an array or not. The thing is, jsRender treats everything you pass into it as an array, but only renders it once if it contains only one value.

Also, ensure that you are compiling your templates correctly. I used a utility function to compile all of them beforehand:

function () {
    return $.when(
        $.get(getPath("templateOne")),
        $.get(getPath("templateTwo"))
    )
    .done(function (one, two) {
        $.templates({
            tmplOne: one[0],
            tmplTwo: one[0]
        });
    });
}

This creates two compile templates with the names "tmplOne" and "tmplTwo" which you can use in your other templates.

One thig to note, however is that compilation takes time. If you try to use a template before it is compiled, jsRender won't know about it yet and have some really strange behavior. Hence returning a Promise to ensure that I don't use a template before it is compiled:

compileTemplates().done(function() {
    // do my work with compile templates here.
}).fail(function() {  /* handle failure */ });

Upvotes: 2

Related Questions