Laravel - Blade @yield 在向用户提供 html 时忽略标签

Posted

技术标签:

【中文标题】Laravel - Blade @yield 在向用户提供 html 时忽略标签【英文标题】:Laravel - blade @yield ignores tabs when serving html to user 【发布时间】:2019-03-11 08:48:27 【问题描述】:

所以我得到了一个奇怪的结果,我无法理解。这只是 html 在源代码中看起来有多漂亮的问题,但这有点烦人,因为它有时也会不一致地缩进。

这里是layout.blade.php文件,忽略上面大部分的html部分:

            </div>
            <div class="content">
                @yield('content')
            </div>
        </div>
    </body>
</html>

这里是扩展 layout.blade.php 的 index.blade.php:

@extends('layout')   

@section('content')

<div class="main-title">
    <h1>Developer</h1>
    <svg>
        <line x1="0" y1="0" x2="300" y2="0" style="stroke:rgb(255,255,255);stroke-width:10" />
    </svg>
    <h1>Designer</h1>
</div>

@stop

我认为这将与 @yield() 放在相同的缩进级别,因为这就是 django 模板和 laravel 教程中发生的情况。

这就是我得到的:

            <div class="content">

<div class="main-title">
    <h1>Developer</h1>
    <svg>
        <line x1="0" y1="0" x2="300" y2="0" style="stroke:rgb(255,255,255);stroke-width:10" />
    </svg>
    <h1>Designer</h1>
</div>

            </div>
        </div>
    </body>
</html>

如您所见,内容不是在 layout.blade.php 中放置 @yield() 的位置。

查看正在服务的生成的php文件看起来应该没问题:

            </div>
            <div class="content">
                <?php echo $__env->yieldContent('content'); ?>
            </div>
        </div>
    </body>
</html>

从 index.blade.php 生成:

<?php $__env->startSection('content'); ?>

                <div class="main-title">
                    <h1>Developer</h1>
                    <svg>
                        <line x1="0" y1="0" x2="300" y2="0" style="stroke:rgb(255,255,255);stroke-width:10" />
                    </svg>
                    <h1>Designer</h1>
                </div>

<?php $__env->stopSection(); ?>
<?php echo $__env->make('layout', \Illuminate\Support\Arr::except(get_defined_vars(), array('__data', '__path')))->render(); ?>

这一切都让我假设提供的 html 将具有适当的制表符间距,但事实并非如此。可能是什么原因?可能有一些配置还是只是刀片的一个怪癖?

【问题讨论】:

我现在正在尝试自己解决这个问题!大声笑我想知道它的输出是否基于它在索引刀片文件中的缩进?看看它是否会因此而改变?你的意思是index.blade.html 还是index.blade.php 这是一个错误,index.blade.php 是正确的文件。 您为什么希望框架为您插入标签?您要求它插入该部分,它会这样做。 我想您可以使用 after 中间件查看响应并使用 tidy_parse_string() 进行清理。我建议不要在生产站点上这样做。 php.net/manual/en/tidy.parsestring.php 【参考方案1】:

可能是什么原因?可能有一些配置还是只是刀片的一个怪癖?

原因是:这就是 PHP 的工作方式,以及 Laravel Blade 作为 PHP 之上的构造如何实现它的功能。指令@yield('content')function call: echo $__env-&gt;yieldContent('content');。你已经猜到了。 Here the implementation.

现在的重点是该函数将'content' 作为输入参数。至于函数在 PHP(和大多数命令式编程语言)中的工作方式,它不知道您作为缩进放置的前面的空格,它根本无法通过使用该语法将其作为参数使用。考虑一下,如果这个例子真的像你预期的那样工作,这意味着违反了 PHP 语法和语义,并且现在工作的许多其他事情会突然停止工作,因为语言本身需要保持 语法结构的一致性.

当然,从开发人员或用户的角度来看,might look "a bit like an annoying quirk" 的说法是正确的,但从未说过刀片或 PHP 应该以这种方式工作,这意味着它不是一个预期的功能。

现在,如果您的意图是更改输出代码,有很多方法可以应用过滤器,无论是用于缩小/混淆还是美化,例如 middleware filters。当然,those approaches 可能需要一些处理能力,您将根据自己的需求和环境(本地或 PRD)进行评估。

【讨论】:

来自 django,我确实希望它能够以这种方式工作。但他们使用接近 jinja 的东西作为他们的模板引擎。这真的没关系,但它会使阅读页面源代码变得更糟,特别是如果您在@section@stop 部分之间没有空间。它从未说过它应该那样工作,这是公平的。 我不知道 Django 是如何处理它的,但如果它以这种方式工作,可能是因为它们使用了不同的结构/方法。这也可能是模板系统本身的一个特性。在你的位置,我会缩进我的部分或使用一些美化器来输出,如果你需要它以获得更好的调试体验,情况会更是如此。【参考方案2】:

我也对此感到困扰,因为这不会在 Laravel 本身中修复I decided to fix this in a package that extends on the blade compiler。在模板中找到刀片语法的正则表达式现在包括任何水平空格,直到刀片语句,并将其传递给生成的 PHP 语句来呈现内容。在替换内容中的任何换行符之后,然后添加间距,如果替换内容没有尾随换行符,则也添加它。希望这对遇到此问题的人有所帮助!

【讨论】:

以上是关于Laravel - Blade @yield 在向用户提供 html 时忽略标签的主要内容,如果未能解决你的问题,请参考以下文章

markdown Para definir布局de la forma tradicional con Blade en Laravel usamos la directiva @yield de es

laravel-模板引擎Blade

TODO:Laravel 使用blade标签布局页面

Laravel中的模板引擎Blade

PHP笔记-laravel中Blade模板引擎的使用

Laravel 6 @yield() 在 include() 方法中不起作用