Closed noel-schenk closed 11 months ago
Are you talking about a webpack loader? Or something else?
Ah no for example if I want to render my templates in the browser and i have templates which have to be included. It should be possible to get the templates via a loader over an ajax request. Nunjuck has a good example: https://mozilla.github.io/nunjucks/api.html#writing-a-loader unfortunately Nunjucks doesn't allow arguments for it's templates.
Oh yes, I see. I have plans for at least two loaders:
I won't include them in Twing. But they'll definitely be available as separate packages.
What would the arguments by needed for?
The server part doesen't has to be part of the library. But for example a simplified TwingLoaderInterface
TwingWebLoaderInterface cache:boolean getSource(name:string, context:any)
Now if a template should be included the "master" loader will ask the "simple" loader for the full rendered template. Everything else can easily be handled by a developer. Also the "master" loader could handle the caching. The context can be passed either with a separate function or "hardcoded".
The arguments are really important because you can make the templates dynamic: {% include 'template.html' with {'foo': 'bar'} %}
But it would be like a wrapper for the TwingLoaderInterface to handle all the stuff currently done by the TwingLoaderFilesystem.
Writing a loader is actually quite simple. But for now it is not possible to write a loader that would make Ajax calls because Twing doesn't support async loaders.
For now.
It's my next move, probably for Twing 3.1 or 3.2. It's been postponed for too long.
thanks for the response. I would love to try something. But I don't get how I can get the real name of the template. I looked at your filesystem example and there is this line where you fill the templates into the cache class variable:
this.cache.set(name, nodePath.resolve(nodePath.join(path, shortname)));
Shortname is set to this:
[namespace, shortname] = this.parseName(name);
parseName returns the shortname as it get's passed (as name) to the function parseName or if starts with an @ then it returns everything after the / as the shortname.
But when I try to get the name I get the templateHash which looks like this: __string_template__5a13abdde6d8986ce9eb3885dd689b2881a9e002406ce18452b1f93f953f76de
I can see that this is generated in the environment.ts at line 244 but I don't get how your class get's a real name it can find in the system and mine gets just the hash.
__string_template__5a13abdde6d8986ce9eb3885dd689b2881a9e002406ce18452b1f93f953f76de
This is the generated name of the template when one use the template_from_string
function of Twig, like this:
{{ include(template_from_string("Hello {{ foo }}")) }}
Can you show me the code of what you are trying to achieve?
Ah I tried doing this:
resolve(env.createTemplate(data[0]).render(data[1]));
So it there any way to get the actual template as I probably need to give it back inside getSourceContext?
getCacheKey would be then
__string_template__5a13abdde6d8986ce9eb3885dd689b2881a9e002406ce18452b1f93f953f76de
isFresh is part of a timestamp based cache
exists just checks if the template exists
resolve just gives back the same as getSourceContext but as a string and without the name (string instead of a TwingSource)
So it there any way to get the actual template as I probably need to give it back inside getSourceContext?
env.createTemplate
returns a template (i.e. an instance of TwingTemplate
).
But I have the feeling that when you talk about template you talk about the source of your template.
It's not quite clear to me what you are trying to achieve in the end.
Maybe you can join me here:
https://nightlycommit.slack.com/messages/C9FNDPD0A
It would make things easier if we need to talk a lot about your issue.
Thank you :) I think you need to add me first as I can't log in.
Am Di., 1. Okt. 2019 um 13:10 Uhr schrieb Eric MORAND < notifications@github.com>:
Maybe you can join me here:
https://nightlycommit.slack.com/messages/C9FNDPD0A
It would make things easier if we need to talk a lot about your issue.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/NightlyCommit/twing/issues/388?email_source=notifications&email_token=ACLYZGPJO2C4ZVIMHPRUVFTQMMVY7A5CNFSM4IYNROC2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAA4QAQ#issuecomment-536987650, or mute the thread https://github.com/notifications/unsubscribe-auth/ACLYZGOCF4FKQGHCWLEFED3QMMVY7ANCNFSM4IYNROCQ .
So it there any way to get the actual template as I probably need to give it back inside getSourceContext?
env.createTemplate
returns a template (i.e. an instance ofTwingTemplate
).But I have the feeling that when you talk about template you talk about the source of your template.
It's not quite clear to me what you are trying to achieve in the end.
The only thing I want to do is to make an interface communicating between my local storage (preloaded template"sources") and the loader. Because I have includes inside the template the loader should fetch them. But I don't get further than getting the string template key. I would need the names/paths of the includes when they get fetched by the loader and the respond with the corresponding template"source".
OK, it's clear.
First, you got it right but it's good to re-say it: templates are loaded by their name. Filesystem loader considers that the name of a template should be considered as a path, but this is an implementation detail.
You should take TwingLoaderArray as an example instead of TwingLoaderFilesystem. It's much easier and much closer to what you are trying to achieve: the local storage is a key/value store.
Here is what I would do:
exists
to return true when the name passed as parameter is a key in the local storagegetSourceContext
that actually do the core job - namely returning a TwingSource which code is the value stored in the local storage under the passed nameOther methods of the TwingLoaderInterface can be left untouched from the parent.
Something like that, out of my head, untested:
import {TwingLoaderArray} from "./array";
import {TwingSource} from "../source";
class LocalStorageLoader extends TwingLoaderArray {
constructor() {
super([]);
}
getSourceContext(name: string, from: TwingSource): TwingSource {
return new TwingSource(localStorage.getItem(name), name);
}
exists(name: string, from: TwingSource): boolean {
return localStorage.getItem(name) !== null;
}
}
Thank you so much! I will look into that. Got kicked out of the airport because I used a power outlet I wasn't supposed to :P but should be back with my laptop at the 3rd.
As the whole engine now also runs in the browser it will need a loader for the browser. For example included templates will not render without a working loader.