Overview: Removed or deprecated methods and their replacements
When Twig's autoescape functionality was enabled in Drupal 8 core, the SafeMarkup class was added in order to integrate Drupal core's own filtering and escaping APIs with Twig's. Following extensive critical work on Drupal 8's sanitization APIs, most of the public API for the SafeMarkup class has been removed. Replacements for the removed methods are listed below.
| Deprecated method | Replacement(s) |
|---|---|
|
SafeMarkup::checkPlain()
|
|
| SafeMarkup::format() | SafeMarkup::format() returns a FormattableMarkup object instead of a string |
| SafeMarkup::isSafe() |
Use $variable instanceof \Drupal\Component\Render\MarkupInterface instead.
|
| Removed method | Replacement(s) |
|---|---|
|
SafeMarkup::escape()
|
Same as for |
|
SafeMarkup::set()
|
See Twig autoescape enabled and text sanitization APIs updated |
|
SafeMarkup::setMultiple()
|
See Twig autoescape enabled and text sanitization APIs updated |
|
SafeMarkup::getAll()
|
No direct replacement. There is no global list of safe strings, but any mixed collection of strings and |
|
SafeMarkup::replace()
|
No direct replacement. Code that needs to do something like this must handle the problem itself. See views_pre_render_views_form_views_form(). (Note however, that uses the deprecated SafeMarkup::isSafe.) |
|
SafeMarkup::xssFilter() and SafeMarkup::xssFilterAdmin()
|
|
|
SafeMarkup::placeholder()
|
No direct replacement. Use SafeMarkup::format() with |
Escaping markup (or, how to check_plain() in Drupal 8) (#)
The most direct replacement for SafeMarkup::checkPlain($text) is return new HtmlEscapedText($text). But, better best practices are explained below. When replacing usages of SafeMarkup::checkPlain(), care needs to be taken to identify where the escaped string is being used. There are four possibilities: a Twig template, a render array, or some other type of response (most often non-HTML).
-
Twig
If the string is used in a Twig template, rely on Twig's auto-escaping feature. Simply remove the call to
SafeMarkup::checkPlain(). For example, mostSafeMarkup::checkPlain()calls in template preprocess functions can be removed. Another common case is the construction of a render array that uses a Twig template. For example, data that is being themed using an item list or table does not need to be escaped as Twig will do this for you. If text that has already been escaped usingHtml::escape()ends up in a Twig template variable, it will be double-escaped. -
Render array #plain_text element
Render arrays can automatically escape text using the #plain_text key:
$escaped_render_array = ['#plain_text' => 'foo <strong>bar</strong>'];See Support for #plain_text has been added for the render arrays.
-
Html::escape() and SafeMarkup::format() for render arrays and HTML output
Alternatively you might be joining escaped markup with markup you do not want escaped. Html::escape() or SafeMarkup::format() with a '@placeholder' can be used in places where explicit escaping is needed:
$escaped = t('Some text') . '<span> foo' . Html::escape('<strong>bar</strong>') . '</span>'; // or: $escaped = SafeMarkup::format('foo <span>@input</span>', ['@input' => '<strong>bar</strong>']); // Using #markup will automatically XSS admin filter the markup but it won't affect the previously escaped content. $render_array = ['#markup' => $escaped];Just like
SafeMarkup::checkPlain()used to, all of these will escape the input string and turn it into: "<strong>bar</strong>" (unescaped this would have been "<strong>bar</strong>"). -
Non-HTML responses
Output that bypasses the theme system (for example, a JSON response) must perform its own sanitization. In these cases, Twig's autoescape functionality will never be invoked.
One strategy is to use
Html::escape()to prepare output for a property value within a JSON response that JavaScript will insert into the DOM as HTML. For example, an autocomplete response should escape its output:foreach ($entities as $entity) { $matches[$entity->id()] = Html::escape($entity->label()); } } return new JsonResponse($matches);Alternatively, it is possible to escape output in JavaScript instead. This was the approach taken on #2503963: XSS in Quick Edit: entity title is not safely encoded.
Drupal.checkPlain()is defined in core/misc/drupal.js
and is used in /core/modules/quickedit/js/theme.js for exampleDrupal.theme.quickeditEntityToolbarLabel = function (settings) { return '<span class="field">' + Drupal.checkPlain(settings.fieldLabel) + '</span>' + Drupal.checkPlain(settings.entityLabel); };
Related change records
See Twig autoescape enabled and text sanitization APIs updated for a full list of related change records.