Return-Path: X-Original-To: apmail-struts-issues-archive@minotaur.apache.org Delivered-To: apmail-struts-issues-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7B2151074F for ; Wed, 31 Jul 2013 02:31:53 +0000 (UTC) Received: (qmail 49485 invoked by uid 500); 31 Jul 2013 02:31:53 -0000 Delivered-To: apmail-struts-issues-archive@struts.apache.org Received: (qmail 48840 invoked by uid 500); 31 Jul 2013 02:31:51 -0000 Mailing-List: contact issues-help@struts.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@struts.apache.org Delivered-To: mailing list issues@struts.apache.org Received: (qmail 48489 invoked by uid 99); 31 Jul 2013 02:31:50 -0000 Received: from arcas.apache.org (HELO arcas.apache.org) (140.211.11.28) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 31 Jul 2013 02:31:50 +0000 Date: Wed, 31 Jul 2013 02:31:50 +0000 (UTC) From: "Jasper Rosenberg (JIRA)" To: issues@struts.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (WW-4145) file.ftl in xhtml theme directly references xhtml controlfooter.ftl MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ 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}" > <#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