You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2025/12/06 09:22:53 UTC
(struts-site) branch docs/ww-5256-compress-tag-documentation created (now 0412d2e27)
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a change to branch docs/ww-5256-compress-tag-documentation
in repository https://gitbox.apache.org/repos/asf/struts-site.git
at 0412d2e27 docs: WW-5256 add documentation for compress tag and freemarker whitespace stripping
This branch includes the following new commits:
new 0412d2e27 docs: WW-5256 add documentation for compress tag and freemarker whitespace stripping
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(struts-site) 01/01: docs: WW-5256 add documentation for compress tag and freemarker whitespace stripping
Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch docs/ww-5256-compress-tag-documentation
in repository https://gitbox.apache.org/repos/asf/struts-site.git
commit 0412d2e2715ac926576fbca0b5d0e7182a240eba
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Sat Dec 6 10:22:19 2025 +0100
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 <no...@anthropic.com>
---
.claude/settings.json | 20 ++++
source/core-developers/constant-configuration.md | 32 +++++--
source/core-developers/freemarker-support.md | 60 +++++++++---
source/core-developers/performance-tuning.md | 111 ++++++++++++++++++-----
source/tag-developers/compress-tag.md | 80 ++++++++++++++++
source/tag-developers/tag-reference.md | 84 ++++++++---------
6 files changed, 299 insertions(+), 88 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..ec700fa71 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.compress.enabled" value="true" />
+ <constant name="struts.compress.maxSize" value="10485760" />
+ <constant name="struts.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..7f5365302 100644
--- a/source/core-developers/performance-tuning.md
+++ b/source/core-developers/performance-tuning.md
@@ -15,15 +15,15 @@ parent:
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
@@ -32,8 +32,8 @@ which provide a drop in replacement for most of the tags, and are a lot faster t
## 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 +42,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 +56,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 +67,94 @@ 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.compress.enabled" value="true" />
+<constant name="struts.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..34079d348
--- /dev/null
+++ b/source/tag-developers/compress-tag.md
@@ -0,0 +1,80 @@
+---
+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.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.compress.enabled" value="true" />
+<constant name="struts.compress.maxSize" value="10485760" />
+```
+
+Or in `struts.properties`:
+
+```properties
+struts.compress.enabled=true
+struts.compress.maxSize=10485760
+```
+
+## Related Configuration
+
+- `struts.compress.enabled` - Controls whether compression is enabled globally (default: true)
+- `struts.compress.maxSize` - Maximum size in bytes of content that can be compressed (default: 10485760 = 10MB)
+- `struts.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) | |