This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts-site.git
The following commit(s) were added to refs/heads/main by this push:
new 87a89f113 WW-5256 Add documentation for compress tag and FreeMarker
whitespace stripping (#286)
87a89f113 is described below
commit 87a89f113355d8d811adcede86f7252d8e8f842c
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sat Dec 6 15:30:16 2025 +0100
WW-5256 Add documentation for compress tag and FreeMarker whitespace
stripping (#286)
* docs: WW-5256 add documentation for compress tag and freemarker
whitespace stripping
Added comprehensive documentation for new features in Struts 7.2.0:
- New compress tag documentation (compress-tag.md)
- Updated tag reference with compress tag
- Added FreeMarker whitespace stripping section to freemarker-support.md
- Added performance tuning sections for both features
- Updated constant configuration examples
Related to apache/struts#1418
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
* docs: WW-5256 update constants to struts.tag.compress namespace
Updated all compress tag configuration constants to follow the struts.tag.*
namespace pattern as per apache/struts#1446:
- struts.compress.enabled → struts.tag.compress.enabled
- struts.compress.maxSize → struts.tag.compress.maxSize
- struts.compress.log.maxLength → struts.tag.compress.log.maxLength
This aligns with established Struts patterns for tag-specific configuration.
Related to apache/struts#1446
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
---------
Co-authored-by: Claude Sonnet 4.5 <[email protected]>
---
.claude/settings.json | 20 ++++
source/core-developers/constant-configuration.md | 32 ++++--
source/core-developers/freemarker-support.md | 60 +++++++++---
source/core-developers/performance-tuning.md | 119 ++++++++++++++++++-----
source/tag-developers/compress-tag.md | 83 ++++++++++++++++
source/tag-developers/tag-reference.md | 84 ++++++++--------
6 files changed, 308 insertions(+), 90 deletions(-)
diff --git a/.claude/settings.json b/.claude/settings.json
new file mode 100644
index 000000000..a22e52465
--- /dev/null
+++ b/.claude/settings.json
@@ -0,0 +1,20 @@
+{
+ "permissions": {
+ "allow": [
+ "mcp__jetbrains",
+ "mcp__perplexity",
+ "WebFetch(domain:lists.apache.org)",
+ "WebFetch(domain:github.com)",
+ "WebFetch(domain:struts.apache.org)",
+ "WebFetch(domain:raw.githubusercontent.com)",
+ "Bash(git checkout:*)",
+ "Bash(git add:*)",
+ "Bash(git commit:*)",
+ "Bash(git push:*)",
+ "Bash(gh pr create:*)",
+ "Bash(gh pr view:*)"
+ ],
+ "deny": [],
+ "ask": []
+ }
+}
diff --git a/source/core-developers/constant-configuration.md
b/source/core-developers/constant-configuration.md
index f8dec3f57..e81c8e526 100644
--- a/source/core-developers/constant-configuration.md
+++ b/source/core-developers/constant-configuration.md
@@ -8,12 +8,12 @@ parent:
# Constant Configuration
-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
+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
[Bean](bean-configuration) implementation, among multiple implementations of a
given type, should be chosen.
-Constants can be declared in multiple files. By default, constants are
searched for in the following order, allowing
+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:
1. [struts-default.xml](struts-default-xml)
@@ -29,10 +29,10 @@ for subsequent files to override previous ones:
In the various XML variants, the constant element has two required attributes:
`name` and `value`.
-|Attribute|Required|Description|
-|---------|--------|-----------|
-|name|**yes**|the name of the constant|
-|value|**yes**|the value of the constant|
+| Attribute | Required | Description |
+|-----------|----------|---------------------------|
+| name | **yes** | the name of the constant |
+| value | **yes** | the value of the constant |
In the [default.properties](default-properties) file, each entry is treated as
a constant.
@@ -40,7 +40,7 @@ In the [web.xml](web-xml) file, any FilterDispatcher
initialization parameters a
### Value substitution
-Since Apache Struts 2.5.6 it is possible to use value substitution when
defining `constant`s in `struts.xml` file.
+Since Apache Struts 2.5.6 it is possible to use value substitution when
defining `constant`s in `struts.xml` file.
You can also define a default value if given System property or ENV variable
is missing, see example below:
```xml
@@ -72,6 +72,20 @@ Note: substitution is limited to System properties and ENV
variables and works o
struts.devMode = true
```
+**Constant Example (Performance - Struts 7.2.0+)**
+
+```xml
+<struts>
+ <!-- Enable FreeMarker whitespace stripping (default: true, auto-disabled in
devMode) -->
+ <constant name="struts.freemarker.whitespaceStripping" value="true" />
+
+ <!-- Control HTML compression globally -->
+ <constant name="struts.tag.compress.enabled" value="true" />
+ <constant name="struts.tag.compress.maxSize" value="10485760" />
+ <constant name="struts.tag.compress.log.maxLength" value="200" />
+</struts>
+```
+
**Constant Example (web.xml)**
```xml
diff --git a/source/core-developers/freemarker-support.md
b/source/core-developers/freemarker-support.md
index f3ccf2598..151183ad0 100644
--- a/source/core-developers/freemarker-support.md
+++ b/source/core-developers/freemarker-support.md
@@ -7,12 +7,17 @@ parent:
---
# Freemarker Support
+{:.no_toc}
+
+* Will be replaced with the ToC, excluding a header
+{:toc}
Freemarker views can be rendered using a result type `freemarker`.
## Configure your action to use the freemarker result type
-The `freemarker` result type is defined in `struts-default.xml`, so normally
you just include it, and define your results to use `type="freemarker"`.
+The `freemarker` result type is defined in `struts-default.xml`, so normally
you just include it, and define your
+results to use `type="freemarker"`.
```xml
<include file="struts-default.xml"/>
@@ -48,7 +53,7 @@ The following variables exist in the FreeMarker views:
- `res` - the current `HttpServletResponse`
- `stack` - the current `OgnlValueStack`
- `ognl` - the `OgnlTool` instance
- - This class contains useful methods to execute OGNL expressions against
arbitary objects, and a method to generate a select list using
+ - This class contains useful methods to execute OGNL expressions against
arbitrary objects, and a method to generate a select list using
the `<s:select/>` pattern. (i.e. taking the name of the list property, a
listKey and listValue)
- `struts` - an instance of `StrutsBeanWrapper`
- `action` - the current Struts action
@@ -56,8 +61,8 @@ The following variables exist in the FreeMarker views:
## FreeMarker configuration with recent releases
-To configure the freemarker engine that Struts uses, just add a file
`freemarker.properties` to the classpath. The supported properties
-are those that the Freemarker Configuration object expects - see the
[Freemarker
documentation](https://freemarker.apache.org/docs/api/freemarker/template/Configuration.html#setSetting-java.lang.String-java.lang.String-)
+To configure the freemarker engine that Struts uses, just add a file
`freemarker.properties` to the classpath.
+The supported properties are those that the Freemarker Configuration object
expects - see the [Freemarker
documentation](https://freemarker.apache.org/docs/api/freemarker/template/Configuration.html#setSetting-java.lang.String-java.lang.String-)
for these.
```
@@ -66,13 +71,45 @@ template_update_delay=5
locale=no_NO
```
+## FreeMarker Whitespace Stripping
+
+**Available since Struts 7.2.0**
+
+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.
+
+This feature is controlled by the `struts.freemarker.whitespaceStripping`
constant:
+
+```xml
+<constant name="struts.freemarker.whitespaceStripping" value="true" />
+```
+
+**Default behavior:**
+
+- **Enabled by default** (`true`)
+- **Automatically disabled** when `struts.devMode` is enabled to make
debugging easier
+- Works transparently with existing templates
+
+**Benefits:**
+
+- Reduces HTML output size by removing template indentation
+- Improves page load times and reduces bandwidth usage
+- No changes needed to existing FreeMarker templates
+- Automatically disabled in development mode for easier debugging
+
+**See also:**
+
+- [Performance Tuning - FreeMarker Whitespace
Stripping](performance-tuning#enable-freemarker-whitespace-stripping)
+- [Compress Tag](../tag-developers/compress-tag) for runtime HTML compression
+
## Using struts UI tags - or any JSP Tag Library
Freemarker has builtin support for using any JSP taglib. You can use JSP
taglibs in FreeMarker even if
- - your servlet container has no support for JSP, or
- - 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.
+- your servlet container has no support for JSP, or
+- 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.
```ftl
<#assign s=JspTaglibs["/WEB-INF/struts.tld"] />
@@ -85,28 +122,25 @@ Freemarker has builtin support for using any JSP taglib.
You can use JSP taglibs
```
-*NOTE*: numeric properties for tags MUST be numbers, not strings. as in the
rows and cols properties above. if you use `cols="40"` you will
-receive an exception. Other than that, the freemarker tag container behaves as
you would expect.
+*NOTE*: numeric properties for tags MUST be numbers, not strings. as in the
rows and cols properties above. If you use
+`cols="40"` you will receive an exception. Other than that, the freemarker tag
container behaves as you would expect.
## Dynamic attributes support
You can specify dynamic attributes with Struts 2 tags like this:
-
```ftl
<@s.textfield name="test"
dynamicAttributes={"placeholder":"input","foo":"bar"}/>
```
or like this:
-
```ftl
<@s.textfield name="test" placeholder="input" foo="bar"/>
```
and for both case, it will be parsed into:
-
```html
<input type="text" name="test" value="" id="test" placeholder="input"
foo="bar"/>
@@ -114,14 +148,12 @@ and for both case, it will be parsed into:
You can also use OGNL expressions with dynamic tags like below:
-
```ftl
<@s.textfield name="test" placeholder="input" foo="checked: %{bar}"/>
```
When using attributes with hyphens, use the below syntax (you can also leave
the single quotes from false if you want)
-
```ftl
<@s.form dynamicAttributes={'data-ajax':'false'}>
...
diff --git a/source/core-developers/performance-tuning.md
b/source/core-developers/performance-tuning.md
index 5d729b473..bb7c1dfec 100644
--- a/source/core-developers/performance-tuning.md
+++ b/source/core-developers/performance-tuning.md
@@ -7,33 +7,35 @@ parent:
---
# Performance Tuning
+
{:.no_toc}
* Will be replaced with the ToC, excluding a header
-{:toc}
+ {:toc}
The following are some tips and tricks to squeeze the most performance out of
Struts 2.
> 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 **much** better performance. See the following JIRA issue for
more information:
+> and provides **much** better performance. See the following JIRA issue for
more information:
> [WW-3580](https://issues.apache.org/jira/browse/WW-3580)
## Turn off logging and devMode
-The [devMode](development-mode) 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.
+The [devMode](development-mode) 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.
## Use the Java Templates
-If you use the simple theme, and do not overwrite any of the FreeMarker
templates, consider using the [java
templates](../plugins/javatemplates-plugin/),
+If you use the simple theme, and do not overwrite any of the FreeMarker
templates, consider using
+the [java templates](../plugins/javatemplates-plugin/),
which provide a drop in replacement for most of the tags, and are a lot faster
than the regular tags.
## Do not use interceptors you do not need
-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 `I18nInterceptor`
interceptor if you don't need it, as it can cause
+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 `I18nInterceptor`
interceptor if you don't need it, as it can cause
a session to be created.
## Use the correct HTTP headers (Cache-Control & Expires)
@@ -42,9 +44,10 @@ When returning HTML views, make sure to add the correct
headers so browsers know
## Copy the static content from the Struts 2 jar when using the Ajax theme
(Dojo) or the Calendar tag
-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 (`/static`).
-Although Struts 2 can handle these requests, an application/servlet container
is not optimized for these kind of requests.
+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 (`/static`).
+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, ..).
## Create a freemarker.properties file in your WEB-INF/classes directory
@@ -55,8 +58,9 @@ Create the freemarker.properties file and add the following
setting (or whatever
template_update_delay=60000
```
-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.
+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.
You can also use `struts.freemarker.templatesCache.updateDelay` constant to
achieve the same effect.
@@ -65,33 +69,96 @@ See also: [Freemarker configuration
properties](https://freemarker.apache.org/do
## Enable Freemarker template caching
-> Note: support for this options has been removed in Struts. See the
[Cache](../tag-developers/freemarker#cache) section of the FreeMarker page.
+> Note: support for this options has been removed in Struts. See the
[Cache](../tag-developers/freemarker#cache) section
+> of the FreeMarker page.
-As of Struts 2.0.10, setting the property `struts.freemarker.templatesCache`
to true will enable the Struts internal
+As of Struts 2.0.10, setting the property `struts.freemarker.templatesCache`
to true will enable the Struts internal
caching of Freemarker templates. This property is set to false by default.
-In Struts versions prior to 2.0.10, you had to copy the `/template` directory
from the Struts 2 jar in your `WEB_APP`
+In Struts versions prior to 2.0.10, you had to copy the `/template` directory
from the Struts 2 jar in your `WEB_APP`
root to utilize Freemarker's built in caching mechanism in order to achieve
similar results.
-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
+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.
+## Enable FreeMarker Whitespace Stripping
+
+**Available since Struts 7.2.0**
+
+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.
+
+This feature is enabled by default and automatically disabled when `devMode`
is active to make debugging easier.
+
+**Configuration:**
+
+```xml
+
+<constant name="struts.freemarker.whitespaceStripping" value="true"/>
+```
+
+Or in `struts.properties`:
+
+```properties
+struts.freemarker.whitespaceStripping=true
+```
+
+**Default value:** `true` (automatically disabled in devMode)
+
+## Use the Compress Tag for HTML Output Optimization
+
+**Available since Struts 7.2.0**
+
+The `<s:compress>` 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.
+
+**Usage:**
+
+```jsp
+<s:compress>
+ <div>
+ <p>Content here will be compressed</p>
+ </div>
+</s:compress>
+```
+
+**Configuration:**
+
+Control compression globally:
+
+```xml
+
+<constant name="struts.tag.compress.enabled" value="true"/>
+<constant name="struts.tag.compress.maxSize" value="10485760"/>
+```
+
+The compress tag is enabled by default and includes security protections:
+
+- Maximum content size limit (10MB default) prevents DoS attacks
+- Body content truncation in logs (200 chars default) prevents sensitive data
exposure
+- ReDoS safeguards for regex operations
+
+For development debugging, compression is automatically disabled in devMode
unless you use the `force="true"` attribute.
+
+**See also:** [Compress Tag](../tag-developers/compress-tag)
+
## When overriding a theme, copy all necessary templates to the theme directory
-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,
+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.
## Do not create sessions unless you need them
-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
**always** be created.
+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
**always** be created.
The I18nInterceptor interceptor can create sessions, so make sure you remove
it, if you don't need it.
## When using Freemarker, try to use the Freemarker equivalent rather than
using the JSP tags
-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
+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. `<s:property value="foo"/>` should be replaced by `${foo}`).
diff --git a/source/tag-developers/compress-tag.md
b/source/tag-developers/compress-tag.md
new file mode 100644
index 000000000..a0a2cdca3
--- /dev/null
+++ b/source/tag-developers/compress-tag.md
@@ -0,0 +1,83 @@
+---
+layout: default
+title: compress tag
+parent:
+ title: Tag Reference
+ url: tag-reference
+---
+
+# compress
+
+Please make sure you have read the [Tag Syntax](tag-syntax) document and
understand how tag attribute syntax works.
+
+## Description
+
+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.
+
+The compress tag can be controlled globally via the
`struts.tag.compress.enabled` configuration property and is
+automatically disabled in development mode for easier debugging.
+
+{%
+remote_file_content
https://raw.githubusercontent.com/apache/struts/main/core/src/site/resources/tags/compress-description.html
%}
+
+## Attributes
+
+{%
+remote_file_content
https://raw.githubusercontent.com/apache/struts/main/core/src/site/resources/tags/compress-attributes.html
%}
+
+## Security Features
+
+- Body content truncation in logs prevents sensitive data exposure
+- Maximum size limits (10MB default) prevent DoS attacks via large inputs
+- Regex operations include ReDoS safeguards with 50MB hard limit
+
+## Examples
+
+**Basic usage:**
+
+```jsp
+<s:compress>
+ <div>
+ <p>This HTML will be compressed</p>
+ <span>Whitespace between tags will be removed</span>
+ </div>
+</s:compress>
+```
+
+**Force compression in development mode:**
+
+```jsp
+<s:compress force="true">
+ <div>
+ <p>This will be compressed even in devMode</p>
+ </div>
+</s:compress>
+```
+
+**Configuration:**
+
+Control compression globally in `struts.xml`:
+
+```xml
+
+<constant name="struts.tag.compress.enabled" value="true"/>
+<constant name="struts.tag.compress.maxSize" value="10485760"/>
+```
+
+Or in `struts.properties`:
+
+```properties
+struts.tag.compress.enabled=true
+struts.tag.compress.maxSize=10485760
+```
+
+## Related Configuration
+
+- `struts.tag.compress.enabled` - Controls whether compression is enabled
globally (default: true)
+- `struts.tag.compress.maxSize` - Maximum size in bytes of content that can be
compressed (default: 10485760 = 10MB)
+- `struts.tag.compress.log.maxLength` - Maximum length of body content in log
messages (default: 200)
+
+## Since
+
+Available since Struts 7.2.0
diff --git a/source/tag-developers/tag-reference.md
b/source/tag-developers/tag-reference.md
index da1f1628d..32997e35c 100644
--- a/source/tag-developers/tag-reference.md
+++ b/source/tag-developers/tag-reference.md
@@ -6,15 +6,15 @@ parent:
url: index
---
-# Tag Reference
+# Tag Reference
{:.no_toc}
* Will be replaced with the ToC, excluding a header
{:toc}
-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 _Localization_
, JavaBeans, and including additional URLs
-or action executions.
+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
_Localization_ , JavaBeans, and including
+additional URLs or action executions.
- Control Tags provide control flow, such as `if`, `else`, and `iterator`
- Data Tags allow for data manipulation or creation, such as `bean`, `push`,
and `i18n`
@@ -25,45 +25,47 @@ or action executions.
Struts Generic Tags control the execution flow as pages render.
-|**Control Tags**| |**Data Tags**| |**Other Tags** |
-| |[if](if-tag) | |[a](a-tag) | |
[script](script-tag) |
-| |[elseif](elseif-tag) | |[action](action-tag) | | [link](link-tag) |
-| |[else](else-tag) | |[bean](bean-tag) | | |
-| |[append](append-tag) | |[date](date-tag) | | |
-| |[generator](generator-tag)| |[debug](debug-tag) | | |
-| |[iterator](iterator-tag) | |[i18n](i18n-tag) | | |
-| |[merge](merge-tag) | |[include](include-tag) | | |
-| |[sort](sort-tag) | |[param](param-tag) | | |
-| |[subset](subset-tag) | |[property](property-tag)| | |
-| | | |[push](push-tag) | | |
-| | | |[set](set-tag) | | |
-| | | |[text](text-tag) | | |
-| | | |[url](url-tag) | | |
+| **Control Tags** | **Data Tags** | **Other Tags**
|
+|----------------------------|--------------------------|--------------------------|
+| [if](if-tag) | [a](a-tag) |
[compress](compress-tag) |
+| [elseif](elseif-tag) | [action](action-tag) | [script](script-tag)
|
+| [else](else-tag) | [bean](bean-tag) | [link](link-tag)
|
+| [append](append-tag) | [date](date-tag) |
|
+| [generator](generator-tag) | [debug](debug-tag) |
|
+| [iterator](iterator-tag) | [i18n](i18n-tag) |
|
+| [merge](merge-tag) | [include](include-tag) |
|
+| [sort](sort-tag) | [param](param-tag) |
|
+| [subset](subset-tag) | [property](property-tag) |
|
+| | [push](push-tag) |
|
+| | [set](set-tag) |
|
+| | [text](text-tag) |
|
+| | [url](url-tag) |
|
## UI Tag Reference
Struts UI Tags display data in rich and reusable HTML.
-|**Form Tags**|
|**Non-Form UI Tags** |
-| |[checkbox](checkbox-tag) |
|[actionerror](actionerror-tag) |
-| |[checkboxlist](checkboxlist-tag) |
|[actionmessage](actionmessage-tag)|
-| |[combobox](combobox-tag) |
|[component](component-tag) |
-| |[datetextfield](datetextfield-tag) |
|[fielderror](fielderror-tag) |
-| |[doubleselect](doubleselect-tag) |
| |
-| |[head](head-tag) |
| |
-| |[file](file-tag) |
| |
-| |[form](form-tag) |
| |
-| |[hidden](hidden-tag) |
| |
-| |[inputtransferselect](inputtransferselect-tag) |
| |
-| |[label](label-tag) |
| |
-| |[optiontransferselect](optiontransferselect-tag)|
| |
-| |[optgroup](optgroup-tag) |
| |
-| |[password](password-tag) |
| |
-| |[radio](radio-tag) |
| |
-| |[reset](reset-tag) |
| |
-| |[select](select-tag) |
| |
-| |[submit](submit-tag) |
| |
-| |[textarea](textarea-tag) |
| |
-| |[textfield](textfield-tag) |
| |
-| |[token](token-tag) |
| |
-| |[updownselect](updownselect-tag) |
| |
+| **Form Tags** | **Non-Form UI Tags**
|
+|--------------------------------------------------|------------------------------------|
+| [checkbox](checkbox-tag) |
[actionerror](actionerror-tag) |
+| [checkboxlist](checkboxlist-tag) |
[actionmessage](actionmessage-tag) |
+| [combobox](combobox-tag) |
[component](component-tag) |
+| [datetextfield](datetextfield-tag) |
[fielderror](fielderror-tag) |
+| [doubleselect](doubleselect-tag) |
|
+| [head](head-tag) |
|
+| [file](file-tag) |
|
+| [form](form-tag) |
|
+| [hidden](hidden-tag) |
|
+| [inputtransferselect](inputtransferselect-tag) |
|
+| [label](label-tag) |
|
+| [optiontransferselect](optiontransferselect-tag) |
|
+| [optgroup](optgroup-tag) |
|
+| [password](password-tag) |
|
+| [radio](radio-tag) |
|
+| [reset](reset-tag) |
|
+| [select](select-tag) |
|
+| [submit](submit-tag) |
|
+| [textarea](textarea-tag) |
|
+| [textfield](textfield-tag) |
|
+| [token](token-tag) |
|
+| [updownselect](updownselect-tag) |
|