You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by ownedthx <se...@gmail.com> on 2009/06/05 22:36:49 UTC

Stuck on implementing recursion (or something like it) cleanly

Yesterday I opened a feature request for recursive components,
https://issues.apache.org/jira/browse/TAP5-739, and had it closed for the
reasons described there (basically, 'not possible').

First of all, thanks Thiago for taking the time to describe the issue and
the pointer to a technique as a workaround.

Here's my question about the suggested workaround (which I'll call the 'use
MarkupWriter' technique).  I have two reasons why I want to avoid a
markupwriter:

1) We have many components already designed that fit in a tree structure (10
now, but easily 200 later).  We would like to have the template in a tml
file, so that a UI designer can contribute without being a Java expert on
our numerous templates.

2) More importantly, components allow us to associate behavior (ajax, forms,
actionlinks, etc) with our components in a very clean, modular way.  

With a MarkupWriter technique, I believe we lose both.  

Does anyone have any suggestions as to how we can pull off recursion of
components (or something like it), while achieving #1 and #2?

Thanks for any help,

Seth
-- 
View this message in context: http://n2.nabble.com/Stuck-on-implementing-recursion-%28or-something-like-it%29-cleanly-tp3032700p3032700.html
Sent from the Tapestry Users 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: Stuck on implementing recursion (or something like it) cleanly

Posted by ownedthx <se...@gmail.com>.
Thanks for responding Denis,

Your approach (markup writer approach) will get the HTML out and to  
the client, but it still doesn't help much with problems #1 and #2,  
right?

As an update to the list, I'l explain what we are having to do to get  
at least close to achieving #1 and #2. You'll see it's very ugly, from  
a template perspective.

We have an iterator  that indicates when a node is being visited and  
being left (going down and going up the tree, respectively). So, as an  
example, if there is only one node in the tree, the iterator hits  
twice--the first time it indicates that the node is being visited, and  
the second it indicates that the visit is over.   We invoke the  
template of the node every iteration, indicating to the template if  
it's the begin visit or end visit.

Because there is this simple NodeVisitor-like pattern, each component  
of ours is extended from a base component that defines two extension- 
points, 'start' and 'end'.

Base Component
------------------------

<?xml version="1.0" encoding="UTF-8"?>
<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd 
">

     <t:if test="begin">
         <t:extension-point id="start"></t:extension-point>
     </t:if>

     <t:if test="end">
         <t:extension-point id="end"></t:extension-point>
     </t:if>

</t:container>

Here's where it gets ugly... because you have to jump through one hoop  
or another to avoid malformed markup, this is what our actual  
component templates look like (the hoop in this case is using  
outputRaw to serialize the <p> and </p> tags, which can not be written  
directly into the template because they would make the template  
malformed):

<?xml version="1.0" encoding="UTF-8"?>
<t:extend xmlns:t="http://tapestry.apache.org/schema/ 
tapestry_5_1_0.xsd">

     <t:replace id="start">

         <t:outputRaw value="literal:&lt;p&gt;" />

         a brown fox

     </t:replace>


     <t:replace id="end">

         runs through field

         <t:outputRaw value="literal:&lt;/p&gt;"/>

     </t:replace>

</t:extend>

The output of visiting just that node would be two renderings of the  
component per node--first the 'start' extension would render, then the  
'end' extension. For example, if we had just a one node tree, this  
would be the flow:

start iteration
-----------------
<p> a brown fox

end iteration
-----------------
runs through the field </p>

resulting in : <p> a brown fox runs through the field </p>


I'm not at all happy with this--but in trying to truly achieve #1 (put  
all markup in templates), and #2 (have a component for each node type  
in our tree to take advantage of behavior and modularization), this is  
the best we've come up with.


If anyone has any suggestions, I'd be all ears!

Seth



On Jun 6, 2009, at 7:12 AM, DenisS (via Nabble) wrote:

> Hi Seth,
>
> I have created Tree component http://pastebin.com/m134af976 for the  
> same purpose, basically you need to transform recursion to iteration.
>
> <div class="treeItem" t:type="tree" t:value="treeItem"  
> t:children="treeItem.children">
>     ...tree item body...
> </div>
>
> output will be:
>
> <div class="treeItem">
> ...tree item body...
> <ul>
>    <li>
>         <div class="treeItem">...tree item body... <ul><li>...</li></ 
> ul></div>
>    </li>
>    <li>
>         <div class="treeItem">...tree item body... <ul><li>...</li></ 
> ul></div>
>    </li>
> </ul>
> </div>
>
> Denis
>
> This email is a reply to your post @ http://n2.nabble.com/Stuck-on-implementing-recursion-%28or-something-like-it%29-cleanly-tp3032700p3035136.html
> You can reply by email or by visting the link above.
>


-- 
View this message in context: http://n2.nabble.com/Stuck-on-implementing-recursion-%28or-something-like-it%29-cleanly-tp3032700p3035508.html
Sent from the Tapestry Users mailing list archive at Nabble.com.

Re: Stuck on implementing recursion (or something like it) cleanly

Posted by DenisS <de...@gmail.com>.
Hi Seth,

I have created Tree component http://pastebin.com/m134af976 for the same
purpose, basically you need to transform recursion to iteration.

<div class="treeItem" t:type="tree" t:value="treeItem"
t:children="treeItem.children"> 
    ...tree item body...
</div>

output will be:

<div class="treeItem">
...tree item body...
<ul>
   <li>
        <div class="treeItem">...tree item body...
<ul><li>...</li></ul></div>
   </li>
   <li>
        <div class="treeItem">...tree item body...
<ul><li>...</li></ul></div>
   </li>
</ul>
</div>

Denis
-- 
View this message in context: http://n2.nabble.com/Stuck-on-implementing-recursion-%28or-something-like-it%29-cleanly-tp3032700p3035136.html
Sent from the Tapestry Users 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: Stuck on implementing recursion (or something like it) cleanly

Posted by ownedthx <se...@gmail.com>.
A coworker of mine with much Tapesty-fu seems to have figured out a much more
elegant solution today. (this issue has blocked most of the team, so we both
attacked this problem simultaneously).  He blogged about it here:
http://blog.bolkey.com/2009/06/06/tapestry-5-recursive-tree/

The short of it is, you have to use <t:body> delegates in the tree
templates, and when you declare the component, be sure to put down a
delegate, go give the inner logic a chance to continue to walk the tree, and
fiddle around with the before/after BodyRender methods.   Also, caching was
a bit of a problem until he learned to turn it off...

Anyway, thanks all,
Seth


ownedthx wrote:
> 
> Yesterday I opened a feature request for recursive components,
> https://issues.apache.org/jira/browse/TAP5-739, and had it closed for the
> reasons described there (basically, 'not possible').
> 
> First of all, thanks Thiago for taking the time to describe the issue and
> the pointer to a technique as a workaround.
> 
> Here's my question about the suggested workaround (which I'll call the
> 'use MarkupWriter' technique).  I have two reasons why I want to avoid a
> markupwriter:
> 
> 1) We have many components already designed that fit in a tree structure
> (10 now, but easily 200 later).  We would like to have the template in a
> tml file, so that a UI designer can contribute without being a Java expert
> on our numerous templates.
> 
> 2) More importantly, components allow us to associate behavior (ajax,
> forms, actionlinks, etc) with our components in a very clean, modular way.  
> 
> With a MarkupWriter technique, I believe we lose both.  
> 
> Does anyone have any suggestions as to how we can pull off recursion of
> components (or something like it), while achieving #1 and #2?
> 
> Thanks for any help,
> 
> Seth
> 

-- 
View this message in context: http://n2.nabble.com/Stuck-on-implementing-recursion-%28or-something-like-it%29-cleanly-tp3032700p3036739.html
Sent from the Tapestry Users 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