[
https://issues.apache.org/jira/browse/WW-5823?focusedWorklogId=1051575&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1051575
]
ASF GitHub Bot logged work on WW-5823:
--------------------------------------
Author: ASF GitHub Bot
Created on: 31/Oct/26 07:49
Start Date: 31/Oct/26 07:49
Worklog Time Spent: 10m
Work Description: lukaszlenart opened a new pull request, #369:
URL: https://github.com/apache/struts-site/pull/369
Relates to [WW-5823](https://issues.apache.org/jira/browse/WW-5823)
The "Dynamic attributes support" section of the FreeMarker support page
shows `foo="checked: %{bar}"` on a textfield and says OGNL expressions work
with dynamic attributes. With the FreeMarker tag syntax the attribute is stored
as given, and the simple theme evaluates it only for `radio` and
`checkboxlist`, once per list item with the item on top of the stack. On every
other tag the text is written out literally.
This replaces the example with FreeMarker interpolation, which resolves
against the value stack in a Struts FreeMarker result, and adds a `radio`
example for the per-item case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Issue Time Tracking
-------------------
Worklog Id: (was: 1051575)
Time Spent: 0.5h (was: 20m)
> Javatemplates plugin renders dynamic attributes differently from the simple
> theme: values are not HTML-escaped and are evaluated a second time
> ----------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: WW-5823
> URL: https://issues.apache.org/jira/browse/WW-5823
> Project: Struts 2
> Issue Type: Bug
> Components: Plugin - Java Templates
> Reporter: Lukasz Lenart
> Assignee: Lukasz Lenart
> Priority: Major
> Fix For: 6.13.0, 7.5.0
>
> Time Spent: 0.5h
> Remaining Estimate: 0h
>
> The javatemplates plugin is documented as a drop-in replacement for the
> simple theme. {{DynamicAttributesHandler.processDynamicAttributes}} differs
> from the FreeMarker {{dynamic-attributes.ftl}} in two ways.
> # Dynamic attribute values are stored with {{Attributes.put}}. Every other
> handler in the plugin goes through {{Attributes.add}} or {{addIfExists}},
> which apply {{escapeHtml4}}, and the FreeMarker template writes the value
> under the configuration's HTML auto-escaping. {{XHTMLTagSerializer.start}}
> then writes the stored value between double quotes as it is.
> # {{UIBean.setDynamicAttributes}} already translates the percent-brace
> expressions for every component that is not lazily evaluated. The handler
> tests the resolved value with {{ComponentUtils.isExpression}} again and calls
> {{findString}} on it, so a value that resolves to text in the percent-brace
> form is evaluated a second time. The FreeMarker template evaluates only when
> {{evaluate_dynamic_attributes}} is set, which {{radiomap.ftl}} and
> {{checkboxlist.ftl}} do because {{Radio}} and {{CheckboxList}} return
> {{lazyEvaluation() == true}} and render their dynamic attributes per list
> item.
> h2. Observed
> With {{struts.ui.templateSuffix=java}} and the {{hint}} property bound from
> the request:
> {code}<s:textfield name="q" data-hint="%{hint}"/>
> hint = a "b" c java: data-hint="a "b" c" ftl: data-hint="a
> "b" c"
> hint = %{1+1} java: data-hint="2" ftl: data-hint="%{1+1}"
> {code}
> The standard attributes of the same tag ({{value}}, {{title}}) render
> identically under both engines. Every tag wired through
> {{DynamicAttributesHandler}} in {{SimpleTheme}} behaves the same way.
> h2. Proposed change
> * Store dynamic attribute values through {{Attributes.add}}, in line with the
> other handlers and the FreeMarker templates.
> * Evaluate a dynamic attribute in the handler only when the component is
> lazily evaluated. {{UIBean}} already knows this through {{lazyEvaluation()}};
> expose it as a component parameter so the plugin can read it. {{Radio}} and
> {{CheckboxList}} keep their per-item evaluation in the handler chain, where
> {{RadioHandler}} and {{CheckboxListHandler}} push each item before calling
> {{start}}.
> h2. Compatibility
> Under the java engine, a dynamic attribute value is now HTML-escaped once, as
> it already is under the FreeMarker themes; a value that already contains
> entities is escaped again, matching the FreeMarker output. A value that
> resolves to text in the percent-brace form is rendered literally instead of
> being evaluated, matching the FreeMarker output. Lazily evaluated components
> are unchanged.
> h2. Tests
> * A dynamic attribute whose resolved value contains a double quote renders
> escaped under the java engine.
> * A dynamic attribute whose resolved value is in the percent-brace form
> renders literally on a non-lazy component.
> * A dynamic attribute on {{Radio}} is still evaluated per item in the handler.
> * The existing dynamic-attribute rendering tests keep passing for every tag
> in {{SimpleTheme}}.
> Reported by Claude and Ada Logics.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)