Widgets
小部件是独立的功能块,可以解决不同的任务。小部件总是有一个用户界面和一个后端控制器(小部件类),后者准备小部件数据并处理小部件用户界面生成的 AJAX 请求。
通用小部件
小部件是后端等同于前端Components.它们是相似的,因为它们是功能的模块化捆绑包,提供部分功能并使用别名命名。关键区别在于后端小部件使用 YAML 标记进行配置并将它们自己绑定到后端页面。
小部件类驻留在widgets 插件目录的目录。目录名称与小写的小部件类名称匹配。小部件可以提供资产和部分。一个示例小部件目录结构如下所示:
📂 widgets
┣ 📂 form
┃ ┣ 📂 partials
┃ ┃ ┗ 📜 _form.php <=== Widget partial file
┃ ┗ 📂 assets
┃ ┣ 📂 js
┃ ┃ ┗ 📜 form.js <=== Widget JavaScript file
┃ ┗ 📂 css
┃ ┗ 📜 form.css <=== Widget StyleSheet file
┗ 📜 Form.php <=== Widget class
类定义
通用小部件类必须扩展Backend\Classes\WidgetBase
班级。与任何其他插件类一样,通用小部件控制器应该属于插件命名空间.小部件控制器类定义示例:
<?php namespace Backend\Widgets;
use Backend\Classes\WidgetBase;
class Lists extends WidgetBase
{
/**
* @var string A unique alias to identify this widget.
*/
protected $defaultAlias = 'list';
// ...
}
小部件类必须包含render()
通过呈现小部件部分来生成小部件标记的方法。例子:
public function render()
{
return $this->makePartial('list');
}
要将变量传递给 partials,您可以将它们添加到$vars
财产。
public function render()
{
$this->vars['var'] = 'value';
return $this->makePartial('list');
}
或者,您可以将变量传递给 makePartial() 方法的第二个参数:
public function render()
{
return $this->makePartial('list', ['var' => 'value']);
}
使用小部件注入页面资产
小部件可以通过使用控制器的 addCss 和 addJs 方法将资产(CSS 和 JavaScript 文件)注入它们所附加的页面或布局,以将资产添加到 CMS 控制器。这应该在小部件的loadAssets()
方法。见资产编译器 文档以获取更多信息。
protected function loadAssets()
{
$this->addCss('css/form.css');
$this->addJs('css/form.js', 'Acme.Test');
}
AJAX 处理程序
小部件实现与后端控制器. AJAX 处理程序是小部件类的公共方法,名称以on 字首。小部件 AJAX 处理程序和后端控制器的 AJAX 处理程序之间的唯一区别是您应该使用小部件的getEventHandler
当您在小部件部分中引用它时返回小部件的处理程序名称的方法。
<a
href="javascript:;"
data-request="<?= $this->getEventHandler('onPaginate') ?>"
title="Next page">Next</a>
当从小部件类或部分调用时,AJAX 处理程序将以自身为目标。例如,如果小部件使用别名mywidget 处理程序将以mywidget::onName
.以上将输出以下属性值:
data-request="mywidget::onPaginate"
将小部件绑定到控制器
一个小部件应该绑定到后端控制器 在您可以开始在后端页面或部分中使用它之前。使用小部件的bindToController
将其绑定到控制器的方法。初始化小部件的最佳位置是控制器的构造函数。例子:
public function __construct()
{
parent::__construct();
$myWidget = new MyWidgetClass($this);
$myWidget->alias = 'myWidget';
$myWidget->bindToController();
}
绑定小部件后,您可以在控制器的视图中或通过其别名部分访问它:
<?= $this->widget->myWidget->render() ?>
表单小部件
使用表单小部件,您可以向后端添加新的控件类型forms.它们提供了为模型提供数据所共有的功能。表单小部件必须在插件注册文件.
表单小部件类驻留在formwidgets 插件目录的目录。目录名称与小写的小部件类名称匹配。小部件可以提供资产和部分。示例表单小部件目录结构如下所示:
📂 formwidgets
┣ 📂 form
┃ ┣ 📂 partials
┃ ┃ ┗ 📜 _form.php <=== Widget partial file
┃ ┗ 📂 assets
┃ ┣ 📂 js
┃ ┃ ┗ 📜 form.js <=== Widget JavaScript file
┃ ┗ 📂 css
┃ ┗ 📜 form.css <=== Widget StyleSheet file
┗ 📜 Form.php <=== Widget class
类定义
表单小部件类必须扩展Backend\Classes\FormWidgetBase
班级。与任何其他插件类一样,通用小部件控制器应该属于插件命名空间.已注册的小部件可以在后端使用表单字段定义 文件。示例表单小部件类定义:
namespace Backend\Widgets;
use Backend\Classes\FormWidgetBase;
class CodeEditor extends FormWidgetBase
{
/**
* @var string A unique alias to identify this widget.
*/
protected $defaultAlias = 'codeeditor';
public function render() {}
}
表单小部件属性
表单小部件可能具有可以使用表单字段配置.只需在类上定义可配置属性,然后调用fillFromConfig
方法将它们填充到init
方法定义。
class DatePicker extends FormWidgetBase
{
//
// Configurable properties
//
/**
* @var bool Display mode: datetime, date, time.
*/
public $mode = 'datetime';
/**
* @var string the minimum/earliest date that can be selected.
* eg: 2000-01-01
*/
public $minDate = null;
/**
* @var string the maximum/latest date that can be selected.
* eg: 2020-12-31
*/
public $maxDate = null;
//
// Object properties
//
/**
* {@inheritDoc}
*/
protected $defaultAlias = 'datepicker';
/**
* {@inheritDoc}
*/
public function init()
{
$this->fillFromConfig([
'mode',
'minDate',
'maxDate',
]);
}
// ...
}
然后属性值可以从表单字段定义 使用小部件时。
born_at:
label: Date of Birth
type: datepicker
mode: date
minDate: 1984-04-12
maxDate: 2014-04-23
表单小部件注册
插件应该通过覆盖registerFormWidgets
里面的方法插件注册类.该方法返回一个数组,其中包含键中的小部件类和作为值的小部件短代码。例子:
public function registerFormWidgets()
{
return [
'Backend\FormWidgets\CodeEditor' => 'codeeditor',
'Backend\FormWidgets\RichEditor' => 'richeditor'
];
}
短代码是可选的,可以在引用小部件时使用表单字段定义,它应该是一个唯一的值,以避免与其他表单字段发生冲突。
加载表单数据
表单小部件的主要目的是与您的模型交互,这意味着在大多数情况下通过数据库加载和保存值。当表单小部件呈现时,它将使用getLoadValue
方法。这getId
和getFieldName
方法将返回表单中使用的 HTML 元素的唯一标识符和名称。这些值通常在渲染时传递给部件部分。
public function render()
{
$this->vars['id'] = $this->getId();
$this->vars['name'] = $this->getFieldName();
$this->vars['value'] = $this->getLoadValue();
return $this->makePartial('myformwidget');
}
在基本层面上,表单小部件可以使用输入元素将用户输入的值发回。从上面的例子中,在myformwidget partial 可以使用准备好的变量来渲染元素。
<input id="<?= $id ?>" name="<?= $name ?>" value="<?= e($value) ?>" />
保存表单数据
当需要获取用户输入并将其存储在数据库中时,表单小部件将调用getSaveValue
在内部请求值。要修改此行为,只需覆盖表单小部件类中的方法即可。
public function getSaveValue($value)
{
return $value;
}
在某些情况下,您有意不希望提供任何值,例如,显示信息但不保存任何内容的表单小部件。返回名为的特殊常量FormField::NO_SAVE_DATA
源自Backend\Classes\FormField
忽略值的类。
public function getSaveValue($value)
{
return \Backend\Classes\FormField::NO_SAVE_DATA;
}
报告小部件
报表小部件可用于后端仪表板和其他后端报表容器。报告小部件必须在插件注册文件.
您可以使用
create:reportwidget
命令。看脚手架命令 了解更多信息。
报告小部件类
报告小部件类应该扩展Backend\Classes\ReportWidgetBase
班级。与任何其他插件类一样,通用小部件控制器应该属于插件命名空间.该类应该覆盖render
方法以呈现小部件本身。与所有后端小部件类似,报表小部件使用部分和特殊的目录布局。示例目录布局:
📂 plugins
┗ 📂 winter <=== Author name
┗ 📂 googleanalytics <=== Plugin name
┗ 📂 reportwidgets <=== Report widgets directory
┣ 📂 trafficsources <=== Widget files directory
┃ ┗ 📂 partials
┃ ┗ 📜 _widget.php
┗ 📜 TrafficSources.php <=== Widget class file
示例报告小部件类定义:
namespace Winter\GoogleAnalytics\ReportWidgets;
use Backend\Classes\ReportWidgetBase;
class TrafficSources extends ReportWidgetBase
{
public function render()
{
return $this->makePartial('widget');
}
}
小部件部分可以包含您想要在小部件中显示的任何 HTML 标记。标记应包装到 DIV 元素中report-widget 班级。最好使用 H3 元素输出小部件标题。示例小部件部分:
<div class="report-widget">
<h3>Traffic sources</h3>
<div
class="control-chart"
data-control="chart-pie"
data-size="200"
data-center-text="180">
<ul>
<li>Direct <span>1000</span></li>
<li>Social networks <span>800</span></li>
</ul>
</div>
</div>
在报告小部件中,您可以使用任何图表或指标、列表或您想要的任何其他标记。请记住,报表小部件扩展了通用后端小部件,您可以在报表小部件中使用任何小部件功能。下一个示例显示了一个列表报告小部件标记。
<div class="report-widget">
<h3>Top pages</h3>
<div class="table-container">
<table class="table data" data-provides="rowlink">
<thead>
<tr>
<th><span>Page URL</span></th>
<th><span>Pageviews</span></th>
<th><span>% Pageviews</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>/</td>
<td>90</td>
<td>
<div class="progress">
<div class="bar" style="90%"></div>
<a href="/">90%</a>
</div>
</td>
</tr>
<tr>
<td>/docs</td>
<td>10</td>
<td>
<div class="progress">
<div class="bar" style="10%"></div>
<a href="/docs">10%</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
NOTE: 报告小部件通过访问页面时的 AJAX 请求加载 - 它们不会立即在页面上可用。这意味着内联
<script>
标签将不起作用。看更新部分 有关在 AJAX 请求后处理部分 JavaScript 的更多信息。
报告小部件属性
报告小部件可能具有用户可以使用检查器管理的属性:
属性应该在defineProperties
小部件类的方法。这些属性在组件文章.例子:
public function defineProperties()
{
return [
'title' => [
'title' => 'Widget title',
'default' => 'Top Pages',
'type' => 'string',
'validationPattern' => '^.+$',
'validationMessage' => 'The Widget Title is required.'
],
'days' => [
'title' => 'Number of days to display data for',
'default' => '7',
'type' => 'string',
'validationPattern' => '^[0-9]+$'
]
];
}
报告小部件注册
插件可以通过覆盖registerReportWidgets
里面的方法插件注册类.该方法应返回一个数组,其中包含键中的小部件类和值中的小部件配置(标签、上下文和所需权限)。例子:
public function registerReportWidgets()
{
return [
'Winter\GoogleAnalytics\ReportWidgets\TrafficOverview' => [
'label' => 'Google Analytics traffic overview',
'context' => 'dashboard',
'permissions' => [
'winter.googleanalytics.widgets.traffic_overview',
],
],
'Winter\GoogleAnalytics\ReportWidgets\TrafficSources' => [
'label' => 'Google Analytics traffic sources',
'context' => 'dashboard',
'permissions' => [
'winter.googleanaltyics.widgets.traffic_sources',
],
]
];
}
这label
元素定义添加小部件弹出窗口的小部件名称。这context
元素定义可以使用小部件的上下文。 Winter 的报表小部件系统允许在任何页面上托管报表容器,并且容器上下文名称是唯一的。 Dashboard 页面上的小部件容器使用dashboard
语境。