-
Notifications
You must be signed in to change notification settings - Fork 71
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
Proposel: dynamic partials #49
Comments
Lambdas can get you around the issue fairly well: // Data
{
heading: "MY content heading",
content: "<p>Some text</p>",
layout: function(raw) { return "{{>header}}" + raw + "{{>footer}}" }
} {{#layout}}
{{heading}}
{{> content}}
{{/layout}} On the other hand, it sounds like what you actually want is a proper "layout" facility. Something like: <html>
<head></head>
<body>
{{> $partialName}}
</body>
</html> Where We need a better answer for v2.0.0. |
Ahh, I see. using a lamda like this means that the layout is now embedded in the code. Workable but as you say, I would much prefer a layout facility as per your example. I would second adding that. |
Here's another proposed solution to this problem:
From mustache/mustache#138. |
Another potential solution involves the creation of "dynamic content" inside templates.
This may have some order-related issues if implemented improperly, but stands to be a fairly simple approach overall. |
@pvande This is template inheritance you mention, yes? (a la #38) I think the functionality it provides is a good idea, but I find the proposed notation intolerable to read, as well as lacking in a certain functional respect. Specifically the top To remedy, I would propose instead an approach that I think is both more readable and reusable: <!-- layout.mustache -->
<html>
<head>
<title>{{{title}}}</title>
</head>
<body>
{{{content}}}
</body>
</html> <!-- content.mustache -->
{{#> layout}}
{{=title}}Page Title{{/title}}
{{=content}}
<div id="content">
<p>Blah blah blah ...</p>
</div>
{{/content}}
</ layout> Notice there is nothing special about The content still uses a "block partial" within which definitions can be made via named blocks (i.e. This could also remain compatible with original |
In this case, what I'm describing isn't actually template inheritance -- that If, as you point out, it looks like you could include the The choice of sigil in the description is for illustrative purposes only. It could just as easily have been As for the functional respect, I actually think this solution could leverage one of the most valuable aspects of Mustache. With very few exceptions ( For all this, we're still just collecting suggestions at this point -- we don't have to make a decision right now, and I'd like us to get a few more thoughts written down before we do. Your proposed solution has some intersting merits: "overrides" seem to be very specifically scoped, and you're actually providing new values for interpolation. Great food for thought, thank you. |
If you take the approach of
How do you deal with a situation where you want to re-use the partial more than once? like this?
Or is that not an intended use case? It seems very odd. There's nothing that structurally ties the |
@mcheely The envisioned behavior of the Regular content in the template behaves as regular content in any other template. Duplicate declarations within the same compilation unit are an error; in resolving multiple declarations, the nearest (inherited) one wins. These examples would all be equivalent: {{! Example 1 -- Partial declared first }}
{{< foo}}***{{/foo}}
[{{> foo}}]
{{! Example 2 -- Partial declared after use }}
[{{> foo}}]
{{< foo}}***{{/foo}}
{{! Example 3 -- Partial includes sibling partial declaration }}
{{> layout}}
{{< layout}}
[{{>foo}}]
{{< foo}}***{{/foo}}
{{/layout}}
{{! Example 4 -- Partial includes parent partial declaration }}
{{> layout}}
{{< layout}}
[{{>foo}}]
{{/layout}}
{{< foo}}***{{/foo}}
{{! Example 5 -- Sibling partial declaration overrides parent partial declaration }}
{{> layout}}
{{< layout}}
[{{>foo}}]
{{< foo}}***{{/foo}}
{{/layout}}
{{< foo}}xxx{{/foo}} Remember that in this model, the Those examples help? |
There's two things your examples really makes clear to me.
At least that's how it seems to me... It really just seems more complex than it needs to be. |
@trans I agree completely about As for the non-order dependent design adding needless complexity, I really can't say. I feel like we'll probably need to do a proposal shootout at some point (with a non-trivial example) to gauge viability. The spec currently only defines two cases in which order of evaluation matters (delimiter changes and stateful functions / methods), and I'm inclined to move away from order-dependency as much as possible. I feel at this point as if I'm being drawn in to defend a decision that hasn't been made. At this point, the proposal's been made, and I've clarified a few points around what the initial proposal was intended to describe. Barring massive communication failure on my part, I intend to avoid further comment on this proposal. |
No problem. I think it's been a good discussion. I think there's a tendency to underestimate the value of detailed dialog like this in figuring out best approaches. I don't think it's so much a matter of defense, as it is just putting pros and cons of variant viewpoints on the table (in print) so they can be easily deliberated. |
@pvande That does clarify things, thank you. Since you asked, I'll refrain from another round of comments. I completely understand that what's here is just a proposal. This does lead me to a few other questions & comments though:
|
@mcheely The formal process at this point is that this issue tracker is being used to aggregate and discuss spec-level problems with Mustache. When there's a clear path forward, one of the spec curators will write (or merge) the changes for review. I'm going to be opening a "v2.0.0 metaissue" shortly, in the hope that we can more concretely designate the things we want to see changed in the next major version of the spec. The best way to participate in this process is to keep engaging with this issue tracker, and with the spec itself. If you have non-trivial real-world examples of problems or solutions, please share! At the very least, it gives us something concrete to discuss. :) |
@pvande, GRMustache has shipped with an implementation of dynamic partials seen as an extension of 0-arity lambdas (variable lambdas, not section lambdas). Discussion was in issue #54. Documentation is at https://github.com/groue/GRMustache/blob/master/Guides/helpers.md. Especially, read the three "Variable helper example" sections. The last example, "Variable helper example: have objects able to render themselves", is based on the following rule that the spec would benefit from embedding:
The same release also introduces this rule:
Basically, it gives Mustache the ability to render I'm looking forward to your feedback, @pvande. |
Dynamic partials need special care when templates are stored in a hierarchy of directories. GRMustache has just shipped with support for both relative and absolute paths to partials. Regular partial tags contain relative paths: {{> header }}, {{> partials/header }}. Absolute paths start with a slash: {{> /path/to/partial }}. Release notes, and link to documentation: https://github.com/groue/GRMustache/blob/master/RELEASE_NOTES.md#v540 |
Hi all, I'm new to moustache so please correct if there is a way to do this. I've been using Mu2 and Node.js as a bit of context.
I could like to be able to create a skeleton moustache template and then tell it which partials to include. The reason for this is that using this top down approach to assembling a document means that each template only needs to be aware of the content it contains, not that which is around it. An example is this - with some help from the Mu2 developer I current need templates like this:
view
Main render: content.mustache
Partial: header.moustache
Partial: footer.moustache
This will work for the moment, but it's rather ugly because the content has to know what goes around it. It also has problems if I need (for example) to select different partials in the headers and the content. What I would much prefer to be able to do is this:
view
Main render: page.moustache
Partial: content.mustache
So when the rendering encounters the
{{> contentPartial}}
code, it detects that contentPartial is a value in the view, insert's it's value and then continues to include, thus including the content.moustache partial.Please let me know if there is a way around this issue - lamda's perhaps?
The text was updated successfully, but these errors were encountered: