-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Inline Partials #1018
Comments
Example covering the use cases described in #893 <html>
<head>
<title>{{title}}</title>
<body>
<nav>
{{> sidebar}}
<a href="/">Home</a>
<a href="/blog">Blog</a>
{{/sidebar}}
</nav>
<article>
{{> content}}
</article>
</body>
</html> {{> layout title="Edit User"}}
{{*inline sidebar}}
{{> @default}}
<a href="/users">Users</a>
{{/inline}}
{{*inline content}}
<form method="post">
<input type="text" />
<button type="submit">Edit User</button>
</form>
{{/inline}}
{{/layout}} |
Looks interesting. I have several thoughts that will take some time to write down. A couple of things for now:
|
block params: I need to think about that some more, I didn't fully bake that bit. inverse:
attempted to address that. Basically these are fine:
This is not:
This was an attempt to avoid confusion, but I can see how others could arise. Perhaps you're right that disallowing inverse entirely when named blocks exist is a better option. |
@mmun for block parameters, the calling from a helper case is simple, we can use the same syntax. I'm not sure the best way to call a named block that defines block parameters from a template though. This comes to mind, but I'm not sure if that's confusing at all.
|
In ember we use {{yield currentUser to=header}} I'd consider prefixing block references to avoid shadowing the scope and generally making the "magic" more explicit, like with {{yield currentUser to=*header}} |
Updated the description after an offline discussion with @mmun. Moving this more to inline partials as the feature and resolved some potential ambiguities in the implementation and behavior. |
We should do a powwow sometime soon; I'm a little concerned about some frog-boiling complexity happening at the syntax level here: {{#> foo}}
{{*bar}}
Blah
{{/bar}}
{{/foo}} One of the nice things about the original grammar was that there were relatively few "mode switches" and most things were done with keywords ( |
@wycats what alternatives are you thinking? |
One concern that I do have is compatibility concerns that will be introduced by using named operators. @mmun's example above (we discussed offline) directly conflicts with https://github.com/walmartlabs/thorax/blob/master/src/helpers/template.js#L23 for example and there's no real way we can avoid that as there are no unused reserved keywords. One idea would be some sort of non-id keyword space:
Or similar and then we would own the whole |
@kpdecker I have to noodle on this a little more, but I'd like to point out that the closing I wonder if there's some grammar tricks we could play, taking advantage of some character that's disallowed in identifiers to form compound keywords. FWIW: I'm pretty sad that {{#if foo}}
<p>{{foo}}</p>
{{&else}}
<p>Nothing</p>
{{/if}} |
I'm still digesting the ideas presented here but there's a considerable overlap of concerns with my question here - #1023 When considering these issues I've been trying to break them up as small as possible and then find solutions that fit as widely as possible. Applying this to the given topic I've come to the following -
thats it for now although i'll try to chew this over a bit more. |
This allows for failover for missing partials as well as limited templating ability through the `{{> @partial-block }}` partial special case. Partial fix for #1018
This allows for failover for missing partials as well as limited templating ability through the `{{> @partial-block }}` partial special case. Partial fix for #1018
We've been using something like this for a while now, roughly (not exactly) we use: Handlebars.registerHelper('registerPartial', function(name, options) {
Handlebars.registerPartial(name, options.fn);
}); We use it to pass blocks as arguments to helpers, e.g: {{#registerPartial "foo"}}Foo?{{/registerPartial}}
{{#registerPartial "bar"}}Bar!{{/registerPartial}}
{{> (switch x A="foo" B="bar")}} And to other partials, e.g: {{#registerPartial "foo"}}Foo?{{/registerPartial}}
{{#registerPartial "bar"}}Bar!{{/registerPartial}}
{{> show partial1="foo" partial2="foo"}} Basically, this, combined with partial context arguments, enables you write your templates more like you would write your Javascript code with the inline partials serving as callback or inline functions allowing for advanced composition and facilitating reduced repetition. It could also be achieved by creating a bunch of separate partial template files etc, but that quickly becomes unmanageable. I would be very happy if this would be properly supported by Handlebars itself as this current approach is quite inefficient; recreating the block function and re-registering the partial each time the containing template or partial is rendered. |
This allows for failover for missing partials as well as limited templating ability through the `{{> @partial-block }}` partial special case. Partial fix for #1018
This allows for failover for missing partials as well as limited templating ability through the `{{> @partial-block }}` partial special case. Partial fix for #1018
Allows for partials to be defined within the current template to allow for localized code reuse as well as for conditional behavior within nested partials. Fixes #1018
Allows for partials to be defined within the current template to allow for localized code reuse as well as for conditional behavior within nested partials. Fixes #1018
This discussion has sort of stalled, so I went ahead and implemented a potential solution under #1082. I think this handles most of the cases described here and is a bit clearer than the sigil-based solution. Dynamic definition is not currently implemented but it could potentially be via conditional decorators but I'm not sure about that use case. Closing this issue out to focus discussion on #1082. |
This allows for failover for missing partials as well as limited templating ability through the `{{> @partial-block }}` partial special case. Partial fix for handlebars-lang#1018
@kpdecker Can "layouts" be nested? I was thinking/hoping this feature could replace shannonmoeller/handlebars-layouts for the basic use case of nesting.
Gives me this error:
I am expecting this output:
|
@michaellopez at the surface it looks like that should work. Do you mind posting this as a separate bug and I'll take a look into what might be going wrong? |
@michaellopez I was able to reproduce this and get a fix. 05b82a2 Published under 4.0.1. Thanks for the bug. Please feel free to file new issues if you run into any other problems! |
@kpdecker Thank you for your fast response. The fix fixes the use case here. I don't know if there is any technical difference between basic partials and block partials in this case but failover content does not work in the above use case. I created a follow up in #1089. Please have a look at that, thank you. |
Inline Partials
Inline partials provide a syntax that allows partials and helpers to have named programs that they can execute at will. This allows for use cases such as local partials, layout templates, and helpers that have more conditional rendering options than just positive and negative cases.
Defining
Inline partials are defined using the
<
flag.Will declare the
bar
inline partial which will be made available when the parent runs.Each block has it's own set of named inlined partials and are able to access any inline partials defined in parent scopes.
Inline partials follow the same standalone rules as blocks.
Multiple inline partials with the same name in a given block result in a compile error.
Inline partials have access to all block parameters defined by their parents and may also define their own:
Calling from helpers
Inline partials contained within helper calls will be exposed to the call's
options.partials
object as a named value.The existence of a given inline partial is not guaranteed so helpers should implement checks when resiliency is a concern.
Calling from templates
Within templates, inline partials may be called using the normal partial syntax:
Custom contexts or parameters may be passed to a inline partial in the same manner as other partials:
Would execute the inline partial
bar
with contextfoo
, augmented with the valuebaz
set tobat
.Inline partials have any block parameters from their defining scope made available to them at execution time.
When run using
{{> }}
, the inlined partials take priority over higher scoped partials that may be defined.Partial Blocks
Partial calls may now have a child block, which define inline partials that may be passed to the executed partial as well as a default behavior to be executed if a given partial does not exist.
Would call the partial
foo
, defining thebar
inline partial which will be passed to the partial, which can execute it as follows:Any content in the partial block other than inline partials is not executed if a given partial exists. If the partial would like to render this content, to augment default behavior for example, it may do so using the
@default
partial name.Would render:
If a partial block is provided and no partial with a given name exists, then the partial block will be rendered rather than throwing an error, which occurs if a partial block is not provided.
The text was updated successfully, but these errors were encountered: