Создание Виджетов
Для того, чтобы создать виджет, следует унаследовать класс [[yii\base\Widget]] и переопределить методы [[yii\base\Widget::init()]] и/или [[yii\base\Widget::run()]]. Как правило, метод init()
должен содержать код, выполняющий нормализацию свойств виджета, а метод run()
- код, возвращающий результат рендеринга виджета. Результат рендеринга может быть выведен непосредственно с помощью конструкции "echo" или же возвращен в строке методом run()
.
В следующем примере, виджет HelloWidget
HTML-кодирует и отображает содержимое, присвоенное свойству message
. В случае, если указанное свойство не установлено, виджет, в качестве значения по умолчанию отобразит строку "Hello World".
namespace app\components;
use yii\base\Widget;
use yii\helpers\Html;
class HelloWidget extends Widget
{
public $message;
public function init()
{
parent::init();
if ($this->message === null) {
$this->message = 'Hello World';
}
}
public function run()
{
return Html::encode($this->message);
}
}
Для того, чтобы использовать этот виджет, достаточно добавить в представление следующий код:
<?php
use app\components\HelloWidget;
?>
<?= HelloWidget::widget(['message' => 'Good morning']) ?>
Ниже представлен вариант виджета HelloWidget
, который принимает содержимое, обрамленное вызовами методов begin()
и end()
, HTML-кодирует его и выводит.
namespace app\components;
use yii\base\Widget;
use yii\helpers\Html;
class HelloWidget extends Widget
{
public function init()
{
parent::init();
ob_start();
}
public function run()
{
$content = ob_get_clean();
return Html::encode($content);
}
}
Как Вы можете видеть, в методе init()
происходит включение буферизации вывода PHP таким образом, что весь вывод между вызовами init()
и run()
может быть перехвачен, обработан и возвращен в run()
.
Info: При вызове метода [[yii\base\Widget::begin()]] будет создан новый экземпляр виджета, при этом вызов метода
init()
произойдет сразу после выполнения остального кода в конструкторе виджета. При вызове метода [[yii\base\Widget::end()]], будет вызван методrun()
, а возвращенное им значение будет выведено методомend()
.
Следующий фрагмент кода содержит пример использования модифицированного варианта HelloWidget
:
<?php
use app\components\HelloWidget;
?>
<?php HelloWidget::begin(); ?>
content that may contain <tag>'s
<?php HelloWidget::end(); ?>
В некоторых случаях, виджету может потребоваться вывести крупный блок содержимого. И хотя это содержимое может быть встроено непосредственно в метод run()
, целесообразней поместить его в представление и вызвать метод [[yii\base\Widget::render()]] для его рендеринга. Например,
public function run()
{
return $this->render('hello');
}
По умолчанию, файлы представлений виджетов должны находиться в директории WidgetPath/views
, где WidgetPath
- директория, содержащая файл класса виджета. Таким образом, в приведенном выше примере, для виджета будет использован файл представления @app/components/views/hello.php
, при этом файл с классом виджета расположен в @app/components
. Для того, чтобы изменить директорию, в которой содержатся файлы-представления для виджета, следует переопределить метод [[yii\base\Widget::getViewPath()]].