You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/10/13 23:13:06 UTC
svn commit: r584454 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry/internal/services/
main/resources/org/apache/tapestry/internal/services/ site/apt/guide/
test/java/org/apache/tapestry/internal/services/ test/resources...
Author: hlship
Date: Sat Oct 13 14:13:05 2007
New Revision: 584454
URL: http://svn.apache.org/viewvc?rev=584454&view=rev
Log:
TAPESTRY-1469: Templates should support an outer t:container element for when a template consists of non-tree structured content
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/container_element.tml
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/tapestry_5_0_0.xsd
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java?rev=584454&r1=584453&r2=584454&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java Sat Oct 13 14:13:05 2007
@@ -47,6 +47,7 @@
import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.ioc.internal.util.LocationImpl;
import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.ioc.util.Stack;
import org.slf4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
@@ -82,13 +83,13 @@
private final List<TemplateToken> _tokens = newList();
- // Non-blank ids from start component (<comp>) elements
+ // Non-blank ids from start component elements
private final Set<String> _componentIds = newSet();
- // Used to accumulate text provided by the characters(). Even contiguous characters may be
- // broken up across multiple invocations due to parser internals. We accumulate those together
- // before forming a text token.
+ // Used to accumulate text provided by the characters() method. Even contiguous characters may
+ // be broken up across multiple invocations due to parser internals. We accumulate those
+ // together before forming a text token.
private final StringBuilder _textBuffer = new StringBuilder();
@@ -106,6 +107,23 @@
private final Map<String, URL> _configuration;
+ private final Stack<Runnable> _endTagHandlerStack = new Stack<Runnable>();
+
+ private final Runnable _addEndElementToken = new Runnable()
+ {
+ public void run()
+ {
+ _tokens.add(new EndElementToken(getCurrentLocation()));
+ }
+ };
+
+ private final Runnable _ignoreEndElement = new Runnable()
+ {
+ public void run()
+ {
+ }
+ };
+
// Note the use of the non-greedy modifier; this prevents the pattern from merging multiple
// expansions on the same text line into a single large
// but invalid expansion.
@@ -134,6 +152,11 @@
_insideBody = false;
_insideBodyErrorLogged = false;
_ignoreEvents = true;
+
+ // Stack needs a clear();
+
+ while (!_endTagHandlerStack.isEmpty())
+ _endTagHandlerStack.pop();
}
public ComponentTemplate parseTemplate(Resource templateResource)
@@ -338,6 +361,12 @@
return;
}
+ if (localName.equalsIgnoreCase("container"))
+ {
+ startContainer();
+ return;
+ }
+
// The component type is derived from the element name. Since element names may not contain
// slashes, we convert periods to slashes. Later down the pipeline, they'll probably be
// converted back into periods, as part of a fully qualified class name.
@@ -348,6 +377,12 @@
startPossibleComponent(attributes, null, componentType);
}
+ private void startContainer()
+ {
+ // Neither the container nor its end tag are considered tokens, just the contents inside.
+ _endTagHandlerStack.push(_ignoreEndElement);
+ }
+
private void startBlock(Attributes attributes)
{
String blockId = findSingleParameter("block", "id", attributes);
@@ -355,6 +390,7 @@
// null is ok for blockId
_tokens.add(new BlockToken(blockId, getCurrentLocation()));
+ _endTagHandlerStack.push(_addEndElementToken);
}
private void startParameter(Attributes attributes)
@@ -366,6 +402,7 @@
getCurrentLocation(), null);
_tokens.add(new ParameterToken(parameterName, getCurrentLocation()));
+ _endTagHandlerStack.push(_addEndElementToken);
}
private String findSingleParameter(String elementName, String attributeName,
@@ -478,6 +515,11 @@
_tokens.addAll(attributeTokens);
if (id != null) _componentIds.add(id);
+
+ // TODO: Is there value in having different end elements for components vs. ordinary
+ // elements?
+
+ _endTagHandlerStack.push(_addEndElementToken);
}
private void startBody()
@@ -486,20 +528,23 @@
_insideBody = true;
_insideBodyErrorLogged = false;
+
+ _endTagHandlerStack.push(new Runnable()
+ {
+ public void run()
+ {
+ _insideBody = false;
+
+ // And don't add an end element token.
+ }
+ });
}
public void endElement(String uri, String localName, String qName) throws SAXException
{
processTextBuffer();
- // TODO: Handle tapestry namespace elements?
-
- // Because XML tags are always balanced, we don't even need to know what element just closed
- // when we assemble things later.
-
- if (!_insideBody) _tokens.add(new EndElementToken(getCurrentLocation()));
-
- _insideBody = false;
+ _endTagHandlerStack.pop().run();
}
private Location getCurrentLocation()
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/tapestry_5_0_0.xsd
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/tapestry_5_0_0.xsd?rev=584454&r1=584453&r2=584454&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/tapestry_5_0_0.xsd (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/tapestry_5_0_0.xsd Sat Oct 13 14:13:05 2007
@@ -2,7 +2,6 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
targetNamespace="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
- <!-- body identifies where the body of the component belongs within the component's template -->
<xs:element name="body">
<xs:annotation>
<xs:documentation>
@@ -11,6 +10,14 @@
their body within their template.
</xs:documentation>
</xs:annotation>
+ </xs:element>
+ <xs:element name="container">
+ <xs:annotation>
+ <xs:documentation>
+ May be used as the root element of a template, but is not part of the template itself. Useful when
+ a component exists to emit a series of related elements that are not inside a containing element.
+ </xs:documentation>
+ </xs:annotation>
</xs:element>
<xs:element name="parameter">
<xs:annotation>
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt?rev=584454&r1=584453&r2=584454&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt Sat Oct 13 14:13:05 2007
@@ -161,6 +161,23 @@
Tapestry 4 users will recognize the \<body\> element as a replacement for the
RenderBody component.
+* \<container\>
+
+ A container element contains markup without being considered part of the template. This is useful for components that render several top level
+ tags, for example, a component that renders several columns within a table row:
+
++---+
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+ <td>${label}</td>
+ <td>${value}</td>
+</t:container>
++---+
+
+ This component only makes sense when used inside a \<tr\> element of its container's template.
+
+ Without the \<t:container\> element, there would be no way to create a valid XML document as the template, because XML documents must always
+ have a single root element.
+
* \<block\>
A block is a container of a portion of the component template. A block does not normally render; any component or contents you put inside
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java?rev=584454&r1=584453&r2=584454&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java Sat Oct 13 14:13:05 2007
@@ -96,7 +96,7 @@
}
@Test
- synchronized void just_HTML()
+ synchronized public void just_HTML()
{
Resource resource = getResource("justHTML.tml");
@@ -147,7 +147,31 @@
}
@Test
- void xml_entity()
+ public void container_element()
+ {
+ List<TemplateToken> tokens = tokens("container_element.tml");
+
+ assertEquals(tokens.size(), 4);
+
+ TextToken t0 = get(tokens, 0);
+
+ assertEquals(t0.getText().trim(), "A bit of text.");
+
+ StartElementToken t1 = get(tokens, 1);
+
+ assertEquals(t1.getName(), "foo");
+
+ EndElementToken t2 = get(tokens, 2);
+
+ assertNotNull(t2); // Keep compiler happy
+
+ TextToken t3 = get(tokens, 3);
+
+ assertEquals(t3.getText().trim(), "Some more text.");
+ }
+
+ @Test
+ public void xml_entity()
{
List<TemplateToken> tokens = tokens("xmlEntity.tml");
@@ -163,7 +187,7 @@
/** Test disabled when not online. */
@Test(enabled = false)
- void html_entity()
+ public void html_entity()
{
List<TemplateToken> tokens = tokens("html_entity.tml");
@@ -182,7 +206,7 @@
}
@Test
- void cdata()
+ public void cdata()
{
List<TemplateToken> tokens = tokens("cdata.tml");
@@ -197,7 +221,7 @@
}
@Test
- void comment()
+ public void comment()
{
List<TemplateToken> tokens = tokens("comment.tml");
@@ -215,7 +239,7 @@
}
@Test
- void multiline_comment()
+ public void multiline_comment()
{
List<TemplateToken> tokens = tokens("multilineComment.tml");
@@ -231,7 +255,7 @@
}
@Test
- void component()
+ public void component()
{
List<TemplateToken> tokens = tokens("component.tml");
@@ -247,7 +271,7 @@
}
@Test
- void component_with_body()
+ public void component_with_body()
{
List<TemplateToken> tokens = tokens("componentWithBody.tml");
@@ -308,7 +332,7 @@
}
@Test
- void body_element()
+ public void body_element()
{
List<TemplateToken> tokens = tokens("body_element.tml");
@@ -321,7 +345,7 @@
}
@Test
- void content_within_body_element()
+ public void content_within_body_element()
{
List<TemplateToken> tokens = parse("content_within_body_element.tml").getTokens();
@@ -336,7 +360,7 @@
}
@Test
- void component_with_parameters()
+ public void component_with_parameters()
{
List<TemplateToken> tokens = tokens("componentWithParameters.tml");
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/container_element.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/container_element.tml?rev=584454&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/container_element.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/container_element.tml Sat Oct 13 14:13:05 2007
@@ -0,0 +1,9 @@
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+A bit of text.
+
+<foo/>
+
+Some more text.
+
+</t:container>