Виджеты
Виджеты — это повторно используемые строительные блоки, используемые в представлениях для создания сложных и настраиваемых элементов пользовательского интерфейса объектно-ориентированным способом. Например, виджет выбора даты может генерировать изящный календарь выбора даты, который позволяет пользователям выбрать дату в качестве ввода. Всё, что вам нужно сделать, это просто вставить код в представление, как показано ниже:
<?php use yii\jui\DatePicker; ?> <?= DatePicker::widget(['name' => 'date']) ?>
В Yii имеется большое количество встроенных виджетов, таких как активная форма, меню, виджеты jQuery UI, виджеты Twitter Bootstrap. В дальнейшем мы рассмотрим основные знания о виджетах. Если вы хотите узнать об использовании определенного виджета, обратитесь к документации API класса.
Использование виджетов
Виджеты в основном используются в представлениях. Вы можете вызвать метод yii\base\Widget::widget() для использования виджета в представлении. Этот метод принимает массив настроек для инициализации виджета и возвращает результат рендеринга виджета. Например, следующий код вставляет виджет выбора даты, настроенный для использования русского языка и сохранения ввода в атрибуте from_date объекта $model.
<?php
use yii\jui\DatePicker;
?>
<?= DatePicker::widget([
'model' => $model,
'attribute' => 'from_date',
'language' => 'ru',
'dateFormat' => 'php:Y-m-d',
]) ?>
Некоторые виджеты могут принимать блок содержимого, который должен быть заключён между вызовами yii\base\Widget::begin() и yii\base\Widget::end(). Например, следующий код использует виджет yii\widgets\ActiveForm для создания формы входа. Виджет сгенерирует открывающие и закрывающие <form> теги в месте вызова begin() и end() соответственно. Всё, что находится между ними, будет отображено как есть.
<?php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
?>
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<div class="form-group">
<?= Html::submitButton('Login') ?>
</div>
<?php ActiveForm::end(); ?>
Обратите внимание, что в отличие от yii\base\Widget::widget(), который возвращает результат рендеринга виджета, метод yii\base\Widget::begin() возвращает экземпляр виджета, который можно использовать для построения содержимого виджета.
Примечание: Некоторые виджеты будут использовать буферизацию вывода, чтобы скорректировать заключенное содержимое при вызове yii\base\Widget::end(). По этой причине вызов yii\base\Widget::begin() и yii\base\Widget::end() ожидается в одном файле представления. Несоблюдение этого правила может привести к неожиданному результату.
Настройка глобальных параметров
Глобальные параметры для типа виджета можно настроить через контейнер DI:
\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);
Подробнее см. "Практическое применение" в руководстве по контейнерам зависимостей.
Создание виджетов
Для создания виджета необходимо расширить yii\base\Widget и переопределить методы yii\base\Widget::init() и/или yii\base\Widget::run(). Обычно метод init() должен содержать код, который нормализует свойства виджета, а метод run() должен содержать код, который генерирует результат рендеринга виджета. Результат рендеринга может быть непосредственно "выведен" или возвращен как строка методом run().
В следующем примере HelloWidget кодирует и отображает содержимое, назначенное свойству message. Если свойство не задано, по умолчанию отображается "Привет, мир".
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(), кодирует его и отображает.
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);
}
}
Как видно, буфер вывода PHP запускается в init() , чтобы любой вывод между вызовами init() и run() можно было захватить, обработать и вернуть в run().
Информация: При вызове 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() для настройки каталога, содержащего файлы представлений виджета.
Рекомендации по лучшим практикам
Виджеты — это объектно-ориентированный способ повторного использования кода представления.
При создании виджетов необходимо придерживаться шаблона MVC. В общем случае логика должна храниться в классах виджетов, а представление — в представлениях.
Виджеты должны быть самодостаточными. То есть при использовании виджета вы должны иметь возможность просто поместить его в представление, не выполняя никаких других действий. Это может быть непросто, если виджет требует внешних ресурсов, таких как CSS, JavaScript, изображения и т. д. К счастью, Yii предоставляет поддержку пакетов ресурсов, которые можно использовать для решения этой проблемы.
Если виджет содержит только код представления, он очень похож на представление. На самом деле, в этом случае их единственное различие заключается в том, что виджет — это перераспределяемый класс, а представление — это просто обычный PHP-скрипт, который вы предпочитаете хранить внутри приложения.
© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc-2.0/guide-structure-widgets.html