CakePHP 3 - 如何在视图单元格内设置 CSS / 脚本块
CakePHP 3 - How to set CSS / Script block inside a View Cell
我正在使用 CakePHP 3.9
我正在尝试在我的视图单元格中设置 css / 脚本依赖块。
我希望将其提取到布局的头部,但它不起作用。如果我想让它工作,我必须在调用单元格的视图 before/after 中设置 css 依赖项。
有什么方法可以在 View Cell 中设置 css 依赖项吗?
我的看法:
<?= $this->cell('Post::post_input'); ?>
....
我的查看单元格:
<?php echo $this->Html->css(['element/post-input'], ['block' => true]); ?>
<div class="post-input">...</div>
我的布局:
<html>
<head>
...
<?php
echo $this->fetch('css');
echo $this->fetch('script');
?>
...
</head>
<body>
<?php echo $this->fetch('content'); ?>
</body>
</html>
它不起作用,因为单元格是一个使用单独视图实例的封闭环境,因此您在其模板中定义的所有块都将驻留在其内部视图中。
来自文档:
Cell templates have an isolated scope that does not share the same View instance as the one used to render template and layout for the current controller action or other cells. Hence they are unaware of any helper calls made or blocks set in the action’s template / layout and vice versa.
Cookbook > Views > View Cells > Implementing the Cell
如果您不想在每次使用单元格时手动添加 CSS 块,那么我建议您构建一个可以生成(甚至直接回显)单元格并添加的自定义助手块,类似这样的东西:
<?php
// in src/View/Helper/PostHelper.php
namespace App\View\Helper;
use Cake\View\Helper;
/**
* @property \Cake\View\Helper\HtmlHelper $Html
*/
class PostHelper extends Helper
{
protected $helpers = [
'Html'
];
protected $wasPostInputCssAdded = false;
public function postInput()
{
if (!$this->wasPostInputCssAdded) {
$this->wasPostInputCssAdded = true;
$this->Html->css(['element/post-input'], ['block' => true]);
}
return $this->_View->cell('Post::post_input');
}
}
下面将添加块并回显单元格:
<?= $this->Post->postInput() ?>
另一个不需要重写模板的选项是创建一个使用 CellView
class 的自定义 Cell
class。视图 class 然后将单元格内容包装在一个布局中,该布局可以像您在 Cake view/layout 模板中通常期望的那样显示块。
<?php
declare(strict_types=1);
namespace App\View;
use Cake\View\Cell as BaseCell;
use Cake\View\View;
class Cell extends BaseCell
{
/**
* @inheritDoc
*/
public function createView(?string $viewClass = null): View
{
// use custom CellView to for Cells
return parent::createView(CellView::class);
}
}
然后是 CellView:
<?php
declare(strict_types=1);
namespace App\View;
class CellView extends AppView
{
/**
* @inheritDoc
*/
public function render(?string $template = null, $layout = null): string
{
$cellContents = parent::render($template, $layout);
// wrap cell contents in "cell" layout
return $this->renderLayout($cellContents, 'cell');
}
}
现在所有的单元格都使用了布局,剩下的就是创建一个单元格专用的基本布局:
/templates/layout/cell.php (CakePHP 3: /src/Template/Layout/cell.ctp)
<?php
/**
* @var CellView $this
*/
use App\View\CellView;
echo $this->fetch('styles');
echo $this->fetch('content');
echo $this->fetch('scripts');
完成这项初始工作后,所有 App\View\Cell
都将使用“单元格”布局。我发现如果您使用不同的块或 postLink
s 块,这在长 运行 中更直观。
注意:此处的代码适用于 CakePHP 4,但要使其与 CakePHP 3 兼容,您需要做的就是匹配方法签名
我正在使用 CakePHP 3.9
我正在尝试在我的视图单元格中设置 css / 脚本依赖块。
我希望将其提取到布局的头部,但它不起作用。如果我想让它工作,我必须在调用单元格的视图 before/after 中设置 css 依赖项。
有什么方法可以在 View Cell 中设置 css 依赖项吗?
我的看法:
<?= $this->cell('Post::post_input'); ?>
....
我的查看单元格:
<?php echo $this->Html->css(['element/post-input'], ['block' => true]); ?>
<div class="post-input">...</div>
我的布局:
<html>
<head>
...
<?php
echo $this->fetch('css');
echo $this->fetch('script');
?>
...
</head>
<body>
<?php echo $this->fetch('content'); ?>
</body>
</html>
它不起作用,因为单元格是一个使用单独视图实例的封闭环境,因此您在其模板中定义的所有块都将驻留在其内部视图中。
来自文档:
Cell templates have an isolated scope that does not share the same View instance as the one used to render template and layout for the current controller action or other cells. Hence they are unaware of any helper calls made or blocks set in the action’s template / layout and vice versa.
Cookbook > Views > View Cells > Implementing the Cell
如果您不想在每次使用单元格时手动添加 CSS 块,那么我建议您构建一个可以生成(甚至直接回显)单元格并添加的自定义助手块,类似这样的东西:
<?php
// in src/View/Helper/PostHelper.php
namespace App\View\Helper;
use Cake\View\Helper;
/**
* @property \Cake\View\Helper\HtmlHelper $Html
*/
class PostHelper extends Helper
{
protected $helpers = [
'Html'
];
protected $wasPostInputCssAdded = false;
public function postInput()
{
if (!$this->wasPostInputCssAdded) {
$this->wasPostInputCssAdded = true;
$this->Html->css(['element/post-input'], ['block' => true]);
}
return $this->_View->cell('Post::post_input');
}
}
下面将添加块并回显单元格:
<?= $this->Post->postInput() ?>
另一个不需要重写模板的选项是创建一个使用 CellView
class 的自定义 Cell
class。视图 class 然后将单元格内容包装在一个布局中,该布局可以像您在 Cake view/layout 模板中通常期望的那样显示块。
<?php
declare(strict_types=1);
namespace App\View;
use Cake\View\Cell as BaseCell;
use Cake\View\View;
class Cell extends BaseCell
{
/**
* @inheritDoc
*/
public function createView(?string $viewClass = null): View
{
// use custom CellView to for Cells
return parent::createView(CellView::class);
}
}
然后是 CellView:
<?php
declare(strict_types=1);
namespace App\View;
class CellView extends AppView
{
/**
* @inheritDoc
*/
public function render(?string $template = null, $layout = null): string
{
$cellContents = parent::render($template, $layout);
// wrap cell contents in "cell" layout
return $this->renderLayout($cellContents, 'cell');
}
}
现在所有的单元格都使用了布局,剩下的就是创建一个单元格专用的基本布局:
/templates/layout/cell.php (CakePHP 3: /src/Template/Layout/cell.ctp)
<?php
/**
* @var CellView $this
*/
use App\View\CellView;
echo $this->fetch('styles');
echo $this->fetch('content');
echo $this->fetch('scripts');
完成这项初始工作后,所有 App\View\Cell
都将使用“单元格”布局。我发现如果您使用不同的块或 postLink
s 块,这在长 运行 中更直观。
注意:此处的代码适用于 CakePHP 4,但要使其与 CakePHP 3 兼容,您需要做的就是匹配方法签名