Only template resolvers and dialects are added automatically. There should be a line in code to add link builders as well: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java#L145

Something like linkBuilders.orderedStream().forEach(engine::addLinkBuilder);.

Comment From: bclozel

Hello @dtrunk90

ILinkBuilder is a new extension point added in Thymeleaf 3.0, that makes the templating engine more independent of the underlying web technology. Are there other 3rd party link builders implementations? Could you describe the use case you're facing for this?

Getting to know more about this feature could help us decide how to surface that in our support.

Thanks!

Comment From: dtrunk90

As far as I know there's only the StandardLinkBuilder implementation (not 3rd party) which is prepending the context path for example if it's a context relative link. My use case is to extend the StandardLinkBuilder to automatically prepend the locale after the context path: https://stackoverflow.com/a/60103777/1163457

In order to achieve this I have to call engine.setLinkBuilders(linkBuilders.stream().collect(Collectors.toSet()));. So maybe it's better to create the StandardLinkBuilder bean conditionally:

@ConditionalOnMissingBean(name = "standardLinkBuilder")

and call the setLinkBuilders method as I did it. The TemplateEngine class is doing this in it's constructor method: https://github.com/thymeleaf/thymeleaf/blob/3.0-master/src/main/java/org/thymeleaf/TemplateEngine.java#L276

Comment From: bclozel

So in your case, adding additional link builders won't help here? Since the standard one will take over? This is why you're using the setter and not the add method after all?

We're currently not building nor setting the standard link builder on the engine instance, but rather relying on the defaults here.

Maybe this use case is specific enough that it doesn't require an extension point on our side? I'm wondering if doing so would not override Thymeleaf defaults and expose us to issues if those defaults change.

Maybe a BeanPostProcessor in your application, setting that link builder, would be enough in this case.

Comment From: dtrunk90

So in your case, adding additional link builders won't help here? Since the standard one will take over? This is why you're using the setter and not the add method after all?

Correct. The add-Method would only add it in addition to the StandardLinkBuilder. Maybe I could also set the order to prepend the locale first and let the context path prepend afterwards by the StandardLinkBuilder. I'll try it on sunday and give feedback. If it works calling the add method would be enough. We're currently not building nor setting the standard link builder on the engine instance, but rather relying on the defaults here.

Maybe this use case is specific enough that it doesn't require an extension point on our side? I'm wondering if doing so would not override Thymeleaf defaults and expose us to issues if those defaults change.

You're right. This would override the defaults even if they change.

Maybe a BeanPostProcessor in your application, setting that link builder, would be enough in this case.

That's another thing I can try to do. But in fact I think the auto configuration should call the add method to add all link builder beans automatically anyway. It wouldn't override the defaults.

Comment From: bclozel

Let's see how things turn out for your use case. As for adding other link builders, I'm not in favour of adding that feature unless we've got actual use cases for this. Otherwise this would just put pressure on startup time for no added benefit.

Comment From: dtrunk90

After implementing a new link builder in addition to the StandardLinkBuilder implementation and setting the order it works by simply calling engine.addLinkBuilder. See updated answer here for details: https://stackoverflow.com/a/60103777/1163457

It would be really great if you could add the linkBuilders.orderedStream().forEach(engine::addLinkBuilder); so I don't need to build the whole TemplateEngine bean myself.

Comment From: bclozel

Injecting ordered link builders makes sense if it's a common use case to have several components like this in the application.

Looking at SO question, I don't think you need to override the templating engine bean, but something like the following should work and is more concise:

public class CustomLinkBuilder implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof SpringTemplateEngine) {
            ((SpringTemplateEngine)bean).addLinkBuilder(new PathVariableLocaleLinkBuilder());
        }
        return bean;
    }
}

I'm closing this issue for now and we'll reconsider it if it appears that more applications have this need. Thanks!

Comment From: didiez

I was also expecting that my custom ILinkBuilder would by added to the SpringTemplateEngine when registered as a bean. It's not a big deal adding it to the TemplateEngine with a BeanPostProcessor, though :+1: