Hi. Let me explain. Imagine that we have standard tapestry page: Templates.java and of course we have template of this page Templates.tml and it works perfect. But I need to change template of this page by user request. More precisely I want to use one java class (Templates.java) with many templates files (Template1.tml, Template2.tml, etc). And of course EventLinks, ActionLinks, Zones, Componenst should work as usual.
Our team has spent much time to get this work by using tapestry standard features. But no luck. I have working solution based on reflection wich brakes oop ideology. I introduce an interface: public interface PageLoadService { Page loadPage(String defaultPageName, String templateName, Locale locale, Object coreComponent); } Where defaultPageName is default template (Templates.tml), templateName is overriding template (Template1.tml, etc) and coreComponent is instance of Page (Template.java instance). And in Template.onActivate() i use this interface like this: @Inject private PageResponseRenderer renderer; @Inject private PageLoadService pageLoadService; public void onActivate() { if (request.isXHR()) { //Ajax return; } if (request.getPath().contains(":") || request.getPath().contains(".")) { //EVENT, ACTION, ZONE return; } if (template == null || template.equals(BASIC_TEMPLATE)) { //Default approach return; } Page page = pageLoadService.loadPage( BASIC_TEMPLATE, template, Locale.getDefault(), this); try { page.attached(); renderer.renderPageResponse(page); page.detached(); } catch (IOException e) { e.printStackTrace(); } } Let me explain. I'm trying to use default approach (without templating Template.tml+Template.java) to handle ajax,zone,event|action links requests, and PageResponseRenderer to render page in other requests. And it works (tested T5.1.05 and T5.2.0, 5.2.6). But tapestry is huge project, and i'm not sure if there are hidden problems, what do you think? --- Realization of PageLoadService is really ugly: package org.apache.tapestry5.internal.pageload; import java.lang.reflect.Method; import java.util.Locale; import org.apache.tapestry5.internal.parser.ComponentTemplate; import org.apache.tapestry5.internal.services.ComponentInstantiatorSource; import org.apache.tapestry5.internal.services.Instantiator; import org.apache.tapestry5.internal.services.PageLoader; import org.apache.tapestry5.internal.services.PersistentFieldManager; import org.apache.tapestry5.internal.services.TemplateParser; import org.apache.tapestry5.internal.structure.ComponentPageElement; import org.apache.tapestry5.internal.structure.ComponentPageElementResources; import org.apache.tapestry5.internal.structure.ComponentPageElementResourcesSource; import org.apache.tapestry5.internal.structure.Page; import org.apache.tapestry5.internal.structure.PageImpl; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.model.ComponentModel; import org.apache.tapestry5.services.ComponentClassResolver; public class PageLoadServiceT5_1Impl implements PageLoadService { private final PageLoaderImpl internalPageLoader; private final ComponentInstantiatorSource internalInstantiatorSource; private final TemplateParser internalTemplateParser; private final ComponentPageElementResourcesSource internalResourcesSource; private final ComponentClassResolver internalComponentClassResolver; private final PersistentFieldManager internalPersistentFieldManager; private final Method internalProgramAssembler; public PageLoadServiceT5_1Impl(PageLoader tapestryPageLoader, TemplateParser templateParser) { this.internalPageLoader = ReflectionToolkit.getDelegate(tapestryPageLoader); this.internalInstantiatorSource = ReflectionToolkit.getField(internalPageLoader, "instantiatorSource"); this.internalResourcesSource = ReflectionToolkit.getField(internalPageLoader, "resourcesSource"); this.internalComponentClassResolver = ReflectionToolkit.getField(internalPageLoader, "componentClassResolver"); this.internalPersistentFieldManager = ReflectionToolkit.getField(internalPageLoader, "persistentFieldManager"); this.internalProgramAssembler = ReflectionToolkit.getMethod(internalPageLoader, "programAssembler"); this.internalTemplateParser = templateParser; } public Page loadPage(String defaultPageName, String pageName, Locale locale, Object coreComponent) { Page page = new PageImpl(defaultPageName, locale, internalPersistentFieldManager); ComponentAssembler assembler = createAssembler(pageName, coreComponent.getClass().getCanonicalName(), locale); ComponentPageElement rootElement = assembler.assembleRootComponent(page); Object newCoreComponent = ReflectionToolkit.getField(rootElement, "coreComponent"); ReflectionToolkit.copyAnnotatedFields(coreComponent, newCoreComponent, CopyField.class); page.setRootElement(rootElement); page.loaded(); return page; } private ComponentAssembler createAssembler(String pageName, String className, Locale locale) { Instantiator instantiator = internalInstantiatorSource.getInstantiator(className); ComponentModel componentModel = instantiator.getModel(); Resource templateResource = componentModel.getBaseResource().forFile(pageName + ".tml"); ComponentTemplate template = internalTemplateParser.parseTemplate(templateResource); ComponentPageElementResources resources = internalResourcesSource.get(locale); ComponentAssembler assembler = new ComponentAssemblerImpl( internalPageLoader, internalInstantiatorSource, internalComponentClassResolver, instantiator, resources, locale); try { internalProgramAssembler.invoke(internalPageLoader, assembler, template); } catch (Exception e) { throw new RuntimeException(e); } return assembler; } } --- Also this approach always creates new instance of Template.java and we loosing setted context. But it is not a big problem - just copy fields from one class to another. -- View this message in context: http://tapestry.1045711.n5.nabble.com/Another-approach-to-dynamic-templating-T5-1-0-5-tp4868869p4868869.html Sent from the Tapestry - User mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org