Closed hedav85 closed 4 years ago
Sorry for the confusion @hedav85. The <include>
tag is fairly flexible. You can pass it any of the following:
<include>
tag)renderBody(out)
functionrenderBody(out)
method (e.g. { renderBody: function(out) { out.write('Hello!'); }
)safeHTML
property (e.g. { safeHTML: '<b>Hello</b>' }
)In your case, you need to provide the loaded template:
// Load the template:
$ let template = require(data.templatePath + data.templateName);
<include(template, {...})/>
The reason for this behavior is that only static string literals can be resolved to template paths at compile-time. At render-time we did not want marko to have to resolve and load templates from a path since that operation can be expensive (better to only load templates once at startup) and often times developers would pass relative paths that were not relative to the template where is <include>
is used and this would lead to runtime exceptions.
After looking at the docs, I see that we absolutely need to do a better of updating the docs to match the <include>
implementation.
@austinkelleher do you mind working on the docs for the <include>
tag? (thanks in advance!)
<include>
tag@hedav85 Regarding:
If I do a
var template = require('../path/to/my/template/' + 'index.marko')
and then in the template<include(data.template, {...})/>
the template is loaded and rendered. But in this case I run into another issues, because the component.js logic is missing: https://github.com/marko-js/marko/issues/689, https://github.com/marko-js/marko/issues/693
Can you provide some code samples for us to add a reproducible test case? It should not be the case that component.js
logic is missing.
Hi, thanks for the feedback. I created a sample to reproduce my problem. https://github.com/hedav85/marko-test In this sample you have the following structure:
In the sample the module provides a button to generate a random number. If the container has a component.js, the button will not work. If you rename or remove the component.js from the container, then the button works fine. You also can check the console. The sample will log the onMount() events.
All components are included with the <include/>
-tag.
I hope this sample helps you to reproduce the problem. Thank you!
I've tested a bit more around this issue. With your provided solution I get it working if the component is in the same node module. I can refer direct to the path.
// Load the template:
$ let template = require(data.templatePath + data.templateName);
<include(template, {...})/>
In the compiled template index.marko.js you will find
let template = require(data.templatePath + data.templateName);
My Problem now is that a component can be located in a another node module. The generated static code has the module version in the path. In my template I did not know anything about this version tag. This means my path becomes incorrect and require is not able to locate the template.
e.g.
If the path is correct the component is loaded and rendered correct and also the logic is there.
If you use a string in the template, e.g. (based on my sample)
// Load the template:
$ let template = require('../module');
<include(template, {...})/>
in the compiled template you get the following require statement:
var template = require('/marko-test$1.0.0/components/module/index.marko'/*'../module'*/);
It seems that a string literal is transformed into a another correct path.
Would it be possible to do this also for variables if they are strings?
$ let path = '../module';
$ let template = require($path);
should be handled in same way like
$ let template = require('../module');
to get
var template = require('/marko-test$1.0.0/components/module/index.marko'/*'../module'*/);
Up i have the same issue :'(
Same issue here
In <include>
tag is now deprecated and replace with the <${dynamic}>
tag. The docs have also been improved https://markojs.com/docs/syntax/#dynamic-tagname and https://markojs.com/docs/syntax/#dynamic-components.
I'm a bit confused about the include tag.
If I use the include tag in the following way, the template will be loaded and rendered correctly.
<include('../path/to/my/template/index.marko', {...})/>
But if I use it with expressions like
<include('../path/to/my/template/' + 'index.marko', {...})/>
then just the string of the path is rendered.My target is to dynamicly import components like e.g.
<include(data.templatePath + data.templateName, {...})/>
Do I anything wrong?
Thanks!
Update:
If I do a
var template = require('../path/to/my/template/' + 'index.marko')
and then in the template<include(data.template, {...})/>
the template is loaded and rendered. But in this case I run into another issues, because the component.js logic is missing: #689, #693