Search code examples
javascripttemplatingjsrenderjsviews

Wrap around template in jsRender


I am trying to wrap a piece of my template with plain HTML. Or in code:

{{expandable}}
     CONTENT
{{/expandable}}

should turn into:

<div class="expandable closed">
  <div class="header lowercase">
    <img src="/Control/Svg?picture=EdgeBracket_Right" style="height: 35px; position: relative; top: 10px;"/>
  </div> 
  <div class="content">
    CONTENT
  </div>
</div>

Things I tried so far:
Custom tag approach

$.views.tags("expandable", function() {
    return '<div class="expandable closed"><div class="header lowercase"><img src="/Control/Svg?picture=EdgeBracket_Right" style="height: 35px; position: relative; top: 10px;"/>' +
    '</div> <div class="content">' + this.tagCtx.render(content) + '</div></div>';
});

But inside CONTENT I can't access my data. [Or at least not the way I am used to.]

Template approach
I considered this example, which is technically closer to what I need:

{{boldp title /}}

...

$.views.tags("boldp", {
  template: "<p><strong>{{:~tag.tagCtx.args[0]}}</strong></p>"
});

But I don't know what to write instead of ~tag.tagCtx.args[0] if I want to wrap around something.

Which approach is closer to what I need? And how can I solve the remaining issues?


Solution

  • You should be able to do either:

    $.views.tags("expandable", function() {
      return '<div class="expandable closed">\
        <div class="header lowercase">\
          <img src="/Control/Svg?picture=EdgeBracket_Right" style="height: 35px; position: relative; top: 10px;"/>\
        </div> \
        <div class="content">' +
          this.tagCtx.render()
      + '</div>\
      </div>';
    });
    

    or alternatively:

    $.views.tags("expandable", {
        template: 
            '<div class="expandable closed">\
              <div class="header lowercase">\
                <img src="samples/data-link/question.jpg" style="height: 35px; position: relative; top: 10px;"/>\
              </div> \
              <div class="content">\
                {{include tmpl=#content||~tag.tagCtx.props.template/}}\
              </div>\
            </div>'
      });
    

    Then if you put content such as:

      {^{expandable}}
        {^{for members}}
          <div data-link="name"></div>
        {{/for}}
      {{/expandable}}
    

    (I am assuming JsViews here, but if you are just using JsRender you can write:

      {{expandable}}
        {{for members}}
          <div>{{:name}}</div>
        {{/for}}
      {{/expandable}}
    

    for the non-data-linked equivalent)

    the content should correctly access the data, such as {^{for members}}

    You should also be able to do (for the first version using the function definition)

      {^{expandable tmpl='externalTemplate'/}}
    

    or for the second - template based - version:

      {^{expandable template='externalTemplate'/}}
    

    There is a related question here: https://github.com/BorisMoore/jsviews/issues/218