Migrating substituteby dialect from 2 to 3

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Migrating substituteby dialect from 2 to 3

corey
Hi,

I was wondering if you had an example or can provide feedback.

We are using a custom dialect for handling "substituteby" in Thymeleaf 2.
Now, we want to migrate to Thymeleaf 3 which uses replace.

Migrating from "substituteby" to "replace" using the new Dialect API is difficult without implementation examples. (Ex: AbstractAttributeTagProcessor.doProcess overriding)

Could you look at our old implementation and provide some feedback?

Template Usage:  
<template mercury:substituteby="/core" th:with="type='template',templateName='app_layout'"/>

Java Code:
package com.chromeriver.tessera.config.thymeleaf;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.Arguments;
import org.thymeleaf.dom.Element;
import org.thymeleaf.dom.Node;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.processor.ProcessorResult;
import org.thymeleaf.processor.attr.AbstractAttrProcessor;
import org.thymeleaf.standard.fragment.StandardFragment;
import org.thymeleaf.standard.fragment.StandardFragmentProcessor;

public class SubstituteByAttrProcessor extends AbstractAttrProcessor {

        private static Logger logger = LoggerFactory.getLogger(SubstituteByAttrProcessor.class);
       
        private String pathPrefix;

        public SubstituteByAttrProcessor(String pathPrefix) {
                super("substituteby");
                this.pathPrefix = pathPrefix;
        }

        @Override
        protected ProcessorResult processAttribute(Arguments arguments, Element element, String attributeName) {

                String attributeValue = element.getAttributeValue(attributeName);

                StandardFragment fragmentAndTarget = StandardFragmentProcessor.computeStandardFragmentSpec(
                                arguments.getConfiguration(), arguments, attributeValue, null, null);

                List<Node> fragmentNodes = null;

                try {
                       
                        //grab the template
                        fragmentNodes = fragmentAndTarget.extractFragment( arguments.getConfiguration(), arguments, arguments.getTemplateRepository() );
                       
                } catch (Exception e) { }

               
                if (fragmentNodes == null || fragmentNodes.size() == 0) {

                        // attempt to get default (customer 0)
                        String templateName = fragmentAndTarget.getTemplateName();
                       
                        logger.debug("Did not find a template named {}, so I'm getting the default...", templateName);
                       
                        templateName = pathPrefix + templateName.replaceFirst("[0-9]+\\/", "/0/");
                       
                        logger.debug("Default template: {}", templateName);

                       
                        // create new defaultFragmentAndTarget with new templateName somehow it's not modifiable
                        StandardFragment defaultFragmentAndTarget = new StandardFragment(templateName, fragmentAndTarget.getFragmentSpec(), null);
                       
                        fragmentNodes = defaultFragmentAndTarget.extractFragment(arguments.getConfiguration(), arguments, arguments.getTemplateRepository());

                        if (fragmentNodes == null || fragmentNodes.size() == 0) {
                                throw new TemplateProcessingException("Cannot process '" + attributeName + "' attribute. "
                                                + "Fragment specification '" + attributeValue + "' matched null and template name is '" + templateName + "'.");
                        }
                       
                }

                element.clearChildren();
                element.removeAttribute(attributeName);

                element.setChildren(fragmentNodes);
                element.getParent().extractChild(element);

                return ProcessorResult.OK;
        }

        @Override
        public int getPrecedence() {
                return 10000;
        }

}