This is an automated email from the ASF dual-hosted git repository.
git-site-role pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/struts-site.git
The following commit(s) were added to refs/heads/asf-site by this push:
new 9c039e8b1 Automatic Site Publish by Buildbot
9c039e8b1 is described below
commit 9c039e8b1a89edc03cd1321b7cb01ee52e53cc7e
Author: buildbot <[email protected]>
AuthorDate: Sat Dec 6 14:30:49 2025 +0000
Automatic Site Publish by Buildbot
---
output/core-developers/constant-configuration.html | 23 +++-
output/core-developers/default-properties.html | 17 +++
output/core-developers/freemarker-support.html | 67 +++++++--
output/core-developers/performance-tuning.html | 131 ++++++++++++------
.../compress-tag.html} | 150 +++++++++++----------
output/tag-developers/css-xhtml-theme.html | 17 +--
output/tag-developers/tag-reference.html | 118 +++-------------
output/tag-developers/xhtml-theme.html | 12 +-
8 files changed, 292 insertions(+), 243 deletions(-)
diff --git a/output/core-developers/constant-configuration.html
b/output/core-developers/constant-configuration.html
index 21274bc28..c17029721 100644
--- a/output/core-developers/constant-configuration.html
+++ b/output/core-developers/constant-configuration.html
@@ -153,12 +153,12 @@
<h1 id="constant-configuration">Constant Configuration</h1>
-<p>Constants provide a simple way to customize a Struts application by
defining key settings that modify framework and
-plugin behavior. There are two key roles for constants. First, they are used
to override settings like the maximum file
-upload size or whether the Struts framework should be in “devMode” or not, and
so on. Second, they specify which
+<p>Constants provide a simple way to customize a Struts application by
defining key settings that modify framework and
+plugin behavior. There are two key roles for constants. First, they are used
to override settings like the maximum file
+upload size or whether the Struts framework should be in “devMode” or not, and
so on. Second, they specify which
<a href="bean-configuration">Bean</a> implementation, among multiple
implementations of a given type, should be chosen.</p>
-<p>Constants can be declared in multiple files. By default, constants are
searched for in the following order, allowing
+<p>Constants can be declared in multiple files. By default, constants are
searched for in the following order, allowing
for subsequent files to override previous ones:</p>
<ol>
@@ -206,7 +206,7 @@ for subsequent files to override previous ones:</p>
<h3 id="value-substitution">Value substitution</h3>
-<p>Since Apache Struts 2.5.6 it is possible to use value substitution when
defining <code class="language-plaintext highlighter-rouge">constant</code>s in
<code class="language-plaintext highlighter-rouge">struts.xml</code> file.
+<p>Since Apache Struts 2.5.6 it is possible to use value substitution when
defining <code class="language-plaintext highlighter-rouge">constant</code>s in
<code class="language-plaintext highlighter-rouge">struts.xml</code> file.
You can also define a default value if given System property or ENV variable
is missing, see example below:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><struts></span>
@@ -235,6 +235,19 @@ You can also define a default value if given System
property or ENV variable is
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre
class="highlight"><code>struts.devMode = true
</code></pre></div></div>
+<p><strong>Constant Example (Performance - Struts 7.2.0+)</strong></p>
+
+<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><struts></span>
+ <span class="c"><!-- Enable FreeMarker whitespace stripping (default:
true, auto-disabled in devMode) --></span>
+ <span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.freemarker.whitespaceStripping"</span> <span
class="na">value=</span><span class="s">"true"</span> <span
class="nt">/></span>
+
+ <span class="c"><!-- Control HTML compression globally --></span>
+ <span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.tag.compress.enabled"</span> <span
class="na">value=</span><span class="s">"true"</span> <span
class="nt">/></span>
+ <span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.tag.compress.maxSize"</span> <span
class="na">value=</span><span class="s">"10485760"</span> <span
class="nt">/></span>
+ <span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.tag.compress.log.maxLength"</span> <span
class="na">value=</span><span class="s">"200"</span> <span
class="nt">/></span>
+<span class="nt"></struts></span>
+</code></pre></div></div>
+
<p><strong>Constant Example (web.xml)</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><web-app</span> <span
class="na">id=</span><span class="s">"WebApp_9"</span> <span
class="na">version=</span><span class="s">"2.4"</span>
diff --git a/output/core-developers/default-properties.html
b/output/core-developers/default-properties.html
index 3edf686ba..3006ea88b 100644
--- a/output/core-developers/default-properties.html
+++ b/output/core-developers/default-properties.html
@@ -374,6 +374,23 @@ struts.freemarker.wrapper.altMap=true
### check WW-3766 for more details
struts.freemarker.mru.max.strong.size=0
+### Controls FreeMarker whitespace stripping during template compilation.
+### Automatically disabled when devMode is enabled.
+struts.freemarker.whitespaceStripping=true
+
+### Controls whether the compress tag is enabled globally.
+struts.tag.compress.enabled=true
+
+### Maximum size (in bytes) of body content that can be compressed.
+### Content exceeding this limit will be skipped without compression.
+### Default: 10MB (10485760 bytes)
+struts.tag.compress.maxSize=10485760
+
+### Maximum length of body content to include in log messages.
+### Content longer than this will be truncated with length indicator.
+### Default: 200 characters
+struts.tag.compress.log.maxLength=200
+
### configure the XSLTResult class to use stylesheet caching.
### Set to true for developers and false for production.
struts.xslt.nocache=false
diff --git a/output/core-developers/freemarker-support.html
b/output/core-developers/freemarker-support.html
index 8741f117d..a2fceada3 100644
--- a/output/core-developers/freemarker-support.html
+++ b/output/core-developers/freemarker-support.html
@@ -151,13 +151,24 @@
<a href="freemarker-result" title="back to Freemarker Result"><< back to
Freemarker Result</a>
- <h1 id="freemarker-support">Freemarker Support</h1>
+ <h1 class="no_toc" id="freemarker-support">Freemarker Support</h1>
+
+<ul id="markdown-toc">
+ <li><a href="#configure-your-action-to-use-the-freemarker-result-type"
id="markdown-toc-configure-your-action-to-use-the-freemarker-result-type">Configure
your action to use the freemarker result type</a></li>
+ <li><a href="#property-resolution"
id="markdown-toc-property-resolution">Property Resolution</a></li>
+ <li><a href="#objects-in-the-context"
id="markdown-toc-objects-in-the-context">Objects in the Context</a></li>
+ <li><a href="#freemarker-configuration-with-recent-releases"
id="markdown-toc-freemarker-configuration-with-recent-releases">FreeMarker
configuration with recent releases</a></li>
+ <li><a href="#freemarker-whitespace-stripping"
id="markdown-toc-freemarker-whitespace-stripping">FreeMarker Whitespace
Stripping</a></li>
+ <li><a href="#using-struts-ui-tags---or-any-jsp-tag-library"
id="markdown-toc-using-struts-ui-tags---or-any-jsp-tag-library">Using struts UI
tags - or any JSP Tag Library</a></li>
+ <li><a href="#dynamic-attributes-support"
id="markdown-toc-dynamic-attributes-support">Dynamic attributes support</a></li>
+</ul>
<p>Freemarker views can be rendered using a result type <code
class="language-plaintext highlighter-rouge">freemarker</code>.</p>
<h2 id="configure-your-action-to-use-the-freemarker-result-type">Configure
your action to use the freemarker result type</h2>
-<p>The <code class="language-plaintext highlighter-rouge">freemarker</code>
result type is defined in <code class="language-plaintext
highlighter-rouge">struts-default.xml</code>, so normally you just include it,
and define your results to use <code class="language-plaintext
highlighter-rouge">type="freemarker"</code>.</p>
+<p>The <code class="language-plaintext highlighter-rouge">freemarker</code>
result type is defined in <code class="language-plaintext
highlighter-rouge">struts-default.xml</code>, so normally you just include it,
and define your
+results to use <code class="language-plaintext
highlighter-rouge">type="freemarker"</code>.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><include</span> <span
class="na">file=</span><span class="s">"struts-default.xml"</span><span
class="nt">/></span>
...
@@ -196,7 +207,7 @@
<li><code class="language-plaintext highlighter-rouge">stack</code> - the
current <code class="language-plaintext
highlighter-rouge">OgnlValueStack</code></li>
<li><code class="language-plaintext highlighter-rouge">ognl</code> - the
<code class="language-plaintext highlighter-rouge">OgnlTool</code> instance
<ul>
- <li>This class contains useful methods to execute OGNL expressions
against arbitary objects, and a method to generate a select list using
+ <li>This class contains useful methods to execute OGNL expressions
against arbitrary objects, and a method to generate a select list using
the <code class="language-plaintext
highlighter-rouge"><s:select/></code> pattern. (i.e. taking the name of
the list property, a listKey and listValue)</li>
</ul>
</li>
@@ -207,8 +218,8 @@ the <code class="language-plaintext
highlighter-rouge"><s:select/></code>
<h2 id="freemarker-configuration-with-recent-releases">FreeMarker
configuration with recent releases</h2>
-<p>To configure the freemarker engine that Struts uses, just add a file <code
class="language-plaintext highlighter-rouge">freemarker.properties</code> to
the classpath. The supported properties
-are those that the Freemarker Configuration object expects - see the <a
href="https://freemarker.apache.org/docs/api/freemarker/template/Configuration.html#setSetting-java.lang.String-java.lang.String-">Freemarker
documentation</a>
+<p>To configure the freemarker engine that Struts uses, just add a file <code
class="language-plaintext highlighter-rouge">freemarker.properties</code> to
the classpath.
+The supported properties are those that the Freemarker Configuration object
expects - see the <a
href="https://freemarker.apache.org/docs/api/freemarker/template/Configuration.html#setSetting-java.lang.String-java.lang.String-">Freemarker
documentation</a>
for these.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre
class="highlight"><code>default_encoding=ISO-8859-1
@@ -216,13 +227,51 @@ template_update_delay=5
locale=no_NO
</code></pre></div></div>
+<h2 id="freemarker-whitespace-stripping">FreeMarker Whitespace Stripping</h2>
+
+<p><strong>Available since Struts 7.2.0</strong></p>
+
+<p>Struts supports automatic whitespace stripping during FreeMarker template
compilation. When enabled, this feature
+removes indentation and trailing whitespace from lines containing only FTL
directives, significantly reducing the size
+of generated HTML output.</p>
+
+<p>This feature is controlled by the <code class="language-plaintext
highlighter-rouge">struts.freemarker.whitespaceStripping</code> constant:</p>
+
+<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><constant</span> <span
class="na">name=</span><span
class="s">"struts.freemarker.whitespaceStripping"</span> <span
class="na">value=</span><span class="s">"true"</span> <span
class="nt">/></span>
+</code></pre></div></div>
+
+<p><strong>Default behavior:</strong></p>
+
+<ul>
+ <li><strong>Enabled by default</strong> (<code class="language-plaintext
highlighter-rouge">true</code>)</li>
+ <li><strong>Automatically disabled</strong> when <code
class="language-plaintext highlighter-rouge">struts.devMode</code> is enabled
to make debugging easier</li>
+ <li>Works transparently with existing templates</li>
+</ul>
+
+<p><strong>Benefits:</strong></p>
+
+<ul>
+ <li>Reduces HTML output size by removing template indentation</li>
+ <li>Improves page load times and reduces bandwidth usage</li>
+ <li>No changes needed to existing FreeMarker templates</li>
+ <li>Automatically disabled in development mode for easier debugging</li>
+</ul>
+
+<p><strong>See also:</strong></p>
+
+<ul>
+ <li><a
href="performance-tuning#enable-freemarker-whitespace-stripping">Performance
Tuning - FreeMarker Whitespace Stripping</a></li>
+ <li><a href="../tag-developers/compress-tag">Compress Tag</a> for runtime
HTML compression</li>
+</ul>
+
<h2 id="using-struts-ui-tags---or-any-jsp-tag-library">Using struts UI tags -
or any JSP Tag Library</h2>
<p>Freemarker has builtin support for using any JSP taglib. You can use JSP
taglibs in FreeMarker even if</p>
+
<ul>
<li>your servlet container has no support for JSP, or</li>
- <li>you didn’t specify the taglib in your web.xml - note how in the example
below we refer to the taglib by its webapp-absolute URL,
- so no configuration in web.xml is needed.</li>
+ <li>you didn’t specify the taglib in your web.xml - note how in the example
below we refer to the taglib by its
+webapp-absolute URL, so no configuration in web.xml is needed.</li>
</ul>
<div class="language-ftl highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="err"><#</span><span
class="no">assign</span><span class="w">
</span>s=JspTaglibs["/WEB-INF/struts.tld"] /><span class="w">
@@ -235,8 +284,8 @@ locale=no_NO
</span></code></pre></div></div>
-<p><em>NOTE</em>: numeric properties for tags MUST be numbers, not strings. as
in the rows and cols properties above. if you use <code
class="language-plaintext highlighter-rouge">cols="40"</code> you will
-receive an exception. Other than that, the freemarker tag container behaves as
you would expect.</p>
+<p><em>NOTE</em>: numeric properties for tags MUST be numbers, not strings. as
in the rows and cols properties above. If you use
+<code class="language-plaintext highlighter-rouge">cols="40"</code> you will
receive an exception. Other than that, the freemarker tag container behaves as
you would expect.</p>
<h2 id="dynamic-attributes-support">Dynamic attributes support</h2>
diff --git a/output/core-developers/performance-tuning.html
b/output/core-developers/performance-tuning.html
index 94ec2dbc4..107f18faa 100644
--- a/output/core-developers/performance-tuning.html
+++ b/output/core-developers/performance-tuning.html
@@ -151,45 +151,37 @@
<a href="index" title="back to Core Developers"><< back to Core
Developers</a>
- <h1 class="no_toc" id="performance-tuning">Performance Tuning</h1>
-
-<ul id="markdown-toc">
- <li><a href="#turn-off-logging-and-devmode"
id="markdown-toc-turn-off-logging-and-devmode">Turn off logging and
devMode</a></li>
- <li><a href="#use-the-java-templates"
id="markdown-toc-use-the-java-templates">Use the Java Templates</a></li>
- <li><a href="#do-not-use-interceptors-you-do-not-need"
id="markdown-toc-do-not-use-interceptors-you-do-not-need">Do not use
interceptors you do not need</a></li>
- <li><a href="#use-the-correct-http-headers-cache-control--expires"
id="markdown-toc-use-the-correct-http-headers-cache-control--expires">Use the
correct HTTP headers (Cache-Control & Expires)</a></li>
- <li><a
href="#copy-the-static-content-from-the-struts-2-jar-when-using-the-ajax-theme-dojo-or-the-calendar-tag"
id="markdown-toc-copy-the-static-content-from-the-struts-2-jar-when-using-the-ajax-theme-dojo-or-the-calendar-tag">Copy
the static content from the Struts 2 jar when using the Ajax theme (Dojo) or
the Calendar tag</a></li>
- <li><a
href="#create-a-freemarkerproperties-file-in-your-web-infclasses-directory"
id="markdown-toc-create-a-freemarkerproperties-file-in-your-web-infclasses-directory">Create
a freemarker.properties file in your WEB-INF/classes directory</a></li>
- <li><a href="#enable-freemarker-template-caching"
id="markdown-toc-enable-freemarker-template-caching">Enable Freemarker template
caching</a></li>
- <li><a
href="#when-overriding-a-theme-copy-all-necessary-templates-to-the-theme-directory"
id="markdown-toc-when-overriding-a-theme-copy-all-necessary-templates-to-the-theme-directory">When
overriding a theme, copy all necessary templates to the theme
directory</a></li>
- <li><a href="#do-not-create-sessions-unless-you-need-them"
id="markdown-toc-do-not-create-sessions-unless-you-need-them">Do not create
sessions unless you need them</a></li>
- <li><a
href="#when-using-freemarker-try-to-use-the-freemarker-equivalent-rather-than-using-the-jsp-tags"
id="markdown-toc-when-using-freemarker-try-to-use-the-freemarker-equivalent-rather-than-using-the-jsp-tags">When
using Freemarker, try to use the Freemarker equivalent rather than using the
JSP tags</a></li>
+ <h1 id="performance-tuning">Performance Tuning</h1>
+
+<ul class="no_toc">
+ <li>Will be replaced with the ToC, excluding a header</li>
</ul>
<p>The following are some tips and tricks to squeeze the most performance out
of Struts 2.</p>
<blockquote>
<p>For Struts 2 versions before 2.3: the OGNL version 3.0.3 library is a
drop-in replacement for older OGNL jars,
-and provides <strong>much</strong> better performance. See the following JIRA
issue for more information:
+and provides <strong>much</strong> better performance. See the following JIRA
issue for more information:
<a href="https://issues.apache.org/jira/browse/WW-3580">WW-3580</a></p>
</blockquote>
<h2 id="turn-off-logging-and-devmode">Turn off logging and devMode</h2>
-<p>The <a href="development-mode">devMode</a> allows reloading of
configuration and validation related files, but because they happen on each
-request, this setting will totally kill your performance.
-When using logging, make sure to turn off logging (esp. Freemarker generates a
LOT of logging), and check if a level is
-enabled before printing it, or you will get the cost of the String
parsing/concatenation anyways.</p>
+<p>The <a href="development-mode">devMode</a> allows reloading of
configuration and validation related files, but because they happen
+on each request, this setting will totally kill your performance. When using
logging, make sure to turn off logging
+(esp. Freemarker generates a LOT of logging), and check if a level is enabled
before printing it, or you will get
+the cost of the String parsing/concatenation anyways.</p>
<h2 id="use-the-java-templates">Use the Java Templates</h2>
-<p>If you use the simple theme, and do not overwrite any of the FreeMarker
templates, consider using the <a href="../plugins/javatemplates-plugin/">java
templates</a>,
+<p>If you use the simple theme, and do not overwrite any of the FreeMarker
templates, consider using
+the <a href="../plugins/javatemplates-plugin/">java templates</a>,
which provide a drop in replacement for most of the tags, and are a lot faster
than the regular tags.</p>
<h2 id="do-not-use-interceptors-you-do-not-need">Do not use interceptors you
do not need</h2>
-<p>If you do not require a full stack of interceptors for an Action, then try
using a different one (basicStack),
-or remove interceptors you do not need. Remove the <code
class="language-plaintext highlighter-rouge">I18nInterceptor</code> interceptor
if you don’t need it, as it can cause
+<p>If you do not require a full stack of interceptors for an Action, then try
using a different one (basicStack),
+or remove interceptors you do not need. Remove the <code
class="language-plaintext highlighter-rouge">I18nInterceptor</code> interceptor
if you don’t need it, as it can cause
a session to be created.</p>
<h2 id="use-the-correct-http-headers-cache-control--expires">Use the correct
HTTP headers (Cache-Control & Expires)</h2>
@@ -198,9 +190,10 @@ a session to be created.</p>
<h2
id="copy-the-static-content-from-the-struts-2-jar-when-using-the-ajax-theme-dojo-or-the-calendar-tag">Copy
the static content from the Struts 2 jar when using the Ajax theme (Dojo) or
the Calendar tag</h2>
-<p>Struts 2 uses some external javascript libraries and cascading stylesheets
for certain themes and tags. These by default
-are located inside the Struts 2 jar, and a special filter returns them when
requesting a special path (<code class="language-plaintext
highlighter-rouge">/static</code>).
-Although Struts 2 can handle these requests, an application/servlet container
is not optimized for these kind of requests.
+<p>Struts 2 uses some external javascript libraries and cascading stylesheets
for certain themes and tags. These by default
+are located inside the Struts 2 jar, and a special filter returns them when
requesting a special path (<code class="language-plaintext
highlighter-rouge">/static</code>).
+Although Struts 2 can handle these requests, an application/servlet container
is not optimized for these kind of
+requests.
Consider moving these .js and .css files to a seperated server (Lighttpd,
Apache HTTPD, ..).</p>
<h2
id="create-a-freemarkerproperties-file-in-your-web-infclasses-directory">Create
a freemarker.properties file in your WEB-INF/classes directory</h2>
@@ -210,8 +203,9 @@ Consider moving these .js and .css files to a seperated
server (Lighttpd, Apache
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre
class="highlight"><code>template_update_delay=60000
</code></pre></div></div>
-<p>This value determines how often Freemarker checks if it needs to reloads
the templates from disk. The default value
-is 500 ms. Since there is no reason to check if a template needs reloading, it
is best to set this to a very large value.
+<p>This value determines how often Freemarker checks if it needs to reloads
the templates from disk. The default value
+is 500 ms. Since there is no reason to check if a template needs reloading, it
is best to set this to a very large
+value.
Note that this value is in seconds and freemarker will convert this value to
milliseconds.</p>
<p>You can also use <code class="language-plaintext
highlighter-rouge">struts.freemarker.templatesCache.updateDelay</code> constant
to achieve the same effect.</p>
@@ -221,36 +215,97 @@ Note that this value is in seconds and freemarker will
convert this value to mil
<h2 id="enable-freemarker-template-caching">Enable Freemarker template
caching</h2>
<blockquote>
- <p>Note: support for this options has been removed in Struts. See the <a
href="../tag-developers/freemarker#cache">Cache</a> section of the FreeMarker
page.</p>
+ <p>Note: support for this options has been removed in Struts. See the <a
href="../tag-developers/freemarker#cache">Cache</a> section
+of the FreeMarker page.</p>
</blockquote>
-<p>As of Struts 2.0.10, setting the property <code class="language-plaintext
highlighter-rouge">struts.freemarker.templatesCache</code> to true will enable
the Struts internal
+<p>As of Struts 2.0.10, setting the property <code class="language-plaintext
highlighter-rouge">struts.freemarker.templatesCache</code> to true will enable
the Struts internal
caching of Freemarker templates. This property is set to false by default.</p>
-<p>In Struts versions prior to 2.0.10, you had to copy the <code
class="language-plaintext highlighter-rouge">/template</code> directory from
the Struts 2 jar in your <code class="language-plaintext
highlighter-rouge">WEB_APP</code>
+<p>In Struts versions prior to 2.0.10, you had to copy the <code
class="language-plaintext highlighter-rouge">/template</code> directory from
the Struts 2 jar in your <code class="language-plaintext
highlighter-rouge">WEB_APP</code>
root to utilize Freemarker’s built in caching mechanism in order to achieve
similar results.</p>
-<p>The built in Freemarker caching mechanism fails to properly cache templates
when they are retrieved from the classpath.
-Copying them to the WEB_APP root allows Freemarker to cache them correctly.
Freemarker looks at the last modified time
-of the template to determine if it needs to reload the templates. Resources
retrieved from the classpath have no last
+<p>The built in Freemarker caching mechanism fails to properly cache templates
when they are retrieved from the classpath.
+Copying them to the WEB_APP root allows Freemarker to cache them correctly.
Freemarker looks at the last modified time
+of the template to determine if it needs to reload the templates. Resources
retrieved from the classpath have no last
modified time, so Freemarker will reload them on every request.</p>
+<h2 id="enable-freemarker-whitespace-stripping">Enable FreeMarker Whitespace
Stripping</h2>
+
+<p><strong>Available since Struts 7.2.0</strong></p>
+
+<p>Struts now supports automatic whitespace stripping during FreeMarker
template compilation, which removes indentation and
+trailing whitespace from lines containing only FTL tags. This significantly
reduces the size of generated HTML output
+without affecting the visual presentation.</p>
+
+<p>This feature is enabled by default and automatically disabled when <code
class="language-plaintext highlighter-rouge">devMode</code> is active to make
debugging easier.</p>
+
+<p><strong>Configuration:</strong></p>
+
+<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code>
+<span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.freemarker.whitespaceStripping"</span> <span
class="na">value=</span><span class="s">"true"</span><span
class="nt">/></span>
+</code></pre></div></div>
+
+<p>Or in <code class="language-plaintext
highlighter-rouge">struts.properties</code>:</p>
+
+<div class="language-properties highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span
class="py">struts.freemarker.whitespaceStripping</span><span
class="p">=</span><span class="s">true</span>
+</code></pre></div></div>
+
+<p><strong>Default value:</strong> <code class="language-plaintext
highlighter-rouge">true</code> (automatically disabled in devMode)</p>
+
+<h2 id="use-the-compress-tag-for-html-output-optimization">Use the Compress
Tag for HTML Output Optimization</h2>
+
+<p><strong>Available since Struts 7.2.0</strong></p>
+
+<p>The <code class="language-plaintext
highlighter-rouge"><s:compress></code> tag provides runtime HTML
compression by removing unnecessary whitespace between tags. This
+complements FreeMarker whitespace stripping and can further reduce output size
for specific sections of your pages.</p>
+
+<p><strong>Usage:</strong></p>
+
+<div class="language-jsp highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><s:compress></span>
+ <span class="nt"><div></span>
+ <span class="nt"><p></span>Content here will be compressed<span
class="nt"></p></span>
+ <span class="nt"></div></span>
+<span class="nt"></s:compress></span>
+</code></pre></div></div>
+
+<p><strong>Configuration:</strong></p>
+
+<p>Control compression globally:</p>
+
+<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code>
+<span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.tag.compress.enabled"</span> <span
class="na">value=</span><span class="s">"true"</span><span
class="nt">/></span>
+<span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.tag.compress.maxSize"</span> <span
class="na">value=</span><span class="s">"10485760"</span><span
class="nt">/></span>
+</code></pre></div></div>
+
+<p>The compress tag is enabled by default and includes security
protections:</p>
+
+<ul>
+ <li>Maximum content size limit (10MB default) prevents DoS attacks</li>
+ <li>Body content truncation in logs (200 chars default) prevents sensitive
data exposure</li>
+ <li>ReDoS safeguards for regex operations</li>
+</ul>
+
+<p>For development debugging, compression is automatically disabled in devMode
unless you use the <code class="language-plaintext
highlighter-rouge">force="true"</code> attribute.</p>
+
+<p><strong>See also:</strong> <a
href="../tag-developers/compress-tag">Compress Tag</a></p>
+
<h2
id="when-overriding-a-theme-copy-all-necessary-templates-to-the-theme-directory">When
overriding a theme, copy all necessary templates to the theme directory</h2>
-<p>There’s a performance cost when a template cannot be found in the current
directory. The reason for this is that
-Struts 2 must check for a template in the current theme first before falling
back to the parent theme. In the future,
+<p>There’s a performance cost when a template cannot be found in the current
directory. The reason for this is that
+Struts 2 must check for a template in the current theme first before falling
back to the parent theme. In the future,
this penalty could be eliminated by implementing a missing template cache in
Struts 2.</p>
<h2 id="do-not-create-sessions-unless-you-need-them">Do not create sessions
unless you need them</h2>
-<p>Struts 2 does not create sessions unless asked to (for example, by having
the createSession interceptor in your
-interceptor stack). Note that when you use SiteMesh however, a session will
<strong>always</strong> be created.
+<p>Struts 2 does not create sessions unless asked to (for example, by having
the createSession interceptor in your
+interceptor stack). Note that when you use SiteMesh however, a session will
<strong>always</strong> be created.
The I18nInterceptor interceptor can create sessions, so make sure you remove
it, if you don’t need it.</p>
<h2
id="when-using-freemarker-try-to-use-the-freemarker-equivalent-rather-than-using-the-jsp-tags">When
using Freemarker, try to use the Freemarker equivalent rather than using the
JSP tags</h2>
-<p>Freemarker has support for iterating lists, displaying properties,
including other templates, macro’s, and so on.
-There is a small performance cost when using the S2 tags instead of the
Freemarker equivalent
+<p>Freemarker has support for iterating lists, displaying properties,
including other templates, macro’s, and so on.
+There is a small performance cost when using the S2 tags instead of the
Freemarker equivalent
(eg. <code class="language-plaintext highlighter-rouge"><s:property
value="foo"/></code> should be replaced by <code class="language-plaintext
highlighter-rouge">${foo}</code>).</p>
</section>
diff --git a/output/core-developers/constant-configuration.html
b/output/tag-developers/compress-tag.html
similarity index 62%
copy from output/core-developers/constant-configuration.html
copy to output/tag-developers/compress-tag.html
index 21274bc28..1ce7a5714 100644
--- a/output/core-developers/constant-configuration.html
+++ b/output/tag-developers/compress-tag.html
@@ -7,7 +7,7 @@
<meta http-equiv="Content-Language" content="en"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
- <title>Constant Configuration</title>
+ <title>compress tag</title>
<link href="/css/source-sans-pro.css" rel="stylesheet" type="text/css">
<link href="/css/font-awesome.css" rel="stylesheet">
@@ -147,114 +147,116 @@
<article class="container">
<section class="col-md-12">
- <a class="edit-on-gh"
href="https://github.com/apache/struts-site/edit/main/source/core-developers/constant-configuration.md"
title="Edit this page on GitHub">Edit on GitHub</a>
+ <a class="edit-on-gh"
href="https://github.com/apache/struts-site/edit/main/source/tag-developers/compress-tag.md"
title="Edit this page on GitHub">Edit on GitHub</a>
- <a href="index" title="back to Core Developers"><< back to Core
Developers</a>
+ <a href="tag-reference" title="back to Tag Reference"><< back to Tag
Reference</a>
- <h1 id="constant-configuration">Constant Configuration</h1>
+ <h1 id="compress">compress</h1>
-<p>Constants provide a simple way to customize a Struts application by
defining key settings that modify framework and
-plugin behavior. There are two key roles for constants. First, they are used
to override settings like the maximum file
-upload size or whether the Struts framework should be in “devMode” or not, and
so on. Second, they specify which
-<a href="bean-configuration">Bean</a> implementation, among multiple
implementations of a given type, should be chosen.</p>
+<p>Please make sure you have read the <a href="tag-syntax">Tag Syntax</a>
document and understand how tag attribute syntax works.</p>
-<p>Constants can be declared in multiple files. By default, constants are
searched for in the following order, allowing
-for subsequent files to override previous ones:</p>
+<h2 id="description">Description</h2>
-<ol>
- <li><a href="struts-default-xml">struts-default.xml</a></li>
- <li><a href="../plugins/plugins-architecture">struts-plugin.xml</a></li>
- <li><a href="struts-xml">struts.xml</a></li>
- <li><a href="default-properties">default.properties</a></li>
- <li><a href="web-xml">web.xml</a></li>
- <li><a href="../plugins/plugins-architecture">struts-deferred.xml</a></li>
-</ol>
+<p>Compresses HTML output by removing unnecessary whitespace between tags
while preserving content within tags. This helps
+reduce the size of generated HTML output, improving page load times and
bandwidth usage.</p>
-<blockquote>
- <p>The <code class="language-plaintext
highlighter-rouge">struts.properties</code> file is provided for
backward-compatibility with WebWork.</p>
-</blockquote>
+<p>The compress tag can be controlled globally via the <code
class="language-plaintext highlighter-rouge">struts.tag.compress.enabled</code>
configuration property and is
+automatically disabled in development mode for easier debugging.</p>
-<h2 id="constant">Constant</h2>
+<p>Compress wrapped content</p>
-<p>In the various XML variants, the constant element has two required
attributes: <code class="language-plaintext highlighter-rouge">name</code> and
<code class="language-plaintext highlighter-rouge">value</code>.</p>
+<p><b>Security:</b> The compress tag includes built-in protections against DoS
attacks and sensitive data exposure. Large content exceeding the configured
maximum size (default 10MB) will be skipped without compression. Log messages
are automatically truncated to prevent sensitive data from appearing in
logs.</p>
-<table>
- <thead>
+<h2 id="attributes">Attributes</h2>
+
+<table class="tag-reference">
+ <tr>
+ <td colspan="6"><h4>Dynamic Attributes Allowed:</h4> false</td>
+ </tr>
<tr>
- <th>Attribute</th>
- <th>Required</th>
- <th>Description</th>
+ <td colspan="6"><hr /></td>
</tr>
- </thead>
- <tbody>
<tr>
- <td>name</td>
- <td><strong>yes</strong></td>
- <td>the name of the constant</td>
+ <th class="tag-header"><h4>Name</h4></th>
+ <th class="tag-header"><h4>Required</h4></th>
+ <th class="tag-header"><h4>Default</h4></th>
+ <th class="tag-header"><h4>Evaluated</h4></th>
+ <th class="tag-header"><h4>Type</h4></th>
+ <th class="tag-header"><h4>Description</h4></th>
</tr>
<tr>
- <td>value</td>
- <td><strong>yes</strong></td>
- <td>the value of the constant</td>
+ <td class="tag-attribute">force</td>
+ <td class="tag-attribute">false</td>
+ <td class="tag-attribute"></td>
+ <td class="tag-attribute">false</td>
+ <td class="tag-attribute">String</td>
+ <td class="tag-attribute">Force output compression</td>
+ </tr>
+ <tr>
+ <td class="tag-attribute">performClearTagStateForTagPoolingServers</td>
+ <td class="tag-attribute">false</td>
+ <td class="tag-attribute">false</td>
+ <td class="tag-attribute">false</td>
+ <td class="tag-attribute">Boolean</td>
+ <td class="tag-attribute">Whether to clear all tag state during
doEndTag() processing (if applicable)</td>
</tr>
- </tbody>
</table>
-<p>In the <a href="default-properties">default.properties</a> file, each entry
is treated as a constant.</p>
-
-<p>In the <a href="web-xml">web.xml</a> file, any FilterDispatcher
initialization parameters are loaded as constants.</p>
+<h2 id="security-features">Security Features</h2>
-<h3 id="value-substitution">Value substitution</h3>
+<ul>
+ <li>Body content truncation in logs prevents sensitive data exposure</li>
+ <li>Maximum size limits (10MB default) prevent DoS attacks via large
inputs</li>
+ <li>Regex operations include ReDoS safeguards with 50MB hard limit</li>
+</ul>
-<p>Since Apache Struts 2.5.6 it is possible to use value substitution when
defining <code class="language-plaintext highlighter-rouge">constant</code>s in
<code class="language-plaintext highlighter-rouge">struts.xml</code> file.
-You can also define a default value if given System property or ENV variable
is missing, see example below:</p>
+<h2 id="examples">Examples</h2>
-<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><struts></span>
- <span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"os"</span> <span class="na">value=</span><span class="s">"Current OS
= ${os.name}"</span><span class="nt">/></span>
+<p><strong>Basic usage:</strong></p>
- <span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.devMode"</span> <span class="na">value=</span><span
class="s">"${env.STRUTS_DEV_MODE:false}"</span><span class="nt">/></span>
-<span class="nt"></struts></span>
+<div class="language-jsp highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><s:compress></span>
+ <span class="nt"><div></span>
+ <span class="nt"><p></span>This HTML will be compressed<span
class="nt"></p></span>
+ <span class="nt"><span></span>Whitespace between tags will be
removed<span class="nt"></span></span>
+ <span class="nt"></div></span>
+<span class="nt"></s:compress></span>
</code></pre></div></div>
-<p>Note: substitution is limited to System properties and ENV variables and
works only for <code class="language-plaintext
highlighter-rouge">constant</code>s (as for now).</p>
-
-<h2 id="examples">Examples</h2>
+<p><strong>Force compression in development mode:</strong></p>
-<p><strong>Constant Example (struts.xml)</strong></p>
+<div class="language-jsp highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><s:compress </span><span
class="na">force=</span><span class="s">"true"</span><span
class="nt">></span>
+ <span class="nt"><div></span>
+ <span class="nt"><p></span>This will be compressed even in
devMode<span class="nt"></p></span>
+ <span class="nt"></div></span>
+<span class="nt"></s:compress></span>
+</code></pre></div></div>
-<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><struts></span>
+<p><strong>Configuration:</strong></p>
- <span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.devMode"</span> <span class="na">value=</span><span
class="s">"true"</span> <span class="nt">/></span>
- ...
+<p>Control compression globally in <code class="language-plaintext
highlighter-rouge">struts.xml</code>:</p>
-<span class="nt"></struts></span>
+<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code>
+<span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.tag.compress.enabled"</span> <span
class="na">value=</span><span class="s">"true"</span><span
class="nt">/></span>
+<span class="nt"><constant</span> <span class="na">name=</span><span
class="s">"struts.tag.compress.maxSize"</span> <span
class="na">value=</span><span class="s">"10485760"</span><span
class="nt">/></span>
</code></pre></div></div>
-<p><strong>Constant Example (struts.properties)</strong></p>
+<p>Or in <code class="language-plaintext
highlighter-rouge">struts.properties</code>:</p>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre
class="highlight"><code>struts.devMode = true
+<div class="language-properties highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span
class="py">struts.tag.compress.enabled</span><span class="p">=</span><span
class="s">true</span>
+<span class="py">struts.tag.compress.maxSize</span><span
class="p">=</span><span class="s">10485760</span>
</code></pre></div></div>
-<p><strong>Constant Example (web.xml)</strong></p>
-
-<div class="language-xml highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="nt"><web-app</span> <span
class="na">id=</span><span class="s">"WebApp_9"</span> <span
class="na">version=</span><span class="s">"2.4"</span>
- <span class="na">xmlns=</span><span
class="s">"http://java.sun.com/xml/ns/j2ee"</span>
- <span class="na">xmlns:xsi=</span><span
class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
- <span class="na">xsi:schemaLocation=</span><span
class="s">"http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</span><span
class="nt">></span>
+<h2 id="related-configuration">Related Configuration</h2>
- <span class="nt"><filter></span>
- <span class="nt"><filter-name></span>struts<span
class="nt"></filter-name></span>
- <span
class="nt"><filter-class></span>org.apache.struts2.dispatcher.StrutsPrepareAndExecuteFilter<span
class="nt"></filter-class></span>
- <span class="nt"><init-param></span>
- <span class="nt"><param-name></span>struts.devMode<span
class="nt"></param-name></span>
- <span class="nt"><param-value></span>true<span
class="nt"></param-value></span>
- <span class="nt"></init-param></span>
- <span class="nt"></filter></span>
+<ul>
+ <li><code class="language-plaintext
highlighter-rouge">struts.tag.compress.enabled</code> - Controls whether
compression is enabled globally (default: true)</li>
+ <li><code class="language-plaintext
highlighter-rouge">struts.tag.compress.maxSize</code> - Maximum size in bytes
of content that can be compressed (default: 10485760 = 10MB)</li>
+ <li><code class="language-plaintext
highlighter-rouge">struts.tag.compress.log.maxLength</code> - Maximum length of
body content in log messages (default: 200)</li>
+</ul>
- ...
+<h2 id="since">Since</h2>
-<span class="nt"></web-app></span>
-</code></pre></div></div>
+<p>Available since Struts 7.2.0</p>
</section>
</article>
diff --git a/output/tag-developers/css-xhtml-theme.html
b/output/tag-developers/css-xhtml-theme.html
index 2d35eeb3b..45ba6d31b 100644
--- a/output/tag-developers/css-xhtml-theme.html
+++ b/output/tag-developers/css-xhtml-theme.html
@@ -289,29 +289,26 @@ block before the element is displayed.</p>
*/
-->
${attributes.after!}<#t/>
- <#lt/>
<#if !attributes.labelPosition?? &&
(attributes.form.labelPosition)??>
<#assign labelPos = attributes.form.labelPosition/>
<#elseif attributes.labelPosition??>
<#assign labelPos = attributes.labelPosition/>
</#if>
<#if (labelPos!"top") == 'top'>
-</div> <#rt/>
+</div><#rt/>
<#else>
-</span> <#rt/>
+</span><#rt/>
</#if>
<#if (attributes.errorposition!"top") == 'bottom'>
<#assign hasFieldErrors = attributes.name?? && fieldErrors??
&& fieldErrors.get(attributes.name)??/>
<#if hasFieldErrors>
<div <#rt/><#if
attributes.id??>id="wwerr_${attributes.id}"<#rt/></#if>
class="wwerr">
<#list fieldErrors.get(attributes.name) as error>
- <div<#rt/>
- <#if attributes.id??>
- errorFor="${attributes.id}"<#rt/>
- </#if>
- class="errorMessage">
- ${error}
- </div><#t/>
+<div<#rt/>
+<#if attributes.id??>
+ errorFor="${attributes.id}"<#rt/>
+</#if>
+ class="errorMessage">${error}</div><#rt/>
</#list>
</div><#t/>
</#if>
diff --git a/output/tag-developers/tag-reference.html
b/output/tag-developers/tag-reference.html
index ae28cd51f..6c8fcc9de 100644
--- a/output/tag-developers/tag-reference.html
+++ b/output/tag-developers/tag-reference.html
@@ -158,9 +158,9 @@
<li><a href="#ui-tag-reference" id="markdown-toc-ui-tag-reference">UI Tag
Reference</a></li>
</ul>
-<p>Generic tags are used for controlling the execution flow when the pages
render. These tags also allow for data extraction
-from places other than your action or the value stack, such as
<em>Localization</em> , JavaBeans, and including additional URLs
-or action executions.</p>
+<p>Generic tags are used for controlling the execution flow when the pages
render. These tags also allow for data
+extraction from places other than your action or the value stack, such as
<em>Localization</em> , JavaBeans, and including
+additional URLs or action executions.</p>
<ul>
<li>Control Tags provide control flow, such as <code
class="language-plaintext highlighter-rouge">if</code>, <code
class="language-plaintext highlighter-rouge">else</code>, and <code
class="language-plaintext highlighter-rouge">iterator</code></li>
@@ -176,118 +176,78 @@ or action executions.</p>
<p>Struts Generic Tags control the execution flow as pages render.</p>
<table>
- <tbody>
+ <thead>
<tr>
- <td><strong>Control Tags</strong></td>
- <td> </td>
- <td><strong>Data Tags</strong></td>
- <td> </td>
- <td><strong>Other Tags</strong></td>
- <td> </td>
+ <th><strong>Control Tags</strong></th>
+ <th><strong>Data Tags</strong></th>
+ <th><strong>Other Tags</strong></th>
</tr>
+ </thead>
+ <tbody>
<tr>
- <td> </td>
<td><a href="if-tag">if</a></td>
- <td> </td>
<td><a href="a-tag">a</a></td>
- <td> </td>
- <td><a href="script-tag">script</a></td>
+ <td><a href="compress-tag">compress</a></td>
</tr>
<tr>
- <td> </td>
<td><a href="elseif-tag">elseif</a></td>
- <td> </td>
<td><a href="action-tag">action</a></td>
- <td> </td>
- <td><a href="link-tag">link</a></td>
+ <td><a href="script-tag">script</a></td>
</tr>
<tr>
- <td> </td>
<td><a href="else-tag">else</a></td>
- <td> </td>
<td><a href="bean-tag">bean</a></td>
- <td> </td>
- <td> </td>
+ <td><a href="link-tag">link</a></td>
</tr>
<tr>
- <td> </td>
<td><a href="append-tag">append</a></td>
- <td> </td>
<td><a href="date-tag">date</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="generator-tag">generator</a></td>
- <td> </td>
<td><a href="debug-tag">debug</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="iterator-tag">iterator</a></td>
- <td> </td>
<td><a href="i18n-tag">i18n</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="merge-tag">merge</a></td>
- <td> </td>
<td><a href="include-tag">include</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="sort-tag">sort</a></td>
- <td> </td>
<td><a href="param-tag">param</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="subset-tag">subset</a></td>
- <td> </td>
<td><a href="property-tag">property</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
- <td> </td>
<td> </td>
<td><a href="push-tag">push</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
- <td> </td>
<td> </td>
<td><a href="set-tag">set</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
- <td> </td>
<td> </td>
<td><a href="text-tag">text</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
- <td> </td>
<td> </td>
<td><a href="url-tag">url</a></td>
<td> </td>
- <td> </td>
</tr>
</tbody>
</table>
@@ -297,144 +257,100 @@ or action executions.</p>
<p>Struts UI Tags display data in rich and reusable HTML.</p>
<table>
- <tbody>
+ <thead>
<tr>
- <td><strong>Form Tags</strong></td>
- <td> </td>
- <td><strong>Non-Form UI Tags</strong></td>
- <td> </td>
+ <th><strong>Form Tags</strong></th>
+ <th><strong>Non-Form UI Tags</strong></th>
</tr>
+ </thead>
+ <tbody>
<tr>
- <td> </td>
<td><a href="checkbox-tag">checkbox</a></td>
- <td> </td>
<td><a href="actionerror-tag">actionerror</a></td>
</tr>
<tr>
- <td> </td>
<td><a href="checkboxlist-tag">checkboxlist</a></td>
- <td> </td>
<td><a href="actionmessage-tag">actionmessage</a></td>
</tr>
<tr>
- <td> </td>
<td><a href="combobox-tag">combobox</a></td>
- <td> </td>
<td><a href="component-tag">component</a></td>
</tr>
<tr>
- <td> </td>
<td><a href="datetextfield-tag">datetextfield</a></td>
- <td> </td>
<td><a href="fielderror-tag">fielderror</a></td>
</tr>
<tr>
- <td> </td>
<td><a href="doubleselect-tag">doubleselect</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="head-tag">head</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="file-tag">file</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="form-tag">form</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="hidden-tag">hidden</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="inputtransferselect-tag">inputtransferselect</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="label-tag">label</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="optiontransferselect-tag">optiontransferselect</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="optgroup-tag">optgroup</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="password-tag">password</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="radio-tag">radio</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="reset-tag">reset</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="select-tag">select</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="submit-tag">submit</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="textarea-tag">textarea</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="textfield-tag">textfield</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="token-tag">token</a></td>
<td> </td>
- <td> </td>
</tr>
<tr>
- <td> </td>
<td><a href="updownselect-tag">updownselect</a></td>
<td> </td>
- <td> </td>
</tr>
</tbody>
</table>
diff --git a/output/tag-developers/xhtml-theme.html
b/output/tag-developers/xhtml-theme.html
index 230cccaa1..e6ca4c05b 100644
--- a/output/tag-developers/xhtml-theme.html
+++ b/output/tag-developers/xhtml-theme.html
@@ -238,12 +238,12 @@ the <a href="ajax-theme">ajax theme</a>) contents:</p>
*/
-->
<#include
"/${attributes.templateDir}/${attributes.expandTheme}/controlheader-core.ftl"
/>
- <td
- <#if attributes.align?? >
- class="align-${attributes.align}"
- <#else >
- class="tdInput"
- </#if>
+ <td<#rt/>
+<#if attributes.align?? >
+ class="align-${attributes.align}"<#rt/>
+<#else >
+ class="tdInput"<#rt/>
+</#if>
><#t/></code></pre></figure>
<figure class="highlight"><pre><code class="language-freemarker"
data-lang="freemarker"><#--