You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Andrew Robinson <an...@gmail.com> on 2006/05/30 17:34:36 UTC

t:div vs. other components and rendering with buffer

I am trying to use a custom component that needs to output its source
at the bottom of the page for HTML reasons. I created the component
and had it use the HtmlBufferResponseWriterWrapper class to buffer the
output so I could delay the output until a custom component at the end
of the page could render the contents.

Most things are working except for t:div and some of my custom
components that extend it (org.apache.myfaces.custom.div.Div).

What happens is that the tag is rendered, but the contents are not.
Here is the component tree I used for testing

<my:custom>
  <t:div>A<t:div>B</t:div>C</t:div>
  <div>D<div>E</div>F</div>
  <t:panelGroup styleClass="test">
    G<t:panelGroup styleClass="test">H</t:panelGroup>I
  </t:panelGroup>
</my:custom>

<!-- render the custom controls from the buffer here -->

The output I get is:

<!-- custom start HTML -->
<div></div>
<div>D<div>E</div>F</div>
<span class="test">G<span class="test">H</span>I</span>

The "normal" DIV tags are fine, the panel group components are fine,
it is just the DIV components that skip the rendering of their
children.

In my custom component renderer, I am returning true for
getRendersChildren() and letting Renderer to take care of the default
children rendering.

Relavent JARs in my environment:
MyFaces Core 1.1.3
MyFaces Tomahawk 1.1.2
Facelets 1.0.14

Any idea why the t:div is not rendering it's children/content?

Thanks,
Andrew

Re: t:div vs. other components and rendering with buffer

Posted by Andrew Robinson <an...@gmail.com>.
Nevermind, found the answer (if the control doesn't encode the
children, the parent must). Looks like what I want to use is already
available in a static method at:

org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils.renderChildren(FacesContext,
UIComponent)

-Andrew

On 5/30/06, Andrew Robinson <an...@gmail.com> wrote:
> I think I found the issue, but I have no idea why. Here is the
> renderer hierarchy:
>
> javax.faces.render.Renderer
> org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer
> org.apache.myfaces.custom.htmlTag.HtmlTagRenderer
>
> No where in this heirarchy is "getRendersChildren" overridden to
> return true. As a result, the children are not rendered in my case. I
> don't know why (please feel free to fill me in), why when not in my
> custom component, the children are rendered, but not when in my custom
> component.
>
> The standard renderer code is (paraphrased):
> public void encodeChildren(FacesContext context, UIComponent component)
>   throws IOException {
>    ...
>    if (child.getRendersChildren())
>      child.encodeChildren(context);
>    ...
>
> So I don't know how t:div's children are ever rendered. According to
> this code, children of a component only should be rendered if the
> component, or the component's rendered returns true for
> getRendersChildren.
>
> Is this a bug, or have I missed something in the JSF spec? It looks
> like a bug to me in HtmlTagRenderer, but I wanted to make sure first.
>
> Thanks,
> Andrew
>
>
>
> On 5/30/06, Andrew Robinson <an...@gmail.com> wrote:
> > I am trying to use a custom component that needs to output its source
> > at the bottom of the page for HTML reasons. I created the component
> > and had it use the HtmlBufferResponseWriterWrapper class to buffer the
> > output so I could delay the output until a custom component at the end
> > of the page could render the contents.
> >
> > Most things are working except for t:div and some of my custom
> > components that extend it (org.apache.myfaces.custom.div.Div).
> >
> > What happens is that the tag is rendered, but the contents are not.
> > Here is the component tree I used for testing
> >
> > <my:custom>
> >   <t:div>A<t:div>B</t:div>C</t:div>
> >   <div>D<div>E</div>F</div>
> >   <t:panelGroup styleClass="test">
> >     G<t:panelGroup styleClass="test">H</t:panelGroup>I
> >   </t:panelGroup>
> > </my:custom>
> >
> > <!-- render the custom controls from the buffer here -->
> >
> > The output I get is:
> >
> > <!-- custom start HTML -->
> > <div></div>
> > <div>D<div>E</div>F</div>
> > <span class="test">G<span class="test">H</span>I</span>
> >
> > The "normal" DIV tags are fine, the panel group components are fine,
> > it is just the DIV components that skip the rendering of their
> > children.
> >
> > In my custom component renderer, I am returning true for
> > getRendersChildren() and letting Renderer to take care of the default
> > children rendering.
> >
> > Relavent JARs in my environment:
> > MyFaces Core 1.1.3
> > MyFaces Tomahawk 1.1.2
> > Facelets 1.0.14
> >
> > Any idea why the t:div is not rendering it's children/content?
> >
> > Thanks,
> > Andrew
> >
>

Re: t:div vs. other components and rendering with buffer

Posted by Andrew Robinson <an...@gmail.com>.
I think I found the issue, but I have no idea why. Here is the
renderer hierarchy:

javax.faces.render.Renderer
org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer
org.apache.myfaces.custom.htmlTag.HtmlTagRenderer

No where in this heirarchy is "getRendersChildren" overridden to
return true. As a result, the children are not rendered in my case. I
don't know why (please feel free to fill me in), why when not in my
custom component, the children are rendered, but not when in my custom
component.

The standard renderer code is (paraphrased):
public void encodeChildren(FacesContext context, UIComponent component)
  throws IOException {
   ...
   if (child.getRendersChildren())
     child.encodeChildren(context);
   ...

So I don't know how t:div's children are ever rendered. According to
this code, children of a component only should be rendered if the
component, or the component's rendered returns true for
getRendersChildren.

Is this a bug, or have I missed something in the JSF spec? It looks
like a bug to me in HtmlTagRenderer, but I wanted to make sure first.

Thanks,
Andrew



On 5/30/06, Andrew Robinson <an...@gmail.com> wrote:
> I am trying to use a custom component that needs to output its source
> at the bottom of the page for HTML reasons. I created the component
> and had it use the HtmlBufferResponseWriterWrapper class to buffer the
> output so I could delay the output until a custom component at the end
> of the page could render the contents.
>
> Most things are working except for t:div and some of my custom
> components that extend it (org.apache.myfaces.custom.div.Div).
>
> What happens is that the tag is rendered, but the contents are not.
> Here is the component tree I used for testing
>
> <my:custom>
>   <t:div>A<t:div>B</t:div>C</t:div>
>   <div>D<div>E</div>F</div>
>   <t:panelGroup styleClass="test">
>     G<t:panelGroup styleClass="test">H</t:panelGroup>I
>   </t:panelGroup>
> </my:custom>
>
> <!-- render the custom controls from the buffer here -->
>
> The output I get is:
>
> <!-- custom start HTML -->
> <div></div>
> <div>D<div>E</div>F</div>
> <span class="test">G<span class="test">H</span>I</span>
>
> The "normal" DIV tags are fine, the panel group components are fine,
> it is just the DIV components that skip the rendering of their
> children.
>
> In my custom component renderer, I am returning true for
> getRendersChildren() and letting Renderer to take care of the default
> children rendering.
>
> Relavent JARs in my environment:
> MyFaces Core 1.1.3
> MyFaces Tomahawk 1.1.2
> Facelets 1.0.14
>
> Any idea why the t:div is not rendering it's children/content?
>
> Thanks,
> Andrew
>