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 1abc30338 WW-5640 docs: document WebJars support (Struts 7.3.0) (#315)
1abc30338 is described below

commit 1abc30338b7f06f728a204ec043cbdf6c6bc1fe7
Author: Lukasz Lenart <[email protected]>
AuthorDate: Mon Jul 6 15:34:13 2026 +0200

    WW-5640 docs: document WebJars support (Struts 7.3.0) (#315)
    
    * WW-5640 docs: add webjar tag reference page
    
    Document the new <s:webjar> tag (and <@s.webjar> macro) that resolves
    version-less WebJar resource paths to servable URLs, introduced in
    Struts 7.3.0. Pulls description/attributes from the released source and
    links the Static Content serving pipeline. Lists the tag under Other
    Tags in the tag reference index.
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
    
    * WW-5640 docs: document WebJars support in static content
    
    Add a WebJars support section to the Static Content guide covering the
    new /static/webjars/** serving pipeline, version-less resolution, the
    struts.webjars.enabled and struts.webjars.allowlist constants, the
    fail-closed security constraints, and the WebJarUrlProvider extension
    seam. Introduced in Struts 7.3.0.
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
    
    ---------
    
    Co-authored-by: Claude Opus 4.8 <[email protected]>
---
 source/core-developers/static-content.md | 65 ++++++++++++++++++++++++++++++++
 source/tag-developers/tag-reference.md   |  2 +-
 source/tag-developers/webjar-tag.md      | 51 +++++++++++++++++++++++++
 3 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/source/core-developers/static-content.md 
b/source/core-developers/static-content.md
index 6d132577f..1416472ae 100644
--- a/source/core-developers/static-content.md
+++ b/source/core-developers/static-content.md
@@ -63,6 +63,71 @@ If needed you can change the default path at which static 
content is served. Jus
 
 This value is also used by the Default Content Loader.
 
+## WebJars support
+
+{:.alert .alert-info}
+Available since Struts 7.3.0.
+
+[WebJars](https://www.webjars.org/) package client-side libraries (Bootstrap, 
jQuery, …) as JARs, shipping their assets
+under `META-INF/resources/webjars/<name>/<version>/…`. Instead of vendoring 
these files into your web application and
+re-committing them on every upgrade, you add the WebJar as a regular 
dependency and let Struts resolve and serve it.
+
+Struts serves WebJar assets through the same static content pipeline described 
above, under
+`<staticContentPath>/webjars/**` (by default `/static/webjars/**`). Resolution 
is **version-less**: you reference a
+resource by its logical path and Struts resolves the version present on the 
classpath. For example, a request for:
+
+```
+/static/webjars/bootstrap/css/bootstrap.min.css
+```
+
+is served from 
`META-INF/resources/webjars/bootstrap/5.3.8/css/bootstrap.min.css` (whichever 
version is on the
+classpath). To emit these URLs from a template without hardcoding the version, 
use the
+[webjar tag](../tag-developers/webjar-tag):
+
+```jsp
+<link rel="stylesheet" href="<s:webjar 
path="bootstrap/css/bootstrap.min.css"/>"/>
+```
+
+Struts resolves versions using 
[webjars-locator-lite](https://github.com/webjars/webjars-locator-lite), which 
is bundled
+with `struts2-core`.
+
+### Configuration
+
+| Constant                   | Default | Description                           
                                                            |
+|----------------------------|---------|---------------------------------------------------------------------------------------------------|
+| `struts.webjars.enabled`   | `true`  | Master switch for resolving and 
serving WebJar assets under `<staticContentPath>/webjars/**`.     |
+| `struts.webjars.allowlist` | (empty) | Optional comma-separated allowlist of 
WebJar names. When empty, all WebJars on the classpath are allowed. |
+
+To restrict serving to specific WebJars:
+
+```xml
+<constant name="struts.webjars.allowlist" value="bootstrap,jquery"/>
+```
+
+To disable the feature entirely:
+
+```xml
+<constant name="struts.webjars.enabled" value="false"/>
+```
+
+### Security
+
+Resolution is hard-constrained to the `META-INF/resources/webjars/` root: path 
traversal attempts (`..`, `.`,
+backslashes) are rejected before resolution, the resolved path is re-checked 
for containment, and only paths that the
+locator can resolve to a real WebJar are served. Disabled, unresolved, 
traversal, and allowlist-blocked requests all
+**fail closed** - a `404` when serving and empty output when building URLs.
+
+### Customizing resolution
+
+URL resolution is provided by the 
`org.apache.struts2.webjars.WebJarUrlProvider` container bean (default 
implementation
+`DefaultWebJarUrlProvider`), which exposes `resolveResourcePath(String)` and 
`resolveUrl(String, HttpServletRequest)`.
+Plugins and applications can replace it by declaring their own bean:
+
+```xml
+<bean type="org.apache.struts2.webjars.WebJarUrlProvider" 
class="com.example.MyWebJarUrlProvider" name="myProvider"/>
+<constant name="struts.webjars.urlProvider" value="myProvider"/>
+```
+
 ## Preventing Struts from handling a request
 
 If there is a request that Struts is handling as an action, and you wish to 
make Struts ignore it,
diff --git a/source/tag-developers/tag-reference.md 
b/source/tag-developers/tag-reference.md
index 32997e35c..8c00832ca 100644
--- a/source/tag-developers/tag-reference.md
+++ b/source/tag-developers/tag-reference.md
@@ -30,7 +30,7 @@ Struts Generic Tags control the execution flow as pages 
render.
 | [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)         |                      
    |
+| [append](append-tag)       | [date](date-tag)         | [webjar](webjar-tag) 
    |
 | [generator](generator-tag) | [debug](debug-tag)       |                      
    |
 | [iterator](iterator-tag)   | [i18n](i18n-tag)         |                      
    |
 | [merge](merge-tag)         | [include](include-tag)   |                      
    |
diff --git a/source/tag-developers/webjar-tag.md 
b/source/tag-developers/webjar-tag.md
new file mode 100644
index 000000000..34df2faeb
--- /dev/null
+++ b/source/tag-developers/webjar-tag.md
@@ -0,0 +1,51 @@
+---
+layout: default
+title: webjar tag
+parent:
+  title: Tag Reference
+  url: tag-reference.html
+---
+
+# webjar
+
+{:.alert .alert-info}
+Available since Struts 7.3.0.
+
+Please make sure you have read the [Tag Syntax](tag-syntax) document and 
understand how tag attribute syntax works.
+
+## Description
+
+Resolves a version-less [WebJar](https://www.webjars.org/) resource path to a 
servable URL and writes it to the output
+(or stores it in a variable when `var` is set). For example, 
`bootstrap/css/bootstrap.min.css` is resolved to
+`<ctx>/static/webjars/bootstrap/5.3.8/css/bootstrap.min.css`, so you never 
hardcode the WebJar version in your templates.
+
+The tag emits a plain URL string, so it composes with [script](script-tag), 
[link](link-tag), or a raw `<link>` /
+`<script>` element. See [Static 
Content](../core-developers/static-content#webjars-support) for the serving 
pipeline and
+configuration constants.
+
+{% remote_file_content 
https://raw.githubusercontent.com/apache/struts/main/core/src/site/resources/tags/webjar-description.html
 %}
+
+## Attributes
+
+{% remote_file_content 
https://raw.githubusercontent.com/apache/struts/main/core/src/site/resources/tags/webjar-attributes.html
 %}
+
+## Examples
+
+**Example 1** - reference a WebJar stylesheet:
+
+```jsp
+<link rel="stylesheet" href="<s:webjar 
path="bootstrap/css/bootstrap.min.css"/>"/>
+```
+
+**Example 2** - reference a WebJar script:
+
+```jsp
+<s:webjar var="webjarUrl" path="jquery/jquery.min.js"/>
+<s:script src="%{webjarUrl}"/>
+```
+
+**Example 3** - FreeMarker macro:
+
+```html
+<@s.webjar path="jquery/jquery.min.js"/>
+```

Reply via email to