jslearner07
jslearner07

Reputation: 471

Process string templates with thymeleaf 3

Can we use StringTemplateResolver to populate a string template with Icontext. If so how we can do? TemplateProcessingParameters and IResourceResolver is removed from Thymeleaf 3. Any working example would greatly help?

I have followed this example and it works great in Thymeleaf 2
Is there a way to make Spring Thymeleaf process a string template?

I didnt see any reference any migration guide as well.

Upvotes: 7

Views: 17596

Answers (3)

jslearner07
jslearner07

Reputation: 471

With the latest version of spring 5 and thymeleaf its easy to read string from thymeleaf.

If you are using gradle use the below import

compile "org.thymeleaf:thymeleaf:3.0.11.RELEASE"
compile "org.thymeleaf:thymeleaf-spring5:3.0.11.RELEASE"

//Code sample starts here
private TemplateEngine templateEngine;

private final static String TEMPLATE_LOCAL = "US";


public TemplateEngine getTemplateEngine() {
    templateEngine = new TemplateEngine();
    StringTemplateResolver stringTemplateResolver = new StringTemplateResolver();
    templateEngine.setTemplateResolver(stringTemplateResolver);
    return templateEngine;
}   



public String getTemplateFromAttributes(String htmlContent, Map<String, Object> attr) 
 {
        templateEngine = getTemplateEngine();
        Context context = new Context(new Locale(TEMPLATE_LOCAL));
        if (!CollectionUtils.isEmpty(attr)) {
            attr.forEach((k,v)->context.setVariable(k, v));
        }
        return templateEngine.process(htmlContent, context);        
}

Hope this is a useful snippet

Upvotes: 3

Anand Rockzz
Anand Rockzz

Reputation: 6658

This is how we did it, as a Spring @Service Bean:

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateProcessingParameters;
import org.thymeleaf.context.IContext;
import org.thymeleaf.messageresolver.IMessageResolver;
import org.thymeleaf.messageresolver.StandardMessageResolver;
import org.thymeleaf.resourceresolver.IResourceResolver;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.templatemode.StandardTemplateModeHandlers;
import org.thymeleaf.templateresolver.ITemplateResolutionValidity;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.templateresolver.NonCacheableTemplateResolutionValidity;
import org.thymeleaf.templateresolver.TemplateResolution;
import org.thymeleaf.util.Validate;
import com.rathna.app.model.constants.common.BeanConstants;

/**
 * Ref: https://github.com/thymeleaf/thymeleaf-itutorial/blob/2.1-master/src/test/java/org/thymeleaf/tools/memoryexecutor/StaticTemplateExecutorTest.java
 * @author anandchakru
 *
 */
@Service
public class StaticTemplateService {
    public String processTemplateCode(final String code, final IContext context) {
        Validate.notNull(code, "Code must be non-null");
        Validate.notNull(context, "Context must be non-null");
        String templateMode = StandardTemplateModeHandlers.HTML5.getTemplateModeName();
        IMessageResolver messageResolver = new StandardMessageResolver();
        ITemplateResolver templateResolver = new MemoryTemplateResolver(code, templateMode);
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setMessageResolver(messageResolver);
        templateEngine.setTemplateResolver(templateResolver);
        templateEngine.initialize();
        return templateEngine.process("dummy", context);
    }
}

class FixedMemoryResourceResolver implements IResourceResolver {
    private static final String NAME = "FixedMemoryResourceResolver";
    private final String templateContent;

    public FixedMemoryResourceResolver(final String templateContent) {
        Validate.notNull(templateContent, "Template content must be non-null");
        this.templateContent = templateContent;
    }
    @Override
    public String getName() {
        return NAME;
    }
    @Override
    public InputStream getResourceAsStream(final TemplateProcessingParameters tpp, final String templateName) {
        return new ByteArrayInputStream(templateContent.getBytes());
    }
}

class MemoryTemplateResolver implements ITemplateResolver {
    private static final String NAME = "MemoryTemplateResolver";
    private static final Integer ORDER = 1;
    private final String templateContent;
    private final String templateMode;

    public MemoryTemplateResolver(final String templateContent, final String templateMode) {
        Validate.notNull(templateContent, "Template content must be non-null");
        Validate.notNull(templateMode, "Template mode must be non-null");
        this.templateContent = templateContent;
        this.templateMode = templateMode;
    }
    @Override
    public void initialize() {
    }
    @Override
    public String getName() {
        return NAME;
    }
    @Override
    public Integer getOrder() {
        return ORDER;
    }
    @Override
    public TemplateResolution resolveTemplate(final TemplateProcessingParameters tpp) {
        String templateName = "CustomTemplate";
        String resourceName = "CustomResource";
        IResourceResolver resourceResolver = new FixedMemoryResourceResolver(templateContent);
        ITemplateResolutionValidity validity = new NonCacheableTemplateResolutionValidity();
        return new TemplateResolution(templateName, resourceName, resourceResolver, StandardCharsets.UTF_8.toString(),
                templateMode, validity);
    }
}

and call it like this:

@Autowired
protected StaticTemplateService staticTemplateService;
...
private String getProcessedHtml(){
    Context context2 = new Context();
    context2.setVariable("greet", "Hello");
    return staticTemplateService.processTemplateCode("<div th:text="${greet}">Hi</div> World", context2);
}

Upvotes: 6

jslearner07
jslearner07

Reputation: 471

I think I found a solution. If anybody has better answer please let me know. I did a small mistake earlier. Hope this helps.

private TemplateEngine templateEngine;

private TemplateEngine getTemplateEngine() {
        if(null == templateEngine){
            templateEngine = new TemplateEngine();
            StringTemplateResolver templateResolver =new   StringTemplateResolver();
            templateResolver.setTemplateMode(TemplateMode.HTML);
            templateEngine.setTemplateResolver(templateResolver);
        }
        return templateEngine;
    }




public String getTemplateFromMap(String htmlContent, Map<String, String> dynamicAttibutesMap) {
    templateEngine = getTemplateEngine();
    String template = null;
    final Context ctx = new Context(new Locale(TEMPLATE_LOCAL));
    if (!CollectionUtils.isEmpty(emailAttibutesMap)) {
        dynamicAttibutesMap.forEach((k,v)->ctx.setVariable(k, v));
    }
    if (null != templateEngine) {
        template = templateEngine.process(htmlContent, ctx);
    } 
    return template;
}

Upvotes: 11

Related Questions