-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider not using Handlebars.create() #23
Comments
The main reason was that I didn't want to modify objects passed in as parameter. If the Handlebars-instance is used in other places as well, the callers may not expect a Promise-result but a string. Would it help you if this line would register all helpers of the original Handlebars-instance instead of the copy? Maybe add a line to copy all partials as well? |
My first thought was that if I'm passing in a Handlebars instance, I would expect that to be modified, otherwise why pass in an instance at all? I'd say that this was the convention for most handlebars libraries. However... I hadn't considered the fact that using promised-handlebars could actually 'break' other libraries that are not expecting a promise as a return value from the render methods, so it's definitely trickier. I think the copying solution you suggest would definitely be a good start, because at a minimum if I pass in a Handlebars instance with helpers and partials registered I would expect those still to exist on the new 'promisified' instance. However maybe in addition a config option could also be exposed to allow people to request that the original instance is modified and not cloned. So then something like the following would be possible (which would certainly be closer to my expectations): const Handlebars = require('handlebars');
const promisedHandlebars = require('promised-handlebars');
Handlebars.registerHelper('foo', function(){
return 'foo';
});
promisedHandlebars(Handlebars, {
clone: false // or modify: true or similar!
});
Handlebars.registerHelper('bar', function(){
return 'bar';
});
// Handlebars instance has both foo and bar helpers on it and returns promises. If you agree and want me to put this together as a PR for you to have a look over just let me know. |
@nknapp @allmarkedup I don't know if further expanding the complexity of the options and increasing amount of code this lib needs to maintain is the right way to go; it could be a good idea, but I think @nknapp should make that call. As an alternative we could make the small change @allmarkedup suggests and just use the passed-in instance, and then change the docs to suggest consumers use this by default to prevent breaking other libraries: promisedHandlebars(Handlebars.create());
// or
AsyncHandlebars = Handlebars.create();
promisedHandlebars(AsyncHandlebars); |
tl;dr
The long versionI would refrain from making another major version bump...... so quickly, so changing the behavior and adapt the documentation is not an option for me. (This is a breaking change after all.) In my experience breaking changes can cause a lot of work for users of the library. I don't want to do this too often. Copy all helpers/partials (decorators?) from the passed-in instance of Handlebars.Copying helpers seems to be a good idea and it doesn't change the behavior for cases where Provide an alternative method to modify an existing instance of Handlebars.I think an option would be fine if this would be a slight change. But to me, modifying the passed-in instance of Handlebars is more fundamental than that. If this change is really required, it might be another method (with its own api-docs, pointing out the dangers, and possibly with no return value). var promisedHandlebars = require('promised-handlebars')
var Handlebars = require('handlebars')
var AsyncHandlebars = Handlebars.create()
promisedHandlebars.morph(AsyncHandlebars) I'm still wary of this change, because it bears dangers. If Handlebars is used by two completely independent libraries in the dependency-tree and one of them is using the var promisedHandlebars = require('promised-handlebars')
var Handlebars = require('handlebars')
promisedHandlebars.morph(Handlebars) then the other library will probably break. A few weeks ago, I spent some hours tracing a bug because of montagejs/collections#139. The Those bugs are very hard to find and I fear introducing such a function might encourage users to introduce one. |
@allmarkedup I'm inviting you as a collaborator. It may be helpful to work on this in a branch in this repository rather than in your fork. |
Fwiw, I agree @nknapp |
@jskrzypek @nknapp I'm really sorry but I am now away on holiday until the 27th with very limited access to internet so I can't do anything on this before then - I'll pick up the thread again as soon as I'm back however. |
@allmarkedup No problem. There is no rush (from my point of view). Enjoy your vacation. |
@allmarkedup I am closing this issue due to the long idle time. If you still want to work on this feature, I will reopen the issue (and invite your as collaborator again). |
First - great job on this, I use it all the time.
However, one sticking point is always that regardless of the Handlebars instance that is passed in, you always call the
.create()
method on it. So if I've already registered partials/helpers then they are not copied across to the new, 'promisified' instance.If this module didn't call the
Handlebars.create()
method but instead just used the passed-in Handlebars object directly then existing helpers will still be promisified (as they will be re-registered along with the default Handlebars ones) and as an additional bonus I can still register helpers on the instance that I passed in (and they will be promisified accordingly) rather than getting back a different instance to the one I supplied.Is there a reason for using the
.create()
method that I'm missing? Will happily open a PR for this (I don't think it will break backwards compatibility with anything) if it's something you'd consider changing.The text was updated successfully, but these errors were encountered: