-
-
Notifications
You must be signed in to change notification settings - Fork 47
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
extending the context from templates (that may be nested) #141
Comments
i am testing a move of my gulp work flow to assemble 0.6. i had originally been using (handlebars-layouts)[https://github.com/shannonmoeller/handlebars-layouts] for layouts but have been having problems with corrupted contexts that seems to be caused by the handlebars-layouts helpers (still trying to debug to know for sure and will report to that project if i can get a test). in the meantime i am trying to use the nested layouts of layouts instead of the inheritance-based layouts of handlebars-layouts and have been stuck trying to find a way to have nested/inner layouts add stylesheets to the top-most layout. basically each layout can add styles (and scripts, etc.) to the final rendered layout that need to appended to the outer layouts. here is a simplified example using the <html>
<head>
{{#block "documentStyles"}}
<link href="assets/styles/document.css" rel="stylesheet"/>
{{/block}}
</head>
</html and the inner/nested layout {{#extend "layouts/document.html"}}
{{content "documentStyles" mode="append"}}
<link href="assets/styles/page.css" rel="stylesheet"/>
{{/content}}
{{/extend}} would give us <html>
<head>
<link href="assets/styles/document.css" rel="stylesheet"/>
<link href="assets/styles/page.css" rel="stylesheet"/>
</head>
</html so far, my initial and simple solution to reproduce this with non-inheritance nested layouts (i.e. w/o ---
styles:
- assets/styles/document.css
---
<html>
<head>
{{#styles}}
<link href="{{.}}" rel="stylesheet"/>
{{/styles}}
</head>
</html and the inner/nested layout ---
layout: layouts/document.html
styles:
- assets/styles/page.css
--- it works, but perhaps there is a better/preferred way? as noted this method requires modifying the context merge to merge array property values (which actually has some nice side effects, but that is for another issue). PS. i leave it up to you, but perhaps the title of this thread should be more along the lines of "inheritance layout block functionality in non-inheritance nested layouts", or "modifying content in outer layouts from inner/nested layouts", or more specifically "appending stylesheets to head from nested layouts". |
I changed the title to something that seems closer to what this is about. I think we need to show how to take any arbitrary data from templates, even nested, and use it to extend the context. (on second thought, this might be about "exposing the layout stack on the context", but it depends...). what if we exposed the layout stack of each template as an array of objects? The order of the array would be significant and would describe the order in which the stack would be "flattened" for any given template, and the objects in the array would be the data object from each template in the stack. After layouts are applied, helpers would be able to use this stack and its objects. etc. etc. we will need to add something to layouts to make this work. @doowb and I have already planned to do this, but haven't yet because there are different ways to do it and we haven't decided which approach will work out best. |
I'm such an airhead sometimes. I didn't even realize I created this issue on assemble.io, "Oooh the pretty green button for issue, I click it now". <= me That's about it. Anyway, @waynedpj I made some changes to the layouts lib that I haven't pushed up yet. I'll can go over this tomorrow, but in a nutshell:
Last, a callback can now be passed to extend or use the object described above in some way, while the stack is being built - so we will only need to loop over the stack for a template a single time. For example, to build that array of scripts you mentioned: function getScripts(obj, stack, i) {
stack.scripts = _.union([], stack.scripts, obj.layout.data.scripts || []);
}; here is what the resulting data object looks like after building the stack, in case anyone has suggestions or ideas for doing this differently. { options: {},
stack:
[ { layout:
{ content: 'aaa above\n{% body %}\naaa below',
data: { title: 'Foo', scripts: [ 'aaa.js' ] },
layout: 'bbb',
key: 'aaa' },
before: 'This is content',
depth: 0,
after: 'aaa above\nThis is content\naaa below' },
{ layout:
{ content: 'bbb above\n{% body %}\nbbb below',
data: { title: 'Bar', scripts: [ 'bbb.js' ] },
layout: 'ccc',
key: 'bbb' },
before: 'aaa above\nThis is content\naaa below',
depth: 1,
after: 'bbb above\naaa above\nThis is content\naaa below\nbbb below' },
{ layout:
{ content: 'ccc above\n{% body %}\nccc below',
data: { title: 'Baz', scripts: [ 'ccc.js' ] },
layout: 'default',
key: 'ccc' },
before: 'bbb above\naaa above\nThis is content\naaa below\nbbb below',
depth: 2,
after: 'ccc above\nbbb above\naaa above\nThis is content\naaa below\nbbb below\nccc below' },
{ layout:
{ content: 'default above\n{% body %}\ndefault below',
data: { title: 'Quux', scripts: [ 'index.js' ] },
key: 'default' },
before: 'ccc above\nbbb above\naaa above\nThis is content\naaa below\nbbb below\nccc below',
depth: 3,
after: 'default above\nccc above\nbbb above\naaa above\nThis is content\naaa below\nbbb below\nccc below\ndefault below' } ],
scripts: [ 'aaa.js', 'bbb.js', 'ccc.js', 'index.js' ],
result: 'default above\nccc above\nbbb above\naaa above\nThis is content\naaa below\nbbb below\nccc below\ndefault below' } What I'm thinking is that we should expose this as a param or a property on the |
Just pushed this to a branch. https://github.com/doowb/layouts/tree/stack-object |
I like this if we want to keep all that logic inside However, I like the callback function since it gives you the control over building the stack object. I think this will allow more flexibility and keep it clean when looking for where to do things with layout data. |
true, but that causes the stack to be looped over twice. this way we only loop once. If we need an array of template names to expose the stack so it can be used in other ways, we can just push the template names into an array and add that to the returned object. |
@jonschlinkert thanks for this. it obviously handles my scripts/styles case. 2 little observations:
regardless, it definitely seems like it would be plenty flexible for other things. thanks again. |
Hmm, I don't think so but it's possible. The only place I can think of that we're using
Now that you mention it, yes lol. I added that since it seemed difficult to visualize the index while you're inspecting the object. It's not really necessary though so I should probably remove it |
so far i have only been using the new and thanks again! |
Sometimes I forget about entire features we have (and no comments from you about that @Melindrea lol), so no worries lol. I'm not cloning the object (I don't think) so I thought maybe I forgot about a reference to it somewhere. |
@jonschlinkert I say nothing, then I have nothing said ;) |
lol |
@doowb did we ever expose the object from the layout stack? |
Don't think we merged in that branch. |
I started this issue to continue the discussion from #74 (comment)
@waynedpj what version are you using? with v0.4.x this is not easy to accomplish.
The text was updated successfully, but these errors were encountered: