Please take care to format your code blocks if you want anyone to take your question seriously.
function inside of a blade functions in the blade view file causes ParseError: Unclosed '(' error
i am using the latest version of Laravel (laravel/framework: 10.38.0)
I think that this is an unintended bug with the laravel blade views, because if i use a
@if(count($items) > 1)
@endif
inside of my blade view (like how it is shown in the documentation, "/docs/10.x/blade#if-statements"), then when i try to load my page the content will be passed through a function called "hasEvenNumberOfParentheses" in the following path: "vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php".
in the function "compileStatements" which calls the "hasEvenNumberOfParentheses" function it will perform a regex search for anything that start with a @ function until the first closing bracket ")" is found, so the result that comes back out of the regex will be
@if(count($items)
which means its unclosed and incomplete from the actual line which in turn triggers errors to be thrown around.
this is the function with the regex "vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php::compileStatements"
/**
* Compile Blade statements that start with "@".
*
* @param string $template
* @return string
*/
protected function compileStatements($template)
{
preg_match_all('/\B@(@?\w+(?:::\w+)?)([ \t]*)(\( ( [\S\s]*? ) \))?/x', $template, $matches);
$offset = 0;
for ($i = 0; isset($matches[0][$i]); $i++) {
$match = [
$matches[0][$i],
$matches[1][$i],
$matches[2][$i],
$matches[3][$i] ?: null,
$matches[4][$i] ?: null,
];
// Here we check to see if we have properly found the closing parenthesis by
// regex pattern or not, and will recursively continue on to the next ")"
// then check again until the tokenizer confirms we find the right one.
while (isset($match[4]) &&
Str::endsWith($match[0], ')') &&
! $this->hasEvenNumberOfParentheses($match[0])) { // this is where the errors occurs
if (($after = Str::after($template, $match[0])) === $template) {
break;
}
$rest = Str::before($after, ')');
if (isset($matches[0][$i + 1]) && Str::contains($rest.')', $matches[0][$i + 1])) {
unset($matches[0][$i + 1]);
$i++;
}
$match[0] = $match[0].$rest.')';
$match[3] = $match[3].$rest.')';
$match[4] = $match[4].$rest;
}
[$template, $offset] = $this->replaceFirstStatement(
$match[0],
$this->compileStatement($match),
$template,
$offset
);
}
return $template;
}
but this also causes errors if i try to do something like this
@if((condition1 || condition2) && condition3)
@endif
or
@if(is_string($value))
@endif
or
@if (count($errors) > 0) // regex return: "@if (count($errors)"
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error) // regex return: "@foreach ($errors->all()"
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
Please or to participate in this conversation.