[
https://issues.apache.org/jira/browse/WW-4145?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13724776#comment-13724776
]
Jasper Rosenberg commented on WW-4145:
--------------------------------------
Okay, I think I actually have a working, non-invasive solution. I will try to
get a real patch together tomorrow, but home right now, and not really set up
well. This code is tested though and works. The basic solution is to support
special notation for theme hierarchy templates. Basically, if you see "**"
(you can choose any token), it assumes that the following path component is a
theme that needs to be searched via the hierarchy.
Usage looks like for xhtml/form.ftl for example:
{code}
<#include "/${parameters.templateDir}/**${parameters.theme}/form-validate.ftl"
/>
<#include "/${parameters.templateDir}/**${parameters.theme}/form-common.ftl" />
<#if (parameters.validate?default(false))>
onreset="${parameters.onreset?default('clearErrorMessages(this);clearErrorLabels(this);')}"
<#else>
<#if parameters.onreset??>
onreset="${parameters.onreset?html}"
</#if>
</#if>
>
<#include "/${parameters.templateDir}/**${parameters.theme}/control.ftl" />
{code}
This has a lot of advantages because you can leave off the "**" if you don't
want to allow it to expand.
Once I took this approach, the code became much simpler and for the most part
let me leverage the existing hierarchy traversal methods already provided by
the TemplateEngine.
Here is the new top level template loader:
{code:java}
import java.io.IOException;
import java.io.Reader;
import java.util.List;
import org.apache.struts2.components.template.Template;
import org.apache.struts2.components.template.TemplateEngine;
import freemarker.cache.TemplateLoader;
/**
* When loading a template, if sees theme token in path, does a template search
through
* theme hierarchy for template, starting at the theme name after the token.
*/
public class ThemeTemplateLoader implements TemplateLoader {
private final String themeExpansionToken;
private final TemplateLoader parent;
private final TemplateEngine templateEngine;
public ThemeTemplateLoader(
String themeExpansionToken, TemplateLoader parent, TemplateEngine
templateEngine) {
this.themeExpansionToken = themeExpansionToken;
this.parent = parent;
this.templateEngine = templateEngine;
}
/** {@inheritDoc} */
public Object findTemplateSource(String name) throws IOException {
int tokenIndex = (name == null) ? -1 :
name.indexOf(themeExpansionToken);
if (tokenIndex < 0) {
return parent.findTemplateSource(name);
}
int themeEndIndex = name.indexOf('/', tokenIndex);
if (themeEndIndex < 0) {
return parent.findTemplateSource(name);
}
Template template = new Template(
name.substring(0, tokenIndex - 1),
name.substring(tokenIndex + 1, themeEndIndex),
name.substring(themeEndIndex + 1));
List<Template> possibleTemplates =
template.getPossibleTemplates(templateEngine);
for (Template possibleTemplate : possibleTemplates) {
Object templateSource =
parent.findTemplateSource(possibleTemplate.toString());
if (templateSource != null) {
return templateSource;
}
}
return null;
}
/** {@inheritDoc} */
public long getLastModified(Object templateSource) {
return parent.getLastModified(templateSource);
}
/** {@inheritDoc} */
public Reader getReader(Object templateSource, String encoding) throws
IOException {
return parent.getReader(templateSource, encoding);
}
/** {@inheritDoc} */
public void closeTemplateSource(Object templateSource) throws IOException {
parent.closeTemplateSource(templateSource);
}
}
{code}
The only necessary integration is in the FreemarkerManager. Just inject the
"ftl" Template engine, and in init() change:
{code:java}
config.setTemplateLoader(createTemplateLoader(servletContext,
templatePath));
{code}
to
{code:java}
config.setTemplateLoader(new ThemeTemplateLoader(
"**",
createTemplateLoader(servletContext, templatePath),
templateEngine));
{code}
> file.ftl in xhtml theme directly references xhtml controlfooter.ftl
> -------------------------------------------------------------------
>
> Key: WW-4145
> URL: https://issues.apache.org/jira/browse/WW-4145
> Project: Struts 2
> Issue Type: Bug
> Components: Other
> Affects Versions: 2.3.15.1
> Reporter: Jasper Rosenberg
> Assignee: Lukasz Lenart
> Labels: freemarker, tags, xhtml
> Fix For: 2.3.16
>
>
> Should use $\{parameters.theme} instead so can be used in theme extension.
> {code}
> <#include "/${parameters.templateDir}/${parameters.theme}/controlheader.ftl"
> />
> <#include "/${parameters.templateDir}/simple/file.ftl" />
> <#include "/${parameters.templateDir}/${parameters.theme}/controlfooter.ftl"
> />
> {code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira