-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HTML API: Introduce safe HTML templating. #5949
base: trunk
Are you sure you want to change the base?
Conversation
0145fef
to
d275ba3
Compare
d275ba3
to
6d712f1
Compare
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
I was chatting with @nerrad about The example from the dev note illustrates it better: import { __ } from '@wordpress/i18n';
import { createInterpolateElement } from '@wordpress/element';
import { CustomComponent } from '../custom-component.js';
const translatedString = createInterpolateElement(
__( 'This is a <span>string</span> with a <a>link</a> and a self-closing <custom_component/>.' ),
{
span: <span class="special-text" />,
a: <a href="https://make.wordpress.org"/>,
custom_component: <CustomComponent />,
}
); |
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @deeemsad. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. Core Committers: Use this line as a base for the props when committing in SVN:
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
This is an interesting idea @gziolo but my initial reaction is wondering what this provides beyond the proposed templating. It feels different than JavaScript because we're already dealing with actual HTML strings. I'd be curious to see some of the tradeoffs this would bring. In contrast, with the ability to "spread" attributes there's a built-in opportunity to make HTML tags placeholders. |
Right, that's a good point. The same functionality is available but with a different syntax that is, in fact, a bit closer to what people familiar with JSX would expect. |
* | ||
* ### Substitution Placeholders. | ||
* | ||
* - `</%named_arg>` finds `named_arg` in the arguments array, escapes its value if possible, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
%
was chosen as the funky comment character because it's what sprintf
uses?
|
||
// Replace entire attributes if their content is exclusively a placeholder, e.g. `title="</%title>"`. | ||
$full_match = null; | ||
if ( preg_match( '~^</%([^>]+)>$~', $value, $full_match ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
</%>
is a funky comment that could set the ""
(empty string) replacement. Was this a conscious decision to disallow empty string? I think in the HTML funky comment replacement it would handle this case.
I'm asking because I think the placeholder could be zero or more:
if ( preg_match( '~^</%([^>]+)>$~', $value, $full_match ) ) { | |
if ( preg_match( '~^</%([^>]*)>$~', $value, $full_match ) ) { |
The tag and attribute handling should behave consistently on this point, either empty funky comments are allowed or disallowed everywhere.
(There are several more places where this change would be necessary.)
Trac ticket: Core-60229
🚧👷♂️🏗️ This feature is currently being proposed for the WordPress 6.6 release cycle, being pushed back from 6.5 to allow for more time to let the design work proceed.
Todo
Description
Introduces a function providing context-aware auto-escaping HTML templating.
true
to create a boolean attribute orfalse
/null
remove an attribute.Why use these strange funky comments?
A funky comment looks like a tag closer, but the first character of what would be the tag name is a symbol. This was first mentioned in an HTML API progress report: there's a particular kind of HTML syntax error that meets a number of needs we have seen in attempting to replace dynamic content on the server. Namely:
>
, making parsing trivial and reliable.What's in this patch?
This preliminary PR only renders child text and doesn't provide a mechanism for composing rendered HTML or rendering pre-processed HTML. That means everything passed as a child will be escaped to render verbatim in the browser. There are open questions about how best to represent nested HTML, and without a clear answer, this code prefers trust and safety over features.
esc_attr()
andesc_html()
which today are the same thing in WordPress, but which could be greatly expanded to improve the overall escaping situationoutputs
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 %.