我可以在哪里存储,如何在CakePHP 3.9中加载小部件字符串模板?

问题描述

我想创建一个CakePHP Widget,以创建一个自定义表单控件。最终目标是使其成为一个插件,但是现在我正在尝试确定Widget的一般结构。我已经在src / View / Widget / DateTimeWidget.PHP中创建了一个包含

文件
<?PHP
namespace App\View\Widget;

use Cake\View\Form\ContextInterface;
use Cake\View\Widget\WidgetInterface;

class DateTimeWidget implements WidgetInterface
{

    protected $_templates;

    public function __construct($templates)
    {
        $this->_templates = $templates;
    }

    public function render(array $data,ContextInterface $context)
    {
        $data += [
            'name' => '',];
        return $this->_templates->format('DateTime',[
            'name' => $data['name'],'attrs' => $this->_templates->formatAttributes($data,['name'])
        ]);
    }

    public function secureFields(array $data)
    {
        return [$data['name']];
    }
}
?>

我将代码加载到视图中的窗口小部件

$this->Form->addWidget(
    'datetime',['DateTime']
);

,然后使用

创建一个表单控件
echo $this->Form->control('end_time',['type' => 'datetime']);

但是,出现错误Cannot find template named 'DateTime'

我已经创建了基本模板代码

<?PHP
$this->Form->setTemplates([
    'DateTime' => '<p {{attrs}}>Test template</p>'
]);

但是我不知道在文件夹结构中的什么位置?在大多数插件中,我都看过它在帮助文件中,但是我想知道这是否是认的方法吗?我有什么选择?我如何告诉CakePHP加载它?首选的方法是什么?

谢谢!

解决方法

我认为您应该使用Cells。

看看:https://book.cakephp.org/3/en/views/cells.html

,

如果您希望小部件附带默认的字符串模板,则可以例如在小部件本身中定义它们,方法是将其添加到要传递给小部件构造函数的字符串模板实例中。不过,您可以在窗口小部件的render()方法中执行此操作,由于在重新使用窗口小部件实例(即,它们仅被构造一次),因此在构造函数中无法正常工作,例如:

public function render(array $data,ContextInterface $context)
{
    if (!array_key_exists('customDateTime',$this->_templates->getConfig())) {
        $this->_templates->add([
            'customDateTime' => '<p {{attrs}}>Test template</p>',// ...
        ]);
    }

     // ...
}

另一个选择是将字符串模板放在配置文件中:

// in path_to_your_plugin/config/form_helper_templates.php
<?php
return [
    'customDateTime' => '<p {{attrs}}>Test template</p>',// ...
];

,并要求用户在想要使用您的窗口小部件时在其视图模板中加载表单帮助器字符串模板:

$this->Form->templater()->load('YourPluginName.form_helper_templates');

这两个选项都将与表单帮助程序正确集成,因此用户仍然可以通过FormHelper::setTemplates()StringTemplate::load()/add()templates选项设置自定义模板来覆盖模板1}}。