Using Thymeleaf 3 pre-processor to remove whitespace
With Thymeleaf 3.0 onwards it is possible to use pre/post processors to manage output, prior to content being rendered, and are applied to the entire template as opposed to a single fragment. As an example, it is possible to strip out whitespace from within HTML elements. Looking at the source of a rendered Thymeleaf HTML page, it is clear that there is typically a substantial level of empty space in, for example, a paragraph or a span. This is not to be confused with inter-HTML element space, already managed by https://github.com/connect-group/thymeleaf-extras.
As mentioned above the removal of unwanted/unnecessarry whitespace is a good example to demonstrate processor usage. The first step is to create the worker, and typically, an extension of AbstractTemplateHandler will suffice.
public final class StripElementWhitespaceHandler extends AbstractTemplateHandler
{
public StripElementWhitespaceHandler()
{
super();
}
@Override
public void handleText(final IText text)
{
if (getNext() == null)
{
return;
}
if (StringUtils.hasText(text.getText()))
{
this.getNext().handleText(text);
}
}
}
The next step is to create a dialect for this handler, that implements IPreProcessorDialect
public class StripElementWhitespaceDialect implements IPreProcessorDialect
{
@Override
public String getName()
{
return "your_dialect_name";
}
@Override
public int getDialectPreProcessorPrecedence()
{
return 1000;
}
@Override
public Set<IPreProcessor> getPreProcessors()
{
return ImmutableSet.of(new PreProcessor(TemplateMode.HTML,
new StripElementWhitespaceHandler().getClass(),
getDialectPreProcessorPrecedence()));
}
}
and then finally, add the dialect to the template engine. Using Springboot, as below
@Bean
public SpringTemplateEngine templateEngine(.....)
{
SpringTemplateEngine engine = new SpringTemplateEngine()
......
engine.addDialect(new StripElementWhitespaceDialect());
return engine;
}
An alternative example makes use of AbstractTextProcessor where there is a requirement to do more than just remove whitespace e.g. modify text.
public class StripElementWhiteSpace extends AbstractTextProcessor
{
StripElementWhiteSpace(TemplateMode templateMode, int precedence)
{
super(templateMode, precedence);
}
@Override
public void doProcess(ITemplateContext context, IText text,
ITextStructureHandler structureHandler)
{
if (!StringUtils.hasText(text.getText()))
{
structureHandler.removeText();
}
}
}
public class StripElementWhiteSpaceDialect
extends AbstractProcessorDialect
{
private final TemplateMode templateMode;
StripElementWhiteSpaceDialect(String name, String prefix,
int precedence,
TemplateMode templateMode) {
super(name, prefix, precedence);
this.templateMode = templateMode;
}
StripElementWhiteSpaceDialect() {
this("strip-element-whitespace-dialect",
"strip-html-element-white-space", 100, TemplateMode.HTML);
}
@Override
public Set<IProcessor> getProcessors(String dialectPrefix) {
return ImmutableSet.of(new StriplElementWhiteSpace(templateMode,
getDialectProcessorPrecedence()));
}
}
//add to template engine
engine.addDialect(new StripElementWhitespaceDialect());
A starting point for more detailed information can be found at https://www.thymeleaf.org/doc/tutorials/3.0/extendingthymeleaf.html.