Skip to content

WICKET-7196 Let a wicket:label tag turn off escaping - #1552

Merged
papegaaij merged 1 commit into
masterfrom
WICKET-7196
Aug 23, 2026
Merged

WICKET-7196 Let a wicket:label tag turn off escaping#1552
papegaaij merged 1 commit into
masterfrom
WICKET-7196

Conversation

@papegaaij

Copy link
Copy Markdown
Contributor

WICKET-7196

<wicket:label> escapes the label text it takes from a model or from a resource bundle. The flag that decides it is read from the TextLabel the resolver inserts, and that component is never handed to the application, so nothing can clear it. An application whose bundle holds markup, or an entity such as Save &amp; close, has no way back other than moving the content into the tag body.

This adds an escape attribute to the tag:

<label wicket:for="myFormComponent"><wicket:label escape="false"/></label>

It sets escapeModelStrings on the label the resolver creates, so the write site in onComponentTagBody is unchanged and the attribute is the markup spelling of the flag SECURITY.md already describes — clearing it is the application saying the content is markup and taking responsibility for it.

Differences from <wicket:message escape="…">

The polarity is inverted: a message is written as markup by default and escape="true" opts in, while a label is escaped by default and escape="false" opts out.

Because of that, a missing or empty attribute keeps the escaping. <wicket:message> reads the same attribute with IValueMap#getBoolean, which resolves an empty value to false; there false is the default, here it is the opt-out, so an empty value has to keep the escaping rather than quietly drop it. An unrecognised value still raises StringValueConversionException, the way it does on <wicket:message>.

The attribute says nothing about the tag body. That body is markup the label has just rendered itself, nested components and <wicket:message> included, and is written as is either way.

Tests

New AutoLabelEscapeAttributeTest covers escape="false" on all three text sources (label model, default label from the bundle, key attribute), escape="true" still escaping, escape="" still escaping, an unrecognised value failing the render, and the FormComponent's label still holding the raw bundle value so error messages are unaffected.

Full wicket-core-tests suite passes (2392 tests).

🤖 Generated with Claude Code

The label text <wicket:label> takes from a model or from a resource bundle is
escaped where it is written, and the flag that decides it is read from the
TextLabel the resolver inserts. That component is never handed to the
application, so its flag stays at the default and nothing can clear it. An
application whose bundle holds markup, or an entity such as Save &amp; close,
had no way back other than moving the content into the tag body.

The tag now carries the decision. An escape attribute sets escapeModelStrings on
the label the resolver creates, so the write site is unchanged and the attribute
is the markup spelling of the flag the security model already describes: clearing
it is the application saying the content is markup and taking responsibility for
it.

A missing attribute keeps the escaping, and so does an empty one. That differs
from <wicket:message>, which reads the same attribute with IValueMap#getBoolean
and resolves an empty value to false. There false is the default, here it is the
opt-out, so an empty value has to keep the escaping rather than quietly drop it.
An unrecognised value still fails, the way it does on <wicket:message>.

The attribute says nothing about the tag body. That body is markup the label has
just rendered itself, nested components and <wicket:message> included, and is
written as is either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@papegaaij
papegaaij marked this pull request as ready for review August 23, 2026 20:48
@papegaaij
papegaaij merged commit d1bfd0b into master Aug 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant