You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by mem <me...@gmail.com> on 2012/07/06 10:22:22 UTC

How to resolve the rendered component in a mixin

Hello,

i'd like to extend some components with the ability to render certain nodes
with an additional attribute which is then picked up in JS and used as a
keybinding for shortcuts.
So far i created a mixin which i preferably would like to put on any kind of
component, in case of an EventLink it should simply render:
link 
instead of:
link 
This works like expected but a problem comes up with components that contain
components, for example:
public class MyComponent
{
    @Component(//parameters)
    private EventLink edit;

    ... more stuff in here
}

Now i'd like to use 'MyComponent' on different pages where on some pages i'd
like to use the mixin whereas on others i don't. I also don't want to change
the component and add the mixin in the component and a parameter to control
if it should be active or not.
When debugging i found the rendered elements are available in class
RenderQueueImpl in the Stack<ComponentResources> renderingComponents, other
than that i couldn't find any appearance and don't know if or how to inject
or access the element.
I'd like to pass the component name and optionally the container
component(s) in a fashion like:
'myComponent.edit' where myComponent is the variable name as in:
@Component
private MyComponent myComponent;
to my mixin.
Is there any way i can filter the rendered element in the render phases?

@BeginRender
    void beginRender(final MarkupWriter markupWriter)
    {
        markupWriter.addListener(new MarkupWriterListener()
        {
            @Override
            public void elementDidEnd(final Element element)
            {
                /**
                  * here i'd like to put my if(element == parameter)
                  * where element is the currently rendered component
                  * and parameter is the passed parameter somhow in the
                  * fashion of containerName.componentName
                  */
                element.attribute(ATTRIBUTE_NAME, shortcut);
            }

            @Override
            public void elementDidStart(Element element)
            {
            }
        });
    }

--
View this message in context: http://tapestry.1045711.n5.nabble.com/How-to-resolve-the-rendered-component-in-a-mixin-tp5714315.html
Sent from the Tapestry - User 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: How to resolve the rendered component in a mixin

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
Answering the question in the subject:

@InjectContainer
private Object parent;

Actually, you can use any type you want, but an exception will be thrown  
if it the parent component isn't assignable to the field.

-- 
Thiago H. de Paula Figueiredo

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: How to resolve the rendered component in a mixin

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Mon, 09 Jul 2012 06:41:01 -0300, mem <me...@gmail.com>  
wrote:

> I'd like to know the variable name of the currently rendered  
> *SUB*component in the afterRender method of my mixin.
> So when myComponent (which contains i.e. an EventLink component) is  
> rendered i can influence all it's containing subcomponents, my problem  
> is that i
> don't know which subcomponent is which.

Notice you're doing a very non-Tapestry-ish thing here: components are  
supposed to be black boxes. You can @Inject ComponentResources and use its  
get*Component() methods recursively to pass though all the components, but  
again this is something you shouldn't do. To do communication between one  
component and another that can't be done by parameters, you should use the  
Environment, as Lance said.

> The reason for this is described above but in short i want the user of  
> the mixin to specify the filtering criteria so we can put the mixin on a  
> higher level than only on the affected component directly.

You should write a component transformation and have this filtering logic  
(apply the mixin or not to a component) written there instead. Taha has  
one example here:  
http://tawus.wordpress.com/2011/08/01/tapestry-mixins-classtransformations/.  
Jump directly to the HelpTextMixinWorker example, as you won't need the  
code before that for what you want to do.

That's exactly why we, in this mailing list, like to see people describing  
in a higher lever what they want instead of saying how to do x using y.  
You may be going through a wrong path due to not knowing yet there's a  
better one. :)

-- 
Thiago H. de Paula Figueiredo

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: How to resolve the rendered component in a mixin

Posted by mem <me...@gmail.com>.
I'd like to know the variable name of the currently rendered *SUB*component
in the afterRender method of my mixin.
So when myComponent (which contains i.e. an EventLink component) is rendered
i can influence all it's containing subcomponents, my problem is that i
don't know which subcomponent is which.
If myComponent contains 5 EventLinks i can't differ which EventLink is
which. I don't want to distinguish them by content, i'd much rather
distinguish by variable name and if possible even by container.variable in
case there's a variable name used multiple times in any nested component(s).
The reason for this is described above but in short i want the user of the
mixin to specify the filtering criteria so we can put the mixin on a higher
level than only on the affected component directly.



--
View this message in context: http://tapestry.1045711.n5.nabble.com/How-to-resolve-the-rendered-component-in-a-mixin-tp5714315p5714351.html
Sent from the Tapestry - User 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: How to resolve the rendered component in a mixin

Posted by Lance Java <la...@googlemail.com>.
I'm not 100% sure exactly what you are trying to achieve but I think that you
should use an environmental object to communicate between the mixin and the
component.

The mixin could push() an object onto the environment in beforeRender(). The
component then peek()s for the object and sets some values on it if it is
available. The mixin then pop()s the object from the environment (ag
afterRender()) and does some decoration based on the values.

NB. If you want mixin render phases to occur after the component's render
phases, use the @MixinAfter annotation.

http://tapestry.apache.org/environmental-services.html

--
View this message in context: http://tapestry.1045711.n5.nabble.com/How-to-resolve-the-rendered-component-in-a-mixin-tp5714315p5714349.html
Sent from the Tapestry - User 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: How to resolve the rendered component in a mixin

Posted by mem <me...@gmail.com>.
@Muhammad:
No, not exactly.
I'd need a reference not necessarily to the component to which the mixin is
applied but rather to all it's rendering subcomponents. Like in the example
in my first post the myComponent could contain a zone which again contains
i.e. an anchor tag where the var is named edit. When applying my mixin i'd
like to specify it somehow like the following on one page:

...
@MixinClasses({SomeMixin.class})
@Component(parameters={"attrName=something", "attrValue=x", "pattern=edit"})
private MyComponent myComponent;

Where on another page i might have something like this:

@MixinClasses({SomeMixin.class})
@Component(parameters={"attrName=something", "attrValue=y"})
private LinkSubmit submit;

or this (MyParentComponent contains myComponent):

@MixinClasses({SomeMixin.class})
@Component(parameters={"attrName=something", "attrValue=z",
"pattern=myComponent.edit"})
private MyParentComponent myParentComponent;


So the pattern parameter should be optional and i'd like to use it in the
mixin in the begin/afterRender to check if the attribute should be applied
to the currently rendered component.


@Thiago:
I tried to inject the container already but i didn't find any method which
would assist me with the currently rendered subcomponent, the container
itself isn't what i need. I also tried and looked at ComponentResources and
JSSupport.

--
View this message in context: http://tapestry.1045711.n5.nabble.com/How-to-resolve-the-rendered-component-in-a-mixin-tp5714315p5714348.html
Sent from the Tapestry - User 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: How to resolve the rendered component in a mixin

Posted by Muhammad Gelbana <m....@gmail.com>.
I'm not sure if I understood your requirement correctly but I think you
need to have a reference to the element on which the mixin is applied,
correct ?

You can use this:

@InjectContainer
> private ClientElement clientElement;



On Fri, Jul 6, 2012 at 10:22 AM, mem <me...@gmail.com> wrote:

> Hello,
>
> i'd like to extend some components with the ability to render certain nodes
> with an additional attribute which is then picked up in JS and used as a
> keybinding for shortcuts.
> So far i created a mixin which i preferably would like to put on any kind
> of
> component, in case of an EventLink it should simply render:
> link
> instead of:
> link
> This works like expected but a problem comes up with components that
> contain
> components, for example:
> public class MyComponent
> {
>     @Component(//parameters)
>     private EventLink edit;
>
>     ... more stuff in here
> }
>
> Now i'd like to use 'MyComponent' on different pages where on some pages
> i'd
> like to use the mixin whereas on others i don't. I also don't want to
> change
> the component and add the mixin in the component and a parameter to control
> if it should be active or not.
> When debugging i found the rendered elements are available in class
> RenderQueueImpl in the Stack<ComponentResources> renderingComponents, other
> than that i couldn't find any appearance and don't know if or how to inject
> or access the element.
> I'd like to pass the component name and optionally the container
> component(s) in a fashion like:
> 'myComponent.edit' where myComponent is the variable name as in:
> @Component
> private MyComponent myComponent;
> to my mixin.
> Is there any way i can filter the rendered element in the render phases?
>
> @BeginRender
>     void beginRender(final MarkupWriter markupWriter)
>     {
>         markupWriter.addListener(new MarkupWriterListener()
>         {
>             @Override
>             public void elementDidEnd(final Element element)
>             {
>                 /**
>                   * here i'd like to put my if(element == parameter)
>                   * where element is the currently rendered component
>                   * and parameter is the passed parameter somhow in the
>                   * fashion of containerName.componentName
>                   */
>                 element.attribute(ATTRIBUTE_NAME, shortcut);
>             }
>
>             @Override
>             public void elementDidStart(Element element)
>             {
>             }
>         });
>     }
>
> --
> View this message in context:
> http://tapestry.1045711.n5.nabble.com/How-to-resolve-the-rendered-component-in-a-mixin-tp5714315.html
> Sent from the Tapestry - User 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
>
>


-- 
*Regards,*
*Muhammad Gelbana
Java Developer*