You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by "Adam P. Jenkins" <ad...@thejenkins.org> on 2002/04/06 11:08:32 UTC

[PATCH] Allow nesting template:insert tags

Here is a patch to org.apache.struts.taglib.template.InsertTag that allows 
nested templates to work correctly.  

Basically I wanted to get the effect of subclassing a template.  Here is an 
example, show what didn't work and what this patch fixes.

<!-- file template-base.jsp -->
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-template.tld" prefix="template" %>

<HTML>
<BODY>
<H1>Title is <template:get name="title"/></H1>
</BODY>
</HTML>

<!-- file template-derived.jsp.  This is a specialization of template-base, 
which puts quotes around the template parameter. -->
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-template.tld" prefix="template" %>

<template:insert template="template-base.jsp">
  <template:put name="title">
    '<template:get name="title"/>'
  </template:put>
</template:insert>

<!-- page.jsp, inserts template-derived -->
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-template.tld" prefix="template" %>

<template:insert template="template-derived.jsp">
  <template:put name="title" content="Success" direct="true"/>
</template:insert>

<!-- end of example -->

When I display page.jsp in a browser, It will display 
  Title is ''
This is because the <template:get> tag in template-derived.jsp can't access 
the value that inserted by <template:put> in page.jsp.  The reason it doesn't 
work is because InsertTag pushes a new ContentMap onto the ContentMapStack in 
doStartTag(), so when <template:get> tries to access the "title" value put 
there in page.jsp, it's not visible.  This prevents templates from being 
derived from like this.

The solution is simple.  Just don't push the new ContentMap onto the stack 
until the InsertTag.doEndTag() method.  The GetTag and PutTag classes are 
already written to support this, since the PutTag access the map from its 
parent InsertTag rather than off the stack.  I just moved the 
ContentMapStack.push() call to doEndTag(), and now the above example works as 
expected.   GetTag has access to the ContentMap created by the inserting 
page, but not to its immediate parent InsertTag's ContentMap.

Here is the patch.
Adam

Index: InsertTag.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-struts/src/share/org/apache/struts/taglib/template/InsertTag.java,v
retrieving revision 1.11
diff -u -r1.11 InsertTag.java
--- InsertTag.java	12 Mar 2002 05:55:08 -0000	1.11
+++ InsertTag.java	6 Apr 2002 08:48:18 -0000
@@ -128,23 +128,23 @@
    }
 
    /**
-     * Process the start tag by pushing this tag's map onto the
-     * content map stack. 
-     * See org.apache.struts.taglib.template.util.ContentMapStack.
+     * Process the start tag by creating this tag's map.
      */
    public int doStartTag() throws JspException {
 
       map = new ContentMap();
-      ContentMapStack.push(pageContext, map);
       return EVAL_BODY_INCLUDE;
 
    }
 
    /**
-     * Process the end tag by including the template. 
+     * Process the end tag by pushing this tag's map onto the
+     * content map stack and including the template.
+     * See org.apache.struts.taglib.template.util.ContentMapStack.
      */
    public int doEndTag() throws JspException {
-
+     
+      ContentMapStack.push(pageContext, map);
       String prefix = "";
       ApplicationConfig config = (ApplicationConfig)
           
pageContext.getServletContext().getAttribute(Action.APPLICATION_KEY);


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>