刀片模板递归包括

Posted

技术标签:

【中文标题】刀片模板递归包括【英文标题】:blade templates recursive includes 【发布时间】:2014-04-17 03:51:31 【问题描述】:

我有一个项目数组,代表服务器上目录的文件和目录结构。

$items 数组的构造如下:

Array
(
    [folder1] => Array
        (
            [folder1_1] => Array
                (
                    [0] => filenameX.txt
                    [1] => filenameY.txt
                )
        )
    [pages] => Array
        (
        )
    [0] => filename.txt
    [1] => filename1.txt
)

我们想要的,本质上是<ul>,每个节点都有<li>

生成的 html 应该类似于

文件夹1/ 文件夹1_1/ 文件名X.txt 文件名Y.txt 页数/ 文件名_1.txt 文件名_2.txt

现在,我的问题与 laravel 刀片模板引擎的嵌套包含有关。

我有一个视图list.blade.php,内容如下

<div class="listing">
  @include('submenu', array('items', $items))
</div>

然后我像这样将数组传递给它:

View::make('list')-&gt;with('items', $items)

包含的模板 (submenu.blade.php) 具有以下内容:

<ul>
@foreach($items as $key=>$value)
    @if (is_array($value))
        <li>$key/
        @include('submenu', array('items', $value))
        </li>
    @else
        <li>$value</li>
    @endif
@endforeach
</ul>

如果$value 是一个数组(目录)

首先,这可能吗?

如果没有,还有其他方法可以达到预期的效果吗?

TIA,

【问题讨论】:

请记住,递归可能很长。 好吧,我做到了...PHP Fatal error: Allowed memory size of 134217728 bytes exhausted 【参考方案1】:

是的,这确实是可能的。

但是,您的包含有一个问题,您有:

@include('submenu', array('items', $value))

应该是:

@include('submenu', array('items' => $value))

值得注意的是另一个隐藏的刀片声明,@each。您可以使用它而不是自己循环遍历数组,如下所示:

<ul>
    @each('item.detail', $items, 'item')
</ul>

然后,您创建一个名为 item.detail 的新刀片文件,并在该文件中弹出您之前在循环中拥有的内容。它有助于清理视图,避免嵌套循环越来越多。

当您在新刀片文件中时,该项目的数据将保存在第三个参数中,在本例中为 $item

【讨论】:

【参考方案2】:

不要使用数组,而是使用一个雄辩的集合。不要使用@include,而是使用\View::make。它清理了一些代码。这是 Foundation 5 框架的示例下拉菜单,使用具有父/子关系的 eloquent 模型:

我的模型有父->子关系

public function children() 
    return $this->hasMany('Category', 'parent_id');

我在我的控制器中生成我的结果

$categories = \Category::where('parent_id', '=', '0')->with('children')->get();

刀片模板:_partials.dd-menu.blade.php

<ul class="$class">
@foreach($items as $item)
<?php
$active = $item->id == \Input::get('category') ? 'active' : '';
$hdd = $item->children->count() ? 'has-dropdown' : '';
?>
<li class="$hdd $active">
    <a href="?category=$item->id">$item->name</a>
    @if ($item->children->count())
     View::make('_partials.dd-menu')->withItems($item->children)->withClass('dropdown')
    @endif
</li>
@endforeach

在您的父刀片中:

<nav class="top-bar" data-topbar role="navigation">
            <ul class="title-area">
                <li class="name">
                    <h1><a href="?category=">Categories</a></h1>
                </li>
                <!-- Remove the class "menu-icon" to get rid of menu icon. Take out "Menu" to just have icon alone -->
                <li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li>
            </ul>
            <section class="top-bar-section">
                <!-- Right Nav Section -->
                 View::make('_partials.dd-menu')->withItems($categories)->withClass('right')
            </section>
        </nav>

【讨论】:

以上是关于刀片模板递归包括的主要内容,如果未能解决你的问题,请参考以下文章

默认包含的刀片模板产量

Laravel 刀片模板

清洁 Laravel 刀片模板文件的最佳方式是啥?

刀片模板未正确显示

laravel 刀片模板变量

Laravel:有啥方法可以在不编译的情况下加载刀片模板?