Closed starmandeluxe closed 7 years ago
Any I/O bound work you need to do should be done as part of creating the model.
Ah, I see what you mean. Normally I'd agree, but our requirement is to allow parameter passing via the template and I/O is totally based on this parameter. For example, the template will specify an ID, and the corresponding entity is then looked up via this ID during template rendering in the Helper method. I have updated my code example to reflect this.
Perhaps this is not using Handlebars as intended?
The template specifies the lookup ID? That seems odd. A template is a static asset - if you know the ID at authoring time, you can go fetch that data at initialization time and cache it for the lifetime of the template, not re-fetch each time during execution.
Or if the object could change, it should be part of a record that is tied to your template so you can look it up as part of constructing the model.
I have the same requirement actually.
The NodeJs hbs implementation for Express has a registerHelperAsync method. I've used it for several of my use cases.
The following post describes how it works under the hood.
https://github.com/wycats/handlebars.js/issues/141#issuecomment-44947766
If I had more experience with c# I'd try to port it over.
If this notion is incorporated into the core handlebarsjs, we'll add it as well.
Any update on this, I need the RegisterHelperAsync too. We'll let user edit the template, so they can call {{GetProductList 43}} to get a furniture(category id:43) picture list.
There are no plans currently to support this. The recommended architectural approach is to do all I/O bound work during the construction of your model object, not during template binding.
Sometimes the logic has no idea what the template might need and there is no way around it. Happens a lot in CMSs where everything is dynamic, and template can't be specialized.
As much as I understand the restriction as it's out of scope, I had to implement my own library also to overcome this limitation.
+1 I need this as well. Are you open to a PR to add it?
I think this is a pretty crucial feature to be able to resolve dependant external inputs while generating. My specific use case is to pull information from a database and interpolate it into the output, which I would think is quite a common requirement.
Intermingling fetching and i/o with template rendering doesn’t align with the architecture of Handlebars. Candidly I think if you are headed down the road where you are using Handlebars for rendering and think you need this, you are already confused about the responsibility boundaries in your system.
you are already confused about the responsibility boundaries in your system.
That's a pretty blunt statement and I try to avoid dealing in absolutes; while I would generally tend to agree with you that there should be a model that populates the view, this only works ahead of time when you are doing something where all the data is known at the time the model is composed. To allow end users complete customisability you need to be able to resolve information at the time the template is rendered which is ostensibly why the helper method exists. To go beyond trivial examples (i.e. anything populated from a database or file system) you need to be able to make use of the async pattern. My particular use case is in a CMS scenario where users can embed images into the template which is resolved along with metadata and rendered into the view.
I doubt my requirements are unique and from looking at this issue, this functionality clearly is something that multiple people could make use of.
FWIW, there are other templating options out there (i.e. Liquid/Fluid) that provide the ability for helpers to be async.
Cheers
+1 for this - would suit my use case perfectly - is the issue closed as you're not going to make this change?
+1. Without that the whole strength of handlebar is minimize.
We are not going support async helpers, unless the Handlebars JS library adds async helpers (which as far as I know, also does not plan to do).
Thank you for your answer, how much works do you think it represents to fork this repo and add that feature ? What are the things you would warn me about ?
"If you have to ask, you can't afford it"
It would be straightforward to get a working prototype in a fork. However, my own experience starting this library over a weekend 10 years ago and it turning into thousands of hours of engineering spread across dozens of contributors, I can say that getting such features to work reliably, predictably, performantly, at scale is a heavy lift.
Currently it seems impossible to make a registered helper method have asynchronous calls inside it. I want to do something like this:
Handlebars.RegisterHelper("my_method", async (writer, context, parameters) => { var blah = await _myService.GetBlahAsync(parameters[0]); writer.WriteSafeString(blah); });
But it ends up closing the writer even before the writesafestring is called.
Can support for this functionality be added?