Sanitizing HTML output in templates in 2.4
-
14-04-2021 - |
Question
Before 2.4 the way you could sanitize an html value in a template was to use $block->escapeHtml($valueHere);
.
Where $blick
is the instance of the current block.
This still works in 2.4, but the method is deprecated.
/**
* Escape HTML entities
*
* @param string|array $data
* @param array|null $allowedTags
* @return string
* @deprecated Use $escaper directly in templates and in blocks.
*/
public function escapeHtml($data, $allowedTags = null)
{
return $this->_escaper->escapeHtml($data, $allowedTags);
}
The recommendation is to use the escaper directly in the templates.
But I cannot add the escaper instance as a view model in the template because Magento\Framework\Escaper
does not implement Magento\Framework\View\Element\Block\ArgumentInterface
.
So if I do this in my layout files
<block ...>
<arguments>
<argument name="escaper" xsi:type="object">Magento\Framework\Escaper</argument>
</arguments>
</block>
I get an exception
Instance of Magento\Framework\View\Element\Block\ArgumentInterface is expected, got Magento\Framework\Escaper instead.
Is there another clean way to use escape the html values in a template?
Solution
Apparently in 2.4 simply calling $escaper->escaperHtml()
works.
$escaper
is an instance of Magento\Framework\Escaper
sent directly to the template in the same way as $block
is an instance of the current block class. It's all done in Magento\Framework\View\TemplateEngine\Php::render()
public function render(BlockInterface $block, $fileName, array $dictionary = [])
{
ob_start();
try {
$tmpBlock = $this->_currentBlock;
$this->_currentBlock = $block;
extract($dictionary, EXTR_SKIP);
//So it can be used in the template.
$escaper = $this->escaper; // <-- here it is
// phpcs:ignore
include $fileName;
$this->_currentBlock = $tmpBlock;
} catch (\Exception $exception) {
ob_end_clean();
throw $exception;
}
/** Get output buffer. */
$output = ob_get_clean();
return $output;
}