Frage

I am reading the Thymeleaf + Spring 3 Tutorial and also trying to build a modular application. My goal is to be able to load thymeleaf templates from Jars in the classpath.

For this I have configured a SpringTemplateEngine in the next xml:

<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
    <property name="templateResolvers">
        <util:set>
            <ref bean="servletContextTemplateResolver" />
            <ref bean="classpathPluginTemplateResolver" />
        </util:set>
    </property>
</bean>

<bean id="classpathPluginTemplateResolver"
    class="org.mael.codex.arcana.web.thymeleaf.templates.ClasspathPluginTemplateResolver">
    <property name="prefix" value="/META-INF/codexarcana/plugin/views" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
</bean>

And the ClasspathPluginTemplateResolver code:

public class ClasspathPluginTemplateResolver extends TemplateResolver {

public ClasspathPluginTemplateResolver() {
    super();
    super.setResourceResolver(new ClasspathTemplateResolver());
}

@Override
public void setResourceResolver(IResourceResolver resourceResolver) {
    throw new ConfigurationException("Cannot set a resource resolver on "
            + this.getClass().getName() + ". If "
            + "you want to set your own resource resolver, use "
            + TemplateResolver.class.getName() + "instead");
}
}

And the ClasspathTemplateResolver:

public class ClasspathTemplateResolver implements IResourceResolver {

@Override
public String getName() {
    return this.getClass().getSimpleName();
}

@Override
public InputStream getResourceAsStream(
        TemplateProcessingParameters templateProcessingParameters,
        String resourceName) {

    if (resourceName == null || resourceName.isEmpty()) {
        throw new IllegalArgumentException("Resource name cannot be null");
    }

    try {
        return new ClassPathResource(resourceName).getInputStream();
    } catch (IOException e) {
        throw new RuntimeException("Cannot open resource '" + resourceName
                + "'", e);
    }
}

}

How can I avoid name conflicts in the templates resolved by the ClasspathPluginTemplateResolver?

Example:

Let's suppose I have 2 plugins with this directory structure:

codexarcana-poll-plugin.jar
    ----/META-INF/codexarcana/plugin/views/wizard.html

and

codexarcana-gravatar-plugin.jar
    ----/META-INF/codexarcana/plugin/views/wizard.html

In this case I believe that the ClasspathTemplateResolver will return a wrong view or will have conflicts resolving such thing.

War es hilfreich?

Lösung

Implementations of the ITemplateResolver interface that extend the base org.thymeleaf.templateresolver.AbstractTemplateResolver class (like all out-of-the-box implementations do) have a resolvablePatterns property that allows you to specify a series of patterns that will be applied for determining which views will be considered resolvable by that specific template engine. This should help you avoid collisions.

There you can specify wildcarded patterns like admin/*, user/*/create, etc.

Have in mind that these patterns apply on the view name, and not on the template file name itself. For example, if your template is /WEB-INF/templates/index.html and your view resolver adds prefix /WEB-INF/templates/ and suffix .html, your view name is index, and so a resolvable pattern like *.html would never match.

Also, there is an order property that establishes the order in which template resolvers will be asked to resolve a view.

Disclaimer, as required by StackOverflow rules: I'm the author of Thymeleaf.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top