Including stache partial in a stache template

I am in the process of changing some ejs file into stache files. I’m having trouble with one where in the original ejs file, it did something like this:

<div class="tab_container account_tab_body">
  <%== can.view.render('//myapp/plugins/manage_account/views/_account_tab.ejs', {options: this.options}) %>
</div>

When changing to stache, I tried the following:

<div class="tab_container account_tab_body">
    {{>//myapp/plugins/manage_account/views/_account_tab.stache}}
</div>

When I hit the page, I get “Uncaught TypeError: info.renderer is not a function” in can’s view.js. If I happen to change the extension of the actual file to mustache and drop the extension from the tag, it works.

<div class="tab_container account_tab_body">
    {{>//myapp/plugins/manage_account/views/_account_tab}}
</div>

So, how do I get it to load the file as a stache file? Also, when it loaded as a mustache file, it didn’t recognize the stache helper or tags I used in the partial. Also, if I don’t include it in the template, but load if from the controller, as below, everything works fine.

  dialog.find(".account_tab_body").html
    (can.view("//myapp/plugins/manage_account/views/_account_tab.stache", {options: this.options}));

Any ideas? Thanks in advance.

Are you building these templates? Are you using StealJS?

Yes, I’m using StealJS.

I just wanted to follow up on this problem I was having. At the time, I was using can.js v2.3.17. I have since upgraded to v2.3.20 and I am now able to load the stache templates successfully. I also dropped the initial ‘//’ in the file name.

<div class="tab_container account_tab_body">
    {{> myapp/plugins/manage_account/views/_account_tab.stache}}
</div>

Does this syntax work today in can version ^3.3.1 ? When I try the same, I get an exception

can-stache.js:370 Uncaught TypeError: Cannot read property 'innerHTML' of null
    at Object.stache.from.mustacheCore.getTemplateById (can-stache.js:370)
    at renderer (mustache_core.js:236)
    at eval (can-observation.js:546)
    at Compute.eval (mustache_core.js:241)
    at Observation.start (can-observation.js:226)
    at Compute._on (proto-compute.js:147)
    at Compute.eval (proto-compute.js:323)
    at Compute.eval [as _eventSetup] (can-observation.js:546)
    at Compute.addAndSetup (lifecycle.js:26)
    at eval (core.js:69)

If not how can I achieve the same? I found registerPartial but I was not able to include from a file using it.

I prefer to render stache template partials like this in 3.x:

my-file.stache

{{>otherTemplate}}

script.js

import template from './my-file.stache';
import partial from './my-partial.stache';
import DefineMap from 'can-define/map/map';
import stache from 'can-stache';

const viewModel = new DefineMap({
    otherTemplate: partial
});

const frag = template(viewModel);

document.body.appendChild(frag);

That way steal js knows that script.js depends on my-file and my-partial and can bundle them both. Otherwise, I’m not sure steal will automatically bundle template partial files.

1 Like

or if you are hard-core:

<can-import from="my.stache" {^@value}="@*template"/>

{{>@*template"}}
2 Likes