WildDev
WildDev

Reputation: 2367

Thymeleaf - how to add a custom util?

Thymeleaf has a number of useful utilities like #strings.capitalize(...) or #lists.isEmpty(...). I'm trying to add a custom one but have no idea how to register this.

Have made a custom Util class:

public class LabelUtil {

    public String[] splitDoubleWord(String str) {
        return str.split("[A-Z]", 1);
    }
}

Now I'm going to use it like this:

<span th:each="item : ${#labels.splitDoubleWord(name)}" th:text="${item}"></span>

Of course, it won't work because I haven't registered the Util and defined #labels var.

So, the question is how and where to do it?

Upvotes: 14

Views: 6695

Answers (2)

Yuki  Yoshida
Yuki Yoshida

Reputation: 1263

This answer is for thymeleaf 2.x.

If you use thymeleaf 3.x or later, please see other answers.

public class MyDialect extends AbstractDialect implements IExpressionEnhancingDialect {

  public MyDialect() {
    super();
  }

  @Override
  public String getPrefix() {
    // @see org.thymeleaf.dialect.IDialect#getPrefix
    return "xxx";
  }

  @Override
  public boolean isLenient() {
    return false;
  }

  @Override
  public Map<String, Object> getAdditionalExpressionObjects(IProcessingContext ctx) {
    Map<String, Object> expressions = new HashMap<>();
    expressions.put("labels", new LabelUtil());
    return expressions;
  }
}

and register your dialect.

@Configuration
public class ThymeleafConfig {

  @Bean
  public MyDialect myDialect() {
    return new MyDialect();
  }
}

thymeleaf-extras-java8time source code is good reference for creating custom thymeleaf expressions.

Upvotes: 10

ryanp
ryanp

Reputation: 5127

The API for registering a custom expression object has changed in Thymeleaf 3, for example:

public class MyDialect extends AbstractDialect implements IExpressionObjectDialect {

    MyDialect() {
        super("My Dialect");
    }

    @Override
    public IExpressionObjectFactory getExpressionObjectFactory() {
        return new IExpressionObjectFactory() {

            @Override
            public Set<String> getAllExpressionObjectNames() {
                return Collections.singleton("myutil");
            }

            @Override
            public Object buildObject(IExpressionContext context,
                    String expressionObjectName) {
                return new MyUtil();
            }

            @Override
            public boolean isCacheable(String expressionObjectName) {
                return true;
            }
        };
    }
}

Upvotes: 11

Related Questions