Has anyone tried nesting "toplevel" layout components successfully?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Has anyone tried nesting "toplevel" layout components successfully?

Chris Poulsen
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
Reply | Threaded
Open this post in threaded view
|

Re: Has anyone tried nesting "toplevel" layout components successfully?

bobharner
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 <[hidden email]> 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
>
Reply | Threaded
Open this post in threaded view
|

Re: Has anyone tried nesting "toplevel" layout components successfully?

Chris Poulsen
Hi

Thanks for the input.

I agree with your points and my experience is also that mostly things just
work or you are provided with a helpful error (my naming is to avoid having
to change all the pages that currently refers to "layout" while testing ;)

I have managed to get it to work. I had screwed up somewhere along the way
and managed to not create PageLayout class/tml in the same path in the
final output. It was apparently "working enough" to make it hard to see
what was actually wrong.

Sorry for the noise

--
Chris

On Mon, Oct 15, 2018 at 1:12 PM Bob Harner <[hidden email]> wrote:

> 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 <[hidden email]>
> 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
> >
>