Interesting! How does your solution differ from the template skinning feature of T5.3? ( http://blog.tapestry5.de/index.php/2011/06/24/template-skinning/ ) - Or is it just the same functionality for pre 5.3 ?
-- Chris On Tue, Oct 4, 2011 at 4:45 PM, Caiiiycuk <caiiiy...@gmail.com> wrote: > 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 > >