Re: [T5] Injecting page into nested layouts
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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [T5] Injecting page into nested layouts
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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [T5] Injecting page into nested layouts
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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [T5] Injecting page into nested layouts
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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [T5] Injecting page into nested layouts
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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [T5] Injecting page into nested layouts
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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]