Magento 2: template security: which method to use?

The escaping methods in AbstractBlock all delegate calls to Magento\Framework\Escaper, so you'll find an overview there.

Let's look at the public methods and their documentation:

escapeHtml()

/**
 * Escape string for HTML context. allowedTags will not be escaped, except the following: script, img, embed,
 * iframe, video, source, object, audio
 *
 * @param string|array $data
 * @param array|null $allowedTags
 * @return string|array
 */
public function escapeHtml($data, $allowedTags = null)

This should be your default escaping method for any output. Convention is that the result of all methods that do not contain "Html" must be escaped.

escapeHtmlAttr()

(since Magento 2.2)

/**
 * Escape a string for the HTML attribute context
 *
 * @param string $string
 * @param boolean $escapeSingleQuote
 * @return string
 */
public function escapeHtmlAttr($string, $escapeSingleQuote = true)

Use this to escape output within a HTML attribute, for example

title="<?php echo $block->escapeHtmlAttr($title) ?>"

It will escape HTML, but also quotes (")

By default, it will also escape single quotes, so this works too:

onclick="alert('<?php echo $block->escapeHtmlAttr($message) ?>')"

Set the second parameter to false if this is not desired.

escapeUrl()

/**
 * Escape URL
 *
 * @param string $string
 * @return string
 */
public function escapeUrl($string)

This can be used to output URLs. It will apply the default HTML escaping and additionally removes javascript:, vbscript: and data:. If you want to prevent URLs like this in user provided links, you can use the method.

Until Magento 2.1 this feature was not included and you needed to use escapeXssInUrl() instead. There was no reason to use escapeUrl() at all.

Otherwise, just use $block->escapeHtmlAttr() for URLs.

escapeJs()

(since Magento 2.2)

/**
 * Escape string for the JavaScript context
 *
 * @param string $string
 * @return string
 */
public function escapeJs($string)

Encodes unicode characters for JavaScript, for example becomes \u2665. Use it to escape output within a JS string. For inline Javascript (i.e. onclick attributes), you still need to call escapeHtmlAttr().

Note that if you use json_encode(), it already does the same escaping, in this case, escapeJs() must not be used.

escapeCss()

(since Magento 2.2)

/**
 * Escape string for the CSS context
 *
 * @param string $string
 * @return string
 */
public function escapeCss($string)

Encodes unicode characters for CSS (see escapeJs()), for example to be used in the content CSS attribute.

Deprecated methods (as of Magento 2.2):

  • escapeJsQuote: Use escapeHtmlAttr() instead
  • escapeXssInUrl: Use escapeUrl() instead
  • escapeQuote: Use escapeHtmlAttr() instead

This is for Magento 2.0. For 2.1, refer to Fabian's answer

escapeHtml

Use this function in the case of a string output that should not contain HTML.

Example:

<span class='label'><?php echo $block->escapeHtml($block->getLabel()); ?></span>

escapeQuote

Use this function in the case of HTML attributes

Example:

<span class="<?php echo $block->escapeQuote($block->getSpanClass()); ?>">Description</span>

escapeUrl

Use this function in case of an URL output (without XSS prevention - only character conversion)

Example:

<a href="<?php echo $block->escapeUrl($block->getUrl()); ?>">Link</a>

escapeXssInUrl

Use this function in case of an URL output (with XSS prevention - including character conversation)

Example:

<a href="<?php echo $block->escapeXssInUrl($block->getUrl()); ?>">Link</a>

What does not need escaping ?

  • Type casting and php function count() (example echo (int)$var)
  • Output in single quotes (example echo 'test')
  • Output in double quotes without variables (example echo "test")

The __ method

This one is used for translation purposes. Use it when you know a string can be translated.

For example:

<caption class="table-caption"><?php /* @escapeNotVerified */ echo __('More Information') ?></caption>