To better understand how Laravel tag settings work, I tried the following:
Blade::setContentTags('<x', 'x>');
Blade::setEscapedContentTags('<y', 'y>');
Blade::setRawTags('<z', 'z>');
in my controller constructor.
In Blade view, I added
<div>
<x 'test' x>
<y 'test' y>
<z 'test' z>
</div>
I cleaned storage/framework/views folder and reloaded the page.
As a result, in compiled view I got
<div>
<?php echo e('test'); ?>
<?php echo e('test'); ?>
<?php echo 'test'; ?>
</div>
As you see, the code compiled for tags specified with setContentTags and setEscapedContentTags looks the same. Why do we need both of these options then?
It's kind of safety reason.
By default, Blade
will return equal results for content with regular and escaped tags. BladeCompiler
class has protected property $echoFormat
with value e(%s)
. This property is used when content compiles with regular tags (in your case it's 'x').
/**
* The "regular" / legacy echo string format.
*
* @var string
*/
protected $echoFormat = 'e(%s)';
The property works as a placeholder for the function e
/**
* Escape HTML entities in a string.
*
* @param string $value
* @return string
*/
function e($value)
{
return htmlentities($value, ENT_QUOTES, 'UTF-8', false);
}
The e
function is also called when content compiles with escaped tags (in your case it's 'y')
Your can change format also:
/**
* Set the echo format to be used by the compiler.
*
* @param string $format
* @return void
*/
public function setEchoFormat($format)
{
$this->echoFormat = $format;
}
With default settings Blade
will return different results for content with regular
and escaped tags
if you prefix your text with an @
symbol.
For view param
['str' => "<script>alert('name')</script>"]
With template
<div>@{{ $str }}</div>
<div>@{{{ $str }}}</div>
<div>@{{"<a>Plain text</a>"}}</div>
<div>@{{{"<a>Plain text</a>"}}}</div>
The result will be
<div>{{ $str }}</div>
<div>@<script>alert('name')</script></div>
<div>{{"<a>Plain text</a>"}}</div>
<div>@<a>Plain text</a></div>