Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions examples/simple/simple.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@
</body>

<template name="layout">
<div class="layout">
{{layoutHelper}}
{{> yield}}
</div>
{{#with data='layoutData'}}
<div class="layout">
{{layoutHelper}}
{{data}}
{{> yield}}
</div>
{{/with}}
</template>

<template name="hello">
{{#Layout template='layout'}}
<h1>Hello World!</h1>
{{helloHelper}}
<input type="button" value="Click" />
{{/Layout}}
{{#with data='templateData'}}
{{#Layout template='layout'}}
<h1>Hello World!</h1>
{{helloHelper}}
{{data}}
<input type="button" value="Click" />
{{/Layout}}
{{/with}}
</template>
17 changes: 17 additions & 0 deletions layout-test.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,26 @@
{{/Layout}}
</template>

<template name="DefaultMainRegionWithData">
{{#with property='good'}}
{{#Layout template="LayoutWithOneYield"}}
{{property}}
{{/Layout}}
{{/with}}
</template>

<template name="ContentForTests">
main
{{#contentFor region="footer"}}
footer
{{/contentFor}}
</template>


<template name="ContentForWithData">
{{#with property='good'}}
{{#Layout template="LayoutWithTwoYields"}}
{{#contentFor region='footer'}}{{property}}{{/contentFor}}
{{/Layout}}
{{/with}}
</template>
13 changes: 13 additions & 0 deletions layout-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,19 @@ Tinytest.add('layout - default main region using Layout template', function (tes
});
});

Tinytest.add('layout - default main region using Layout template should pickup data from context', function (test) {
withRenderedComponent(Template.DefaultMainRegionWithData, function (cmp, screen) {
test.equal(screen.innerHTML.compact(), 'layoutgood', 'default main region should be __content and inherit data');
});
});

Tinytest.add('layout - contentFor region using Layout template should pickup data from context', function (test) {
console.log('here')
withRenderedComponent(Template.ContentForWithData, function (cmp, screen) {
test.equal(screen.innerHTML.compact(), 'good', 'region should be contentFor and inherit data');
});
});

Tinytest.add('layout - dynamic yield regions', function (test) {
withRenderedLayout({template: 'LayoutWithTwoYields'}, function (layout, screen) {
var renderedCount = 1;
Expand Down
97 changes: 66 additions & 31 deletions layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,13 @@ var lookupTemplate = function (name) {
throw new Error("BlazeLayout: You must pass a name to lookupTemplate");

if (contentBlocksByRegion[name]) {
result = contentBlocksByRegion[name];
console.log(self, self.parent)
if (self.parent)
result = UI.InTemplateScope(self, contentBlocksByRegion[name]);
else
// XXX: this is really only for the test where we render the layout in
// isolation, without a parent. @cmather -- we should fix this.
result = contentBlocksByRegion[name];
} else if ((comp = findComponentWithProp(name, self))) {
result = comp[name];
} else if (_.has(Template, name)) {
Expand Down Expand Up @@ -107,8 +113,7 @@ Layout = UI.Component.extend({
var data = Deps.nonreactive(function () { return self.get(); });
var dataDep = new Deps.Dependency;
var regions = this._regions = new ReactiveDict;
var content = this.__content;


// a place to put content defined like this:
// {{#contentFor region="footer"}}content{{/contentFor}}
// this will be searched in the lookup chain.
Expand Down Expand Up @@ -220,12 +225,9 @@ Layout = UI.Component.extend({
var regions = layout._regions;
// create a reactive dep
var tmpl = regions.get(region);

if (tmpl)
return lookupTemplate.call(layout, tmpl);
else if (region === 'main' && content) {
return content;
}
else
return null;
};
Expand Down Expand Up @@ -260,15 +262,9 @@ Layout = UI.Component.extend({
var self = this;
var region = self.region;

var contentBlocksByRegion = layout._contentBlocksByRegion;

if (contentBlocksByRegion[region]) {
delete contentBlocksByRegion[region];
}

// store away the content block so we can find it during lookup
// which happens in the yield function.
contentBlocksByRegion[region] = self.__content;
layout._contentBlocksByRegion[region] = self.__content;

// this will just set the region to itself but when the lookupTemplate
// function searches it will check contentBlocksByRegion first, so we'll
Expand All @@ -293,6 +289,12 @@ Layout = UI.Component.extend({
// computation. so if the template changes
// the layout is re-endered.
return function () {
// store away the main content block so we can find it during lookup too
if (self.__content) {
self._contentBlocksByRegion.main = self.__content;
self.setRegion('main', 'main');
}

// reactive
var tmplName = self.template();

Expand All @@ -301,23 +303,8 @@ Layout = UI.Component.extend({
if (tmplName === '_defaultLayout')
return self._defaultLayout;
else if (tmplName) {
var tmpl = lookupTemplate.call(self, tmplName);
// it's a component
if (typeof tmpl.instantiate === 'function')
// See how __pasthrough is used in overrides.js
// findComponentWithHelper. If __passthrough is true
// then we'll continue past this component in looking
// up a helper method. This allows this use case:
// <template name="SomeParent">
// {{#Layout template="SomeLayout"}}
// I want a helper method on SomeParent
// called {{someHelperMethod}}
// {{/Layout}}
// </template>
tmpl.__passthrough = true;
return tmpl;
}
else {
return lookupTemplate.call(self, tmplName);
} else {
return self['yield'];
}
};
Expand Down Expand Up @@ -372,3 +359,51 @@ BlazeUIManager.prototype = {
UI.DomRange.insert(this.render(props, parentComponent).dom, parentDom || document.body);
}
};

var findComponentOfKind = function (kind, comp) {
while (comp) {
if (comp.kind === kind)
return comp;
comp = comp.parent;
}
return null;
};

// Override {{> yield}} and {{#contentFor}} to find the closest
// enclosing layout
var origLookup = UI.Component.lookup;
UI.Component.lookup = function (id, opts) {
if (id === 'yield') {
throw new Error("Sorry, would you mind using {{> yield}} instead of {{yield}}? It helps the Blaze engine.");
} else if (id === 'contentFor') {
var layout = findComponentOfKind('Layout', this);
console.log(id, layout, this)
if (!layout)
throw new Error("Couldn't find a Layout component in the rendered component tree");
else {
return layout[id];
}
} else {
return origLookup.apply(this, arguments);
}
};

var origLookupTemplate = UI.Component.lookupTemplate;
UI.Component.lookupTemplate = function (id, opts) {
if (id === 'yield') {
var layout = findComponentOfKind('Layout', this);
if (!layout)
throw new Error("Couldn't find a Layout component in the rendered component tree");
else {
return layout[id];
}
} else {
return origLookupTemplate.apply(this, arguments);
}
};

if (Package['iron-router']) {
Package['iron-router'].Router.configure({
uiManager: new BlazeUIManager
});
}
104 changes: 0 additions & 104 deletions overrides.js

This file was deleted.

1 change: 0 additions & 1 deletion package.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Package.on_use(function (api) {
api.use('deps-ext');

api.add_files('layout.js', 'client');
api.add_files('overrides.js', 'client');
api.export('Layout', 'client');
});

Expand Down