You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Richard Hoberman <ri...@sadalbari.com> on 2008/08/18 12:14:03 UTC
[T5] Injecting page into nested layouts
Hi
I'm getting the following exception:
Component TestPage:innerlayout is not assignable to field
test.components.Layout.page (of type test.BasePage).
The skeletons for my components are below. Essentially, my page has an
(inner) layout, which in turn has an (outer) layout. I try to inject the
page into both (inner and outer) layouts.
The page is successfully injected into the inner layout, but the outer
fails. @InjectContainer seems to be selecting the wrong component in this
case. It makes no difference if I remove the injection for the inner layout
(so it doesn't seem to be a conflict).
Should this work?
Richard Hoberman
Page template:
-----------------
<html t:type="InnerLayout" ...>
//page contents
</html>
Inner layout template:
--------------------------
<html t:type="Layout" ...>
//inner layout markup including <t:body />
</html>
Layout template:
--------------------
<html ...>
//layout markup including <t:body />
</html>
Inner Layout class:
----------------------
public class InnerLayout extends BaseComponent {
@InjectContainer
@Property
private BasePage page;
//etc
}
Layout class:
---------------
public class InnerLayout extends BaseComponent {
@InjectContainer
@Property
private BasePage page;
//etc
}
--
View this message in context: http://www.nabble.com/-T5--Injecting-page-into-nested-layouts-tp19028771p19028771.html
Sent from the Tapestry - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: [T5] Injecting page into nested layouts
Posted by "Filip S. Adamsen" <fs...@fsadev.com>.
Hi,
> You're right - casting componentResources#getPage works fine.
ComponentResources is your friend. :)
>> @InjectContainer does indeed inject the "parent" of the component. For
>> InnerLayout this is the page alright, but for Layout it's actually the
>> InnerLayout because Layout is contained in InnerLayout.
>
> Could you clarify the meaning of 'contained'?
I think ComponentResources#getContainer has the best explanation:
"Returns the component which contains this component, or null for the
root component. For mixins, this returns the componet to which the mixin
is attached."
I probably shouldn't have used the word "parent", it's a bit confusing
in this context.
> From an html point of view
> (and I assume a component tree point of view), the hierarchy of my page is:
>
> Page
> +-- Layout
> +-- InnerLayout
That is correct.
> However, if "Layout is contained in InnerLayout" means "InnerLayout.tml
> references Layout.tml" then the 'reference' hierarchy is:
>
> Page
> +-- InnerLayout
> +-- Layout
Also correct.
> Should I be reading "InjectContainer" as
> "InjectTheComponentWhoseTemplateContainsTheContentsToBeInsertedAsBody"? If
> so, perhaps @InjectContentProvider would be more intuitive?
No, just InjectTheComponentWhoseTemplateContainsThisComponent.
> Is there any documentation on @InjectContainer? I've searched the Tapestry
> site and Wiki but found nothing.
Here are the relevant docs:
http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/annotations/InjectContainer.html
http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/ComponentResources.html#getContainer()
InjectContainer should probably have its description updated to match
ComponentResources#getContainer. I'll file a JIRA issue.
Hope this helps. If not, you know what to do. ;)
-Filip
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: [T5] Injecting page into nested layouts
Posted by Richard Hoberman <ri...@sadalbari.com>.
You're right - casting componentResources#getPage works fine.
> @InjectContainer does indeed inject the "parent" of the component. For
> InnerLayout this is the page alright, but for Layout it's actually the
> InnerLayout because Layout is contained in InnerLayout.
Could you clarify the meaning of 'contained'? From an html point of view
(and I assume a component tree point of view), the hierarchy of my page is:
Page
+-- Layout
+-- InnerLayout
However, if "Layout is contained in InnerLayout" means "InnerLayout.tml
references Layout.tml" then the 'reference' hierarchy is:
Page
+-- InnerLayout
+-- Layout
Should I be reading "InjectContainer" as
"InjectTheComponentWhoseTemplateContainsTheContentsToBeInsertedAsBody"? If
so, perhaps @InjectContentProvider would be more intuitive?
Is there any documentation on @InjectContainer? I've searched the Tapestry
site and Wiki but found nothing.
--
View this message in context: http://www.nabble.com/-T5--Injecting-page-into-nested-layouts-tp19028771p19046282.html
Sent from the Tapestry - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: [T5] Injecting page into nested layouts
Posted by "Filip S. Adamsen" <fs...@fsadev.com>.
Hi again,
> That's a typo. The Layout class name should read 'Layout' and not
> 'InnerLayout' but the relevant code is the same.
Ah, okay.
>> A potential solution would be to use ComponentResources#getPage to get
>> your page in a getter and just use that in your layout.
>
> Unfortunately, that won't work. CompontResources#getPage returns
> (org.apache.tapestry5.runtime.)Component, which doesn't expose the page's
> properties. (See Howard's post at:
> http://www.nabble.com/Re%3A--T5--Expansions---calling-page-methods-via-componentResources-p19006392.html)
It works if you cast it:
@Inject
private ComponentResources resources;
public BasePage getPage() {
return (BasePage) resources.getPage();
}
It just doesn't work directly with property expressions like
${resources.page}.
> I'm a bit confused by the terminology. I can't seem to find the docs on
> @InjectContainer, but I assumed it injected the 'parent' of the component,
> because the page is the root of the component tree. Now now it seems that
> it injects the contents of the layout?
@InjectContainer does indeed inject the "parent" of the component. For
InnerLayout this is the page alright, but for Layout it's actually the
InnerLayout because Layout is contained in InnerLayout.
The exception states this as well, this is what I missed the first time
through:
"Component TestPage:innerlayout is not assignable to field
test.components.Layout.page (of type test.BasePage)."
So the component innerlayout in the page TestPage is not assignable to
the field page in Layout - because Layout expects page to be of type
BasePage.
> There must be a way to do this...
See above. Just use ComponentResources and cast it, simple as that.
> Richard
-Filip
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: [T5] Injecting page into nested layouts
Posted by Richard Hoberman <ri...@sadalbari.com>.
Hi Filip
That's a typo. The Layout class name should read 'Layout' and not
'InnerLayout' but the relevant code is the same.
> A potential solution would be to use ComponentResources#getPage to get
> your page in a getter and just use that in your layout.
Unfortunately, that won't work. CompontResources#getPage returns
(org.apache.tapestry5.runtime.)Component, which doesn't expose the page's
properties. (See Howard's post at:
http://www.nabble.com/Re%3A--T5--Expansions---calling-page-methods-via-componentResources-p19006392.html)
I'm a bit confused by the terminology. I can't seem to find the docs on
@InjectContainer, but I assumed it injected the 'parent' of the component,
because the page is the root of the component tree. Now now it seems that
it injects the contents of the layout?
There must be a way to do this...
Richard
--
View this message in context: http://www.nabble.com/-T5--Injecting-page-into-nested-layouts-tp19028771p19034207.html
Sent from the Tapestry - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: [T5] Injecting page into nested layouts
Posted by "Filip S. Adamsen" <fs...@fsadev.com>.
Hi,
Looking over your code again I just noticed something's amiss. Where's
the Java code for the Layout class? You seem to have posted the
InnerLayout class twice.
Anyhow, I think I've figured out what's really going on. Your using
InjectContainer in Layout, but that doesn't inject the page, it injects
the InnerLayout. This, of course, fails.
A potential solution would be to use ComponentResources#getPage to get
your page in a getter and just use that in your layout.
-Filip
On 2008-08-18 15:30, Filip S. Adamsen wrote:
> Hi,
>
> Your BasePage should be in the base subpackage, that's test.base in your
> case. What happens is that Tapestry tries to cast BasePage to Component,
> which fails because it hasn't been enhanced by Tapestry - this only
> happens for components in the base, components, and page subpackages.
>
> That's my (more or less informed) guess having checked the source of
> InjectContainerWorker, anyhow.
>
> -Filip
>
> On 2008-08-18 12:14, Richard Hoberman wrote:
>> Hi
>>
>> I'm getting the following exception:
>>
>> Component TestPage:innerlayout is not assignable to field
>> test.components.Layout.page (of type test.BasePage).
>>
>> The skeletons for my components are below. Essentially, my page has an
>> (inner) layout, which in turn has an (outer) layout. I try to inject the
>> page into both (inner and outer) layouts.
>>
>> The page is successfully injected into the inner layout, but the outer
>> fails. @InjectContainer seems to be selecting the wrong component in
>> this
>> case. It makes no difference if I remove the injection for the inner
>> layout
>> (so it doesn't seem to be a conflict).
>>
>> Should this work?
>>
>> Richard Hoberman
>>
>> Page template:
>> -----------------
>> <html t:type="InnerLayout" ...>
>>
>> //page contents
>> </html>
>>
>> Inner layout template:
>> --------------------------
>>
>> <html t:type="Layout" ...>
>>
>> //inner layout markup including <t:body />
>>
>> </html>
>>
>> Layout template:
>> --------------------
>>
>> <html ...>
>>
>> //layout markup including <t:body />
>>
>> </html>
>>
>> Inner Layout class:
>> ----------------------
>> public class InnerLayout extends BaseComponent {
>>
>> @InjectContainer
>> @Property
>> private BasePage page;
>> //etc
>> }
>>
>> Layout class:
>> ---------------
>> public class InnerLayout extends BaseComponent {
>>
>> @InjectContainer
>> @Property
>> private BasePage page;
>> //etc
>> }
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: [T5] Injecting page into nested layouts
Posted by "Filip S. Adamsen" <fs...@fsadev.com>.
Hi,
Your BasePage should be in the base subpackage, that's test.base in your
case. What happens is that Tapestry tries to cast BasePage to Component,
which fails because it hasn't been enhanced by Tapestry - this only
happens for components in the base, components, and page subpackages.
That's my (more or less informed) guess having checked the source of
InjectContainerWorker, anyhow.
-Filip
On 2008-08-18 12:14, Richard Hoberman wrote:
> Hi
>
> I'm getting the following exception:
>
> Component TestPage:innerlayout is not assignable to field
> test.components.Layout.page (of type test.BasePage).
>
> The skeletons for my components are below. Essentially, my page has an
> (inner) layout, which in turn has an (outer) layout. I try to inject the
> page into both (inner and outer) layouts.
>
> The page is successfully injected into the inner layout, but the outer
> fails. @InjectContainer seems to be selecting the wrong component in this
> case. It makes no difference if I remove the injection for the inner layout
> (so it doesn't seem to be a conflict).
>
> Should this work?
>
> Richard Hoberman
>
> Page template:
> -----------------
> <html t:type="InnerLayout" ...>
>
> //page contents
>
> </html>
>
> Inner layout template:
> --------------------------
>
> <html t:type="Layout" ...>
>
> //inner layout markup including <t:body />
>
> </html>
>
> Layout template:
> --------------------
>
> <html ...>
>
> //layout markup including <t:body />
>
> </html>
>
> Inner Layout class:
> ----------------------
> public class InnerLayout extends BaseComponent {
>
> @InjectContainer
> @Property
> private BasePage page;
>
> //etc
> }
>
> Layout class:
> ---------------
> public class InnerLayout extends BaseComponent {
>
> @InjectContainer
> @Property
> private BasePage page;
>
> //etc
> }
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org