protected static FormattableMarkup::placeholderFormat($string, array $args)
Replaces placeholders in a string with values.
string $string: A string containing placeholders. The string itself is expected to be safe and correct HTML. Any unsafe content must be in $args and inserted via placeholders.
array $args: An associative array of replacements. Each array key should be the same as a placeholder in $string. The corresponding value should be a string or an object that implements \Drupal\Component\Render\MarkupInterface. The value replaces the placeholder in $string. Sanitization and formatting will be done before replacement. The type of sanitization and formatting depends on the first character of the key:
$this->placeholderFormat('This will force HTML-escaping of the replacement value: @text', ['@text' => (string) $safe_string_interface_object));
Use this placeholder as the default choice for anything displayed on the site, but not within HTML attributes, JavaScript, or CSS. Doing so is a security risk.
$string = "%output_text"; $arguments = ['output_text' => 'text output here.']; $this->placeholderFormat($string, $arguments);
makes the following HTML code:
<em class="placeholder">text output here.em>
As with @variable, do not use this within HTML attributes, JavaScript, or CSS. Doing so is a security risk.
// Secure (with quotes): $this->placeholderFormat('<a href=":url">@variable</a>', [':url' => $url, '@variable' => $variable]); // Insecure (without quotes): $this->placeholderFormat('<a href=:url>@variable</a>', [':url' => $url, '@variable' => $variable]);
When ":variable" comes from arbitrary user input, the result is secure, but not guaranteed to be a valid URL (which means the resulting output could fail HTML validation). To guarantee a valid URL, use Url::fromUri($user_input)->toString() (which either throws an exception or returns a well-formed URL) before passing the result into a ":variable" placeholder.
string A formatted HTML string with the placeholders replaced.
\Drupal\Core\StringTranslation\TranslatableMarkup
\Drupal\Core\StringTranslation\PluralTranslatableMarkup
\Drupal\Component\Utility\Html::escape()
\Drupal\Component\Utility\UrlHelper::stripDangerousProtocols()
protected static function placeholderFormat($string, array $args) { // Transform arguments before inserting them. foreach ($args as $key => $value) { switch ($key[0]) { case '@': // Escape if the value is not an object from a class that implements // \Drupal\Component\Render\MarkupInterface, for example strings will // be escaped. // Strings that are safe within HTML fragments, but not within other // contexts, may still be an instance of // \Drupal\Component\Render\MarkupInterface, so this placeholder type // must not be used within HTML attributes, JavaScript, or CSS. $args[$key] = static::placeholderEscape($value); break; case ':': // Strip URL protocols that can be XSS vectors. $value = UrlHelper::stripDangerousProtocols($value); // Escape unconditionally, without checking whether the value is an // instance of \Drupal\Component\Render\MarkupInterface. This forces // characters that are unsafe for use in an "href" HTML attribute to // be encoded. If a caller wants to pass a value that is extracted // from HTML and therefore is already HTML encoded, it must invoke // \Drupal\Component\Render\OutputStrategyInterface::renderFromHtml() // on it prior to passing it in as a placeholder value of this type. // @todo Add some advice and stronger warnings. // https://www.drupal.org/node/2569041. $args[$key] = Html::escape($value); break; case '%': // Similarly to @, escape non-safe values. Also, add wrapping markup // in order to render as a placeholder. Not for use within attributes, // per the warning above about // \Drupal\Component\Render\MarkupInterface and also due to the // wrapping markup. $args[$key] = '<em class="placeholder">' . static::placeholderEscape($value) . '</em>'; break; default: // We do not trigger an error for placeholder that start with an // alphabetic character. if (!ctype_alpha($key[0])) { // We trigger an error as we may want to introduce new placeholders // in the future without breaking backward compatibility. trigger_error('Invalid placeholder (' . $key . ') in string: ' . $string, E_USER_ERROR); } break; } } return strtr($string, $args); }
© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!lib!Drupal!Component!Render!FormattableMarkup.php/function/FormattableMarkup::placeholderFormat/8.1.x