[wp-trac] [WordPress Trac] #60229: HTML API: Introduce HTML Templating
WordPress Trac
noreply at wordpress.org
Fri Nov 21 21:48:10 UTC 2025
#60229: HTML API: Introduce HTML Templating
-------------------------------------------------+-------------------------
Reporter: dmsnell | Owner: (none)
Type: enhancement | Status: new
Priority: normal | Milestone: 7.0
Component: HTML API | Version: 6.5
Severity: normal | Resolution:
Keywords: has-patch has-unit-tests needs-dev- | Focuses:
note dev-feedback |
-------------------------------------------------+-------------------------
Description changed by westonruter:
Old description:
> WordPress relies on developers remembering to perform proper escaping
> when building HTML strings. There's no mechanism to ensure that output
> HTML is safe. This patch introduces `WP_HTML_Template::render( $template,
> $args )` to do just that.
>
> {{{#!php
> <?php
> echo WP_HTML_Template::render(
> <<<HTML
> <a href="</%url>">
> <img src="</%url>">
> </%url>
> </a>
> HTML,
> array( 'url' =>
> 'https://s.wp.com/i/atat.png?w=640&h=480&alt="atat>atst"' ),
> );
> }}}
>
> outputs
>
> {{{
> <a
> href="https://s.wp.com/i/atat.png?w=640&h=480&alt="atat>atst"">
> <img
> src="https://s.wp.com/i/atat.png?w=640&h=480&alt="atat>atst"">
> https://s.wp.com/i/atat.png?w=640&h=480&alt="atat>atst"
> </a>
> }}}
>
> This proposed templating syntax uses closing tags containing invalid tag
> names, so-called "funky comments," as placeholders, because they are
> converted to HTML comments in the DOM and because there is near universal
> existing support for them in all browsers, and because the syntax cannot
> be nested. The `%` at the front indicates that the value for the
> placeholder should come from the args array with a key named according to
> what follows the `%`.
>
> This proposal does not yet consider nested HTML, or "raw" HTML. It
> currently escapes all content. It would be great if the templating engine
> can properly and safely handle HTML passed into it without risking
> unintentional exposure, but there must also be some way to communicate
> that a value inside is already escaped //and that its safety is
> maintained//.
>
> By relying on the HTML API, this templating only supports replacement of
> values //inside// HTML attributes or in plaintext (`#text`) nodes. It's
> not possible to inject HTML tags (unless nested support can be safely
> added), comments, or other HTML syntax.
>
> == Related work
>
> - #50867 An API which encourages automatic escaping of HTML
> - PR#5884 Introduce WP_HTML::tag() for safely creating HTML
New description:
WordPress relies on developers remembering to perform proper escaping when
building HTML strings. There's no mechanism to ensure that output HTML is
safe. This patch introduces `WP_HTML_Template::render( $template, $args )`
to do just that.
{{{#!php
<?php
echo WP_HTML_Template::render(
<<<HTML
<a href="</%url>">
<img src="</%url>">
</%url>
</a>
HTML,
array( 'url' =>
'https://s.wp.com/i/atat.png?w=640&h=480&alt="atat>atst"' ),
);
}}}
outputs
{{{
<a
href="https://s.wp.com/i/atat.png?w=640&h=480&alt="atat>atst"">
<img
src="https://s.wp.com/i/atat.png?w=640&h=480&alt="atat>atst"">
https://s.wp.com/i/atat.png?w=640&h=480&alt="atat>atst"
</a>
}}}
This proposed templating syntax uses closing tags containing invalid tag
names, so-called "funky comments," as placeholders, because they are
converted to HTML comments in the DOM and because there is near universal
existing support for them in all browsers, and because the syntax cannot
be nested. The `%` at the front indicates that the value for the
placeholder should come from the args array with a key named according to
what follows the `%`.
This proposal does not yet consider nested HTML, or "raw" HTML. It
currently escapes all content. It would be great if the templating engine
can properly and safely handle HTML passed into it without risking
unintentional exposure, but there must also be some way to communicate
that a value inside is already escaped //and that its safety is
maintained//.
By relying on the HTML API, this templating only supports replacement of
values //inside// HTML attributes or in plaintext (`#text`) nodes. It's
not possible to inject HTML tags (unless nested support can be safely
added), comments, or other HTML syntax.
== Related work
- #50867 An API which encourages automatic escaping of HTML
- [https://github.com/WordPress/wordpress-develop/pull/5884 PR #5884]
Introduce WP_HTML::tag() for safely creating HTML
--
--
Ticket URL: <https://core.trac.wordpress.org/ticket/60229#comment:20>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list