You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Andrea Chiumenti <ki...@gmail.com> on 2007/05/31 12:03:08 UTC
dynamic component injection
Hello I'd like to konw if in Tap 4.1.2 there is a way do dynamically
render components inside a page.
If yes, how ?
regards,
kiuma
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: dynamic component injection
Posted by Martino Piccinato <ma...@gmail.com>.
tnx a lot Alejandro!
this is exactly what I was looking for, block/renderblock components
combined with EventListener can be really powerful stuff but I didn't
realize it until I read your example.
It's also very interesting the way you use that Editors page as a "block
component repository" and the ComponentAddress beans.
Re: dynamic component injection
Posted by Alejandro Scandroli <al...@gmail.com>.
Hi Guys,
I don't know if this is what are you looking for but here is how we
handle our "dynamic" components at Trails.
First we have a page which contains what we call "editors" (our
"dynamic" components):
http://svn.codehaus.org/trails/trunk/trails/modules/trails-core/src/main/resources/org/trails/page/Editors.html
http://svn.codehaus.org/trails/trunk/trails/modules/trails-core/src/main/resources/org/trails/page/Editors.page
They are all wrapped by @Blocks.
Then we have a map where the key is an ongl expression we use to
evaluate if that is right component for render a property, and the
value is a ComponentAddress. The map definition is in our sping
configuration file.
Here is an example of one entry:
<entry>
<key>
<value>string and !large and !identifier</value>
</key>
<bean class="org.apache.tapestry.util.ComponentAddress">
<constructor-arg index="0">
<value>trails:Editors</value> <!-- it refers to Editors page -->
</constructor-arg>
<constructor-arg index="1">
<value>stringEditor</value>
</constructor-arg>
</bean>
</entry>
So "stringEditor" is the name of the block we are going to look for in
our Editors page.
Then wherever we need to render one of those blocks we do:
<span jwcid="$content$">
<span jwcid="renderBlock@Block" block="ognl:block"/>
</span>
and
public Block getBlock()
{
ComponentAddress componentAddress = get the ComponentAddress from the map.
componentAddress.findComponent(getPage().getRequestCycle()); //activate it.
// set all the properties you need to set
return (Block) componentAddress;
}
That's all!
This is safe to use inside a For or Table or wherever you need to use it.
Of course an ognl expressions map is not a good fit for everyone, so
you can use whatever service you need to implement your logic as long
as it returns a ComponentAddress from the Editors page.
I hope this helps you.
Saluti.
Alejandro.
On 6/20/07, Martino Piccinato <ma...@gmail.com> wrote:
> did you find any cleaner way to do this?
>
> I think this problem is not just related to "one page applications" but
> apply also to any page/component that depending un user actions must show
> different enough content (unless one wants to go with EventListener and a
> long ugly list of IF components...)
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: dynamic component injection
Posted by Martino Piccinato <ma...@gmail.com>.
did you find any cleaner way to do this?
I think this problem is not just related to "one page applications" but
apply also to any page/component that depending un user actions must show
different enough content (unless one wants to go with EventListener and a
long ugly list of IF components...)
Re: dynamic component injection
Posted by Andrea Chiumenti <ki...@gmail.com>.
Well I want to make a single page application, so componentns (the
body part of a page)
will be injected as reference by hivemind into different jars.
Playng a bit with Tapestry src I've found a better way to do this, but
I need some more testing (assets, listeners, etc).
I'm investigating on this kind of solution becase this will optimize
dojo loading with incremental load.
What do you thik about this ?
kiuma
Here it is the code
--------------------------------------------------------------------------
package org.jfly.sample.pages;
import org.jfly.sample.components.widgets.DynaRenderer;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.HiveMind;
import org.apache.hivemind.Location;
import org.apache.tapestry.AbstractPage;
import org.apache.tapestry.BaseComponent;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.INamespace;
import org.apache.tapestry.IPage;
import org.apache.tapestry.IRender;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.TapestryConstants;
import org.apache.tapestry.annotations.InjectObject;
import org.apache.tapestry.engine.IPageLoader;
import org.apache.tapestry.html.BasePage;
import org.apache.tapestry.pageload.ComponentClassProvider;
import org.apache.tapestry.pageload.ComponentClassProviderContext;
import org.apache.tapestry.pageload.PageLoader;
import org.apache.tapestry.resolver.ComponentSpecificationResolver;
import org.apache.tapestry.services.ComponentConstructor;
import org.apache.tapestry.services.ComponentConstructorFactory;
import org.apache.tapestry.services.ResponseBuilder;
import org.apache.tapestry.spec.ContainedComponent;
import org.apache.tapestry.spec.IComponentSpecification;
import org.apache.tapestry.spec.IContainedComponent;
import org.apache.tapestry.web.WebRequest;
import org.apache.hivemind.Messages;
import org.apache.tapestry.annotations.InjectObject;
import java.util.Date ;
/**
* Start page of application pageInjection.
*/
abstract public class Home extends BasePage {
private IRender renderer;
public IRender getRenderer() {
return renderer;
}
public Date getCurrentTime() {
return new Date();
}
@InjectObject("service:tapestry.page.ComponentClassProvider")
public abstract ComponentClassProvider getComponentClassProvider();
@InjectObject("service:tapestry.page.ComponentSpecificationResolver")
public abstract ComponentSpecificationResolver getComponentResolver();
@InjectObject("service:tapestry.enhance.ComponentConstructorFactory")
public abstract ComponentConstructorFactory
getComponentConstructorFactory();
@InjectObject("service:tapestry.page.PageLoader")
public abstract IPageLoader getPageLoader();
public IRender getDynaComp() {
IRequestCycle cycle = getEngine().getInfrastructure().getRequestCycle();
ComponentSpecificationResolver componentResolver =
getComponentResolver();
IPageLoader pageLoader = getPageLoader();
String componentType = DynaRenderer.class.getName();
Location location = getLocation();
componentResolver.resolve(cycle, getNamespace(),
componentType, location);
INamespace componentNamespace = componentResolver.getNamespace();
IComponentSpecification spec = componentResolver.getSpecification();
IContainedComponent contained = new ContainedComponent();
contained.setLocation(location);
contained.setType(componentType);
IComponent result = instantiateComponent(this, this, "message",
spec, componentResolver.getType(), componentNamespace,
contained);
//IRender result =
getPageLoader().createImplicitComponent(cycle, this, "message",
DynaRenderer.class.getName(), getLocation());
return result;
}
private IComponent instantiateComponent(IPage page, IComponent container,
String id, IComponentSpecification spec, String type,
INamespace namespace, IContainedComponent containedComponent)
{
ComponentClassProviderContext context = new
ComponentClassProviderContext(
type, spec, namespace);
String className =
getComponentClassProvider().provideComponentClassName(context);
if (HiveMind.isBlank(className))
className = BaseComponent.class.getName();
else
{
Class componentClass =
getEngine().getInfrastructure().getClassResolver().findClass(className);
if (!IComponent.class.isAssignableFrom(componentClass))
throw new ApplicationRuntimeException(componentClass +
" is not a component class", container, spec
.getLocation(), null);
if (IPage.class.isAssignableFrom(componentClass))
throw new ApplicationRuntimeException("Not assignable
" + id, container, spec.getLocation(),
null);
}
ComponentConstructor cc =
getComponentConstructorFactory().getComponentConstructor(spec,
className);
IComponent result = (IComponent) cc.newInstance();
result.setNamespace(namespace);
result.setPage(page);
result.setContainer(container);
result.setId(id);
result.setContainedComponent(containedComponent);
result.setLocation(containedComponent.getLocation());
return result;
}
}
On 5/31/07, Jesse Kuhnert <jk...@gmail.com> wrote:
> Hmm I'm not sure. It doesn't look right but it's possible. Wouldn't
> @Block be the easiest way to do it? Or different instances of IRender ?
>
> On 5/31/07, Andrea Chiumenti <ki...@gmail.com> wrote:
> >
> > Is it right to do this ?
> > public IRender getDynaComp() {
> > IRequestCycle cycle =
> > getEngine().getInfrastructure().getRequestCycle();
> > IWorkerRender result;
> > if ((cycle.getParameter("body") != null) &&
> > (!(cycle.getParameter("body").equals(""))) ) {
> > result = from a service via IOC <----
> > result.setRenderWorker(getRenderWorker());
> > } else {
> > result = new DynaRenderer(); //Default
> > result.setRenderWorker(getRenderWorker());
> > }
> > return result;
> > }
> >
> > of course components must not be abstract.
> >
> >
> > On 5/31/07, Andrea Chiumenti <ki...@gmail.com> wrote:
> > > Hello I'd like to konw if in Tap 4.1.2 there is a way do dynamically
> > > render components inside a page.
> > >
> > > If yes, how ?
> > >
> > > regards,
> > > kiuma
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>
>
> --
> Jesse Kuhnert
> Tapestry/Dojo team member/developer
>
> Open source based consulting work centered around
> dojo/tapestry/tacos/hivemind. http://blog.opencomponentry.com
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: dynamic component injection
Posted by Jesse Kuhnert <jk...@gmail.com>.
Hmm I'm not sure. It doesn't look right but it's possible. Wouldn't
@Block be the easiest way to do it? Or different instances of IRender ?
On 5/31/07, Andrea Chiumenti <ki...@gmail.com> wrote:
>
> Is it right to do this ?
> public IRender getDynaComp() {
> IRequestCycle cycle =
> getEngine().getInfrastructure().getRequestCycle();
> IWorkerRender result;
> if ((cycle.getParameter("body") != null) &&
> (!(cycle.getParameter("body").equals(""))) ) {
> result = from a service via IOC <----
> result.setRenderWorker(getRenderWorker());
> } else {
> result = new DynaRenderer(); //Default
> result.setRenderWorker(getRenderWorker());
> }
> return result;
> }
>
> of course components must not be abstract.
>
>
> On 5/31/07, Andrea Chiumenti <ki...@gmail.com> wrote:
> > Hello I'd like to konw if in Tap 4.1.2 there is a way do dynamically
> > render components inside a page.
> >
> > If yes, how ?
> >
> > regards,
> > kiuma
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>
--
Jesse Kuhnert
Tapestry/Dojo team member/developer
Open source based consulting work centered around
dojo/tapestry/tacos/hivemind. http://blog.opencomponentry.com
Re: dynamic component injection
Posted by Andrea Chiumenti <ki...@gmail.com>.
Is it right to do this ?
public IRender getDynaComp() {
IRequestCycle cycle = getEngine().getInfrastructure().getRequestCycle();
IWorkerRender result;
if ((cycle.getParameter("body") != null) &&
(!(cycle.getParameter("body").equals(""))) ) {
result = from a service via IOC <----
result.setRenderWorker(getRenderWorker());
} else {
result = new DynaRenderer(); //Default
result.setRenderWorker(getRenderWorker());
}
return result;
}
of course components must not be abstract.
On 5/31/07, Andrea Chiumenti <ki...@gmail.com> wrote:
> Hello I'd like to konw if in Tap 4.1.2 there is a way do dynamically
> render components inside a page.
>
> If yes, how ?
>
> regards,
> kiuma
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org