Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPostProcessorDialect implementation to minify/remove comments from output html #999

Closed
albilu opened this issue Feb 26, 2024 · 2 comments
Closed

Comments

@albilu
Copy link

albilu commented Feb 26, 2024

Following the discussion in #108

I am unable to find a proper example of a PostProcessor to achieve html minification or any other update on the html output using https://code.google.com/p/htmlcompressor/

There is a simpler Filter solution to achieve this but from this blog Filter as some performance downsides.

I believe this should be a built in feature but as rejected in previous issue.

Getting error with the following implementation, any help is welcome:

public class StripElementWhiteSpaceDialect implements IPostProcessorDialect {

    @Override
    public int getDialectPostProcessorPrecedence() {
        return 0;
    }

    @Override
    public Set<IPostProcessor> getPostProcessors() {
        Set<IPostProcessor> processors = new HashSet<>();
        processors.add(new StripElementWhiteSpace());
        return processors;
    }

    @Override
    public String getName() {
        return "Minifier";
    }

    public class StripElementWhiteSpace implements ITextProcessor, IPostProcessor {

        @Override
        public void process(ITemplateContext context, IText text, ITextStructureHandler structureHandler) {
            //update the text
        }

        @Override
        public TemplateMode getTemplateMode() {
            return TemplateMode.TEXT;
        }

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

        @Override
        public Class<? extends ITemplateHandler> getHandlerClass() {
            return ITemplateHandler.class;
        }

    }

}

Getting error:

threw exception [Request processing failed: org.thymeleaf.exceptions.ConfigurationException: Post-Processor class org.thymeleaf.engine.ITemplateHandler specified for post-processor io.bootify.my_app.minify.StripElementWhiteSpaceDialect$StripElementWhiteSpace in dialect io.bootify.my_app.minify.StripElementWhiteSpaceDialect does not implement required zero-argument constructor.] with root cause

java.lang.NoSuchMethodException: org.thymeleaf.engine.ITemplateHandler.<init>()
        at java.base/java.lang.Class.getConstructor0(Class.java:3585) ~[na:na]
        at java.base/java.lang.Class.getConstructor(Class.java:2271) ~[na:na]
        at org.thymeleaf.DialectSetConfiguration.build(DialectSetConfiguration.java:397) ~[thymeleaf-3.1.2.RELEASE.jar:3.1.2.RELEASE]
@duoduobingbing
Copy link

duoduobingbing commented Mar 18, 2024

Here's a working demo

Your error boils down to mixing APIs in an unsupported way.

If you have a look at the documentation for PostProcessors you will see that it states:

Pre-processors and post-processors are different to processors in that instead of executing on a single event or on an event model (a fragment of a template), they apply to the entire template execution process as an additional step in the engine’s processing chain. Therefore they follow an API completely different to that of processors, much more event-oriented, defined by the lower-level ITemplateHandler interface.

a) ITextProcessor cannot be used in conjunction with IPostProcessorDialect.

b) The method getHandlerClass() defines the implementation of your PostProcessor, so it fails in your case because of

return ITemplateHandler.class;

ITemplateHandler is an interface and does not have a constructor, thus the exception java.lang.NoSuchMethodException: org.thymeleaf.engine.ITemplateHandler.<init>()

How can it be fixed?

public class StripElementWhiteSpaceDialect implements IPostProcessorDialect {

    Set<IPostProcessor> processors = new HashSet<>();

    {
       processors.add(new PostProcessor(TemplateMode.HTML, StripElementWhiteSpaceHandler.class, Integer.MAX_VALUE));
    }

    @Override
    public int getDialectPostProcessorPrecedence() {
        return 0;
    }

    @Override
    public Set<IPostProcessor> getPostProcessors() {
        return processors;
    }

    @Override
    public String getName() {
        return "Minifier";
    }

    public static class StripElementWhiteSpaceHandler extends AbstractTemplateHandler {

       @Override
       public void handleText(IText textNode) {
          
           //update the text
           
           super.handleText(...);
       }

    }

}

@albilu
Copy link
Author

albilu commented May 14, 2024

@duoduobingbing thanks for the demo. But actually textNode.getText() is not the final complete processed output but rather chuncks. So doesnt fit what i was looking for. Thanks very much anyway.

@albilu albilu closed this as completed May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants