Custom Laravel Blade Directive 始终将 Bool 解释为 True

huangapple go评论55阅读模式
英文:

Custom Laravel Blade Directive Always Interprets Bool as True

问题

我正在开发一个 Laravel 9 项目,想要创建一个自定义 Blade 指令,该指令接受一个布尔值,如果为 "true",则添加 style="display: none;"(这样我就不需要使用 @if... @endif)。

在我的 App\Providers\AppServiceProvider.php 文件中,我在 boot() 方法中添加了以下内容:

Blade::directive('fadeIn', function (bool $fade_in) {
    if ($fade_in) {
        return 'style="display: none;"';
    }
});

然后在我的 Blade 模板中这样使用它:

<div @fadeIn(false)></div>

尽管我传递了 "false",但它仍然返回/添加了 style="display: none;",就好像我传递了 "true" 一样。

我已经运行了 php artisan view:clear(因为指令的函数被缓存,不会在更改后更新),但似乎没有解决问题。移除参数类型也不起作用。

英文:

I'm working on a Laravel 9 project and wanted to create a custom Blade directive that takes in a bool and if it's "true" adds style=&quot;display: none;&quot; (so I don't need to use @if... @endif)

In my App\Providers\AppServiceProvider.php I added the following in the boot() method:

Blade::directive(&#39;fadeIn&#39;, function (bool $fade_in) {
    if ($fade_in) {
        return &#39;style=&quot;display: none;&quot;&#39;;
    }
});

And using it like so in my Blade template:

&lt;div @fadeIn(false)&gt;&lt;/div&gt;

And even though I pass "false" it still returns/adds style=&quot;display: none;&quot; as if I passed "true" to it.

I've ran php artisan view:clear (as the directive's function is cached and won't update on any changes) and that doesn't seem to fix things. Removing the parameter type doesn't work either.

答案1

得分: 1

以下是您要翻译的内容:

Blade directives receive the expression inside the parenthesis, (...).
Blade指令接收括号内的表达式,(...)

Directives do not run at the time the template is executed. They are ran as the Blade template is being compiled to PHP. Directives replace things, they don't run at run time. So you need to return what you want the directive to be replaced with at the time it runs.
指令不在模板执行时运行。它们在将Blade模板编译为PHP时运行。指令替换内容,它们不在运行时执行。因此,您需要返回希望指令在运行时替换的内容。

function ($expression) {
return "<?php echo ({$expression}) ? 'style="display: none;"' : '' ?>";
}

This would replace that Blade directive with what is returned, which is just text, that just happens to be valid PHP. So, when the compiled template is actually executed (since it is just a PHP file) it will run that PHP that we have now compiled into it. This means it will actually be dynamic since we now have PHP code that we have in the template that will run at run time and can make use of the expression.
这将用返回的内容替换Blade指令,这只是文本,恰好是有效的PHP。因此,当编译后的模板实际执行时(因为它只是一个PHP文件),它将运行我们现在编译到其中的PHP。这意味着它实际上是动态的,因为我们现在在模板中有可以在运行时运行并使用表达式的PHP代码。

Resulting text in compiled PHP file; based on your example usage:
编译后的PHP文件中的结果文本;基于您的示例用法:

<?php echo (false) ? 'style="display: none;"' : '' ?>

To explain why you are seeing what you are seeing in your version:
解释您看到的原因:

The directive's function receives the expression not the value; it receives the text, it is not code in the context of executing code, it is just arbitrary text. You are forcing that string to be a boolean with the type-hint: true === (bool) 'false'.
指令的函数接收表达式而不是值;它接收文本,它不是在执行代码的上下文中的代码,它只是任意的文本。您使用类型提示将该字符串强制转换为布尔值:true === (bool) 'false'

Even if you removed the type-hint and received the string properly your conditional would cause type-juggling and it would be converted to a boolean; which again: true === (bool) 'false'.
即使您删除了类型提示并正确接收了字符串,您的条件也会引起类型转换,并将其转换为布尔值;再次强调:true === (bool) 'false'

On a side note, all strings are true except the "falsey" strings: '0', ''.
顺便说一句,除了“falsey”字符串,所有字符串都是true'0'''

英文:

Blade directives receive the expression inside the parenthesis, (...).

Directives do not run at the time the template is executed. They are ran as the Blade template is being compiled to PHP. Directives replace things, they don't run at run time. So you need to return what you want the directive to be replaced with at the time it runs.

function ($expression) {
    return &quot;&lt;?php echo ({$expression}) ? &#39;style=\&quot;display: none;\&quot;&#39; : &#39;&#39;; ?&gt;&quot;;
}

This would replace that Blade directive with what is returned, which is just text, that just happens to be valid PHP. So, when the compiled template is actually executed (since it is just a PHP file) it will run that PHP that we have now compiled into it. This means it will actually be dynamic since we now have PHP code that we have in the template that will run at run time and can make use of the expression.

Resulting text in compiled PHP file; based on your example usage:

&lt;?php echo (false) ? &#39;style=&quot;display: none;&quot;&#39; : &#39;&#39;; ?&gt;

To explain why you are seeing what you are seeing in your version:

The directive's function receives the expression not the value; it receives the text, it is not code in the context of executing code, it is just arbitrary text. You are forcing that string to be a boolean with the type-hint: true === (bool) &#39;false&#39;.

Even if you removed the type-hint and received the string properly your conditional would cause type-juggling and it would be converted to a boolean; which again: true === (bool) &#39;false&#39;.

On a side note, all strings are true except the "falsey" strings: &#39;0&#39;, &#39;&#39;.

huangapple
  • 本文由 发表于 2023年4月11日 01:33:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75979314.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定