What you're trying to do is quite common and always works fine in my experience. In fact this sort of composition is preferred over having a shared base class. I often have a main "Layout" component along with more specialized layout components for different sections of a site (e.g., AuthenticatedLayout"), each of which wraps itself in the main Layout component. The naming is backward from yours, but it's the same idea. The nesting of layout components is really just using Tapestry's basic ability to nest components in general.
Can you show us the first few lines of TML from your main pagelayout component and your nested layout component? On Mon, Oct 15, 2018, 6:13 AM Chris Poulsen <mailingl...@nesluop.dk> wrote: > Hi > > I'm trying to improve on the layout we are using across several tapestry > based products. > Initially it used an abstract base layout component that the products > extend to provide a common line for the layout. > > I'm trying to simplify this situation by making the layout in the framework > module a concrete component (lets call it pagelayout), that wrap its t:body > in <html> etc. > > Each product creates its own layout (called layout) component that provides > the specific menu, topbar etc. and then wraps itself in the layout from the > framework module. > > Ordinary pages has t:type=layout in their root element to wrap themselves > in the product layout component, which in turn has t:type=pagelayout on its > root element to wrap itself in the framework layout providing the > surrounding html tag. > > According to the documentation ( > > https://tapestry.apache.org/layout-component.html#LayoutComponent-NestedLayouts > ) > this should not be an issue. > > However when I try to render one of these pages tapestry complains with: > > Caused by: java.lang.RuntimeException: The root element of the rendered > document was <div>, not <html>. A root element of <html> is needed when > linking JavaScript and stylesheet resources. > at > > org.apache.tapestry5.internal.services.DocumentLinkerImpl.addScriptElements(DocumentLinkerImpl.java:179) > at > > org.apache.tapestry5.internal.services.DocumentLinkerImpl.updateDocument(DocumentLinkerImpl.java:140) > at > > org.apache.tapestry5.modules.TapestryModule$25.renderMarkup(TapestryModule.java:1752) > at $MarkupRenderer_1760ef286199e.renderMarkup(Unknown Source) > at > > com.dezide.author.tapestry.DeferredDialogFilter.renderMarkup(DeferredDialogFilter.java:21) > at $MarkupRendererFilter_1760ef286199c.renderMarkup(Unknown Source) > at $MarkupRenderer_1760ef286199e.renderMarkup(Unknown Source) > at $MarkupRenderer_1760ef2861999.renderMarkup(Unknown Source) > at > > org.apache.tapestry5.internal.services.PageMarkupRendererImpl.renderPageMarkup(PageMarkupRendererImpl.java:47) > at $PageMarkupRenderer_1760ef2861997.renderPageMarkup(Unknown > Source) > at > > org.apache.tapestry5.internal.services.PageResponseRendererImpl.renderPageResponse(PageResponseRendererImpl.java:64) > at $PageResponseRenderer_1760ef28618e2.renderPageResponse(Unknown > Source) > at > > org.apache.tapestry5.internal.services.PageRenderRequestHandlerImpl.handle(PageRenderRequestHandlerImpl.java:72) > at > > org.apache.tapestry5.modules.TapestryModule$34.handle(TapestryModule.java:1974) > at $PageRenderRequestHandler_1760ef28618e4.handle(Unknown Source) > at $PageRenderRequestHandler_1760ef28618d3.handle(Unknown Source) > at > > org.apache.tapestry5.internal.services.ComponentRequestHandlerTerminator.handlePageRender(ComponentRequestHandlerTerminator.java:48) > at > > org.apache.tapestry5.internal.services.DeferredResponseRenderer.handlePageRender(DeferredResponseRenderer.java:52) > at $ComponentRequestHandler_1760ef28618d4.handlePageRender(Unknown > Source) > at > > org.apache.tapestry5.services.InitializeActivePageName.handlePageRender(InitializeActivePageName.java:47) > at $ComponentRequestHandler_1760ef28618d4.handlePageRender(Unknown > Source) > at > > org.apache.tapestry5.internal.services.RequestOperationTracker$2.run(RequestOperationTracker.java:73) > at > > org.apache.tapestry5.ioc.internal.OperationTrackerImpl.run(OperationTrackerImpl.java:56) > ... 151 more > > The document linker root is the output of rendering the specific page (it > may have wrapped the Layout around it, but it is hard to tell as that one > only provides shared configuration of the pagelayout. > > Has anyone successfully used nested layouts like this? The documentation > seems to suggest it should work, but I've tried a lot of different > constructs without success. > > -- > Best regards > Chris >