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
>
>

Reply via email to