question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Mechanism for configuring template resolution on a per-template basis

See original GitHub issue

A mechanism called template resolution attributes has been added to Thymeleaf 3.0 that will allow further configuration of the way a template is resolved, specifying this for each call of the template engine’s process(...) methods.

The idea is that at the process(...) call a series of configurations (attributes) can be specified by means of a map in the TemplateSpec class:

public TemplateSpec(
        final String template, final Set<String> templateSelectors, 
        final TemplateMode templateMode,
        final Map<String, Object> templateResolutionAttributes) {
    ...
}

This template specification can then be used for calling the template engine:

templateEngine.process(templateSpec, context, writer);

And the result will be not only that the specified Map will be available at any time for template processing artifacts from the ITemplateContext:

public interface ITemplateContext extends IExpressionContext {
    ...
    public Map<String, Object> getTemplateResolutionAttributes();
    ...
}

…but also that every call to the ITemplateResolver will include this map:

public interface ITemplateResolver {
    ...
    public TemplateResolution resolveTemplate(
            final IEngineConfiguration configuration,
            final String ownerTemplate, final String template,
            final Map<String, Object> templateResolutionAttributes);
    ...


Importantly, note that not only this map will be included in the ITemplateResolver#resolveTemplate(...) call for the first-level template, but also for every other template from which a fragment might be included during the processing of the first-level template.

Also note that these template resolution attributes will be inclued as a part of the template’s cache key, so that the same template resolved with different resolution attributes will result in different cache entries. It is important therefore that the values of these attributes correctly implement the equals(...) and hashCode() methods.

This should solve scenarios like the ones detailed at #329 and #380.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
tobiasflohrecommented, Jun 10, 2016

@danielfernandez I’m not using them directly since I use the Spring integration with ThymeleafView, so it’s not my choice. What I need would be some hook where I can add template resolution attributes. I’m now building a proxy ITemplateEngine that does that, but that doesn’t feel like the optimal solution. Thanks for all your work on Thymeleaf, it’s a great thing!

0reactions
jfleschlercommented, Sep 16, 2019

Resurrecting this issue in case someone else needs help adding templateResolutionAttributes.

The solution that we came up with is to create a new template engine that delegates to the out of box Thymeleaf TemplateEngine. In doing so, we can modify the templateResolutionAttributes and then pass them along.

public class DelegatingTemplateEngine implements ISpringTemplateEngine {
    public SpringTemplateEngine delegate;

    public DelegatingTemplateEngine(SpringTemplateEngine delegate) {
        this.delegate = delegate;
    }

	// excluded all overrides here, but basically they are just passthroughs 
	// to the delegate's methods.

    @Override
    public void process(String template,
            Set<String> templateSelectors,
            IContext context,
            Writer writer) {
        Map<String, Object> resolutionAttributes = new HashMap<>();

        // add your attributes here

		// create a null `TemplateMode` variable so that it can determine 
		// the correct `TemplateSpec` constructor
        TemplateMode templateMode = null;
        final TemplateSpec templateSpec = 
					new TemplateSpec(template, 
									templateSelectors, 
									templateMode, 
									resolutionAttributes);
        
		delegate.process(templateSpec, context, writer);
    }
}

To configure the new DelegatingTemplateEngine we added the following configuration:

@Configuration
public class TemplateAutoConfiguration {
	@Bean
    public DelegatingTemplateEngine delegatingTemplateEngine(
            SpringTemplateEngine templateEngine) {
        return new DelegatingTemplateEngine(templateEngine);
    }

	/**
	 * We need to tell the view resolvers to use our new engine
	 */
    @Bean
    public static BeanPostProcessor viewResolverPostProcessor(
            DelegatingTemplateEngine templateEngine) {
        return new ViewResolverPostProcessor(templateEngine);
    }

    @RequiredArgsConstructor
    protected static class ViewResolverPostProcessor implements BeanPostProcessor {
        private final DelegatingTemplateEngine templateEngine;

        @Override
        @Nullable
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            if (ThymeleafViewResolver.class.isAssignableFrom(bean.getClass())) {
                ThymeleafViewResolver resolver = ((ThymeleafViewResolver) bean);
                resolver.setTemplateEngine(templateEngine);
            }
            return bean;
        }
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Set template resolution in Motion - Apple Support
In Motion, set the resolution of the template (up to 4K) to be used in Final Cut Pro.
Read more >
Templates - Django documentation
A template contains the static parts of the desired HTML output as well as some special syntax describing how dynamic content will be...
Read more >
Documentation - Module Resolution - TypeScript
Module resolution is the process the compiler uses to figure out what an import refers to. Consider an import statement like import {...
Read more >
5. The IoC container - Spring
The BeanFactory interface provides an advanced configuration mechanism capable of managing ... The container performs bean dependency resolution as follows:.
Read more >
Configure Trusted Roots and Disallowed Certificates
The following improved automatic update mechanisms for a disconnected environment are available in Windows Server 2012 R2 and Windows 8.1 or ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found