diff --git a/docs/guide-ru/structure-widgets.md b/docs/guide-ru/structure-widgets.md new file mode 100644 index 0000000..41ce7b9 --- /dev/null +++ b/docs/guide-ru/structure-widgets.md @@ -0,0 +1,201 @@ +Виджеты +======= + +Виджеты представляют собой многоразовые строительные блоки, используемые в [представлениях](structure-views.md) +для создания сложных и настраиваемых элементов пользовательского интерфейса в рамках объектно-ориентированного +подхода. Например, виджет выбора даты (date picker) позволяет генерировать интерактивный интерфейс для выбора дат, +предоставляя пользователям приложения удобный способ для ввода данных такого типа. Все, что нужно для +подключения виджета - это добавить следующий код в представление: + +```php + + 'date']) ?> +``` + +В комплект Yii входит большое количество виджетов, например: [[yii\widgets\ActiveForm|active form]], +[[yii\widgets\Menu|menu]], [виджеты jQuery UI](widget-jui.md), [виджеты Twitter Bootstrap](widget-bootstrap.md). +Далее будут представлены базовые сведения о виджетах. Для получения сведений относительно использования +конкретного виджета, следует обратиться к документации соответствующего класса. + + +## Использование Виджетов + +Главным образом, виджеты применяют в [представлениях](structure-views.md). Для того, чтобы использовать виджет +в представлении, достаточно вызвать метод [[yii\base\Widget::widget()]]. Метод принимает массив [настроек](concept-configurations.md) +для инициализации виджета и возвращает результат его рендеринга. Например, следующий +код добавляет виджет для выбора даты, сконфигурированный для использования русского в качестве языка интерфейса +виджета и хранения вводимых данных в атрибуте `from_date` модели `$model`. + +```php + + $model, + 'attribute' => 'from_date', + 'language' => 'ru', + 'clientOptions' => [ + 'dateFormat' => 'yy-mm-dd', + ], +]) ?> +``` + +Некоторые виджеты могут иметь внутреннее содержимое, которое следует располагать между вызовами методов +[[yii\base\Widget::begin()]] и [[yii\base\Widget::end()]]. Например, для генерации формы входа, в следующем +фрагменте кода используется виджет [[yii\widgets\ActiveForm]]. Этот виджет сгенерирует открывающий и закрывающий +тэги `
` в местах вызова методов `begin()` и `end()` соответственно. При этом, содержимое, расположенное +между вызовами указанных методов будет выведено без каких-либо изменений. + +```php + + + 'login-form']); ?> + + field($model, 'username') ?> + + field($model, 'password')->passwordInput() ?> + +
+ +
+ + +``` + +Обратите внимание на то, что в отличие от метода [[yii\base\Widget::widget()]], который возвращает результат +рендеринга, метод [[yii\base\Widget::begin()]] возвращает экземпляр виджета, который может быть +использован в дальнейшем для формирования его внутреннего содержимого. + + +## Создание Виджетов + +Для того, чтобы создать виджет, следует унаследовать класс [[yii\base\Widget]] и переопределить методы +[[yii\base\Widget::init()]] и/или [[yii\base\Widget::run()]]. Как правило, метод `init()` должен содержать +код, выполняющий нормализацию свойств виджета, а метод `run()` - код, возвращающий результат рендеринга виджета. +Результат рендеринга может быть выведен непосредственно с помощью конструкции "echo" или же возвращен +в строке методом `run()`. + +В следующем примере, виджет `HelloWidget` HTML-кодирует и отображает содержимое, присвоенное свойству `message`. +В случае, если указанное свойство не установлено, виджет, в качестве значения по умолчанию отобразит строку "Hello World". + +```php +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 + + 'Good morning']) ?> +``` + +Ниже представлен вариант виджета `HelloWidget`, который принимает содержимое, обрамленное вызовами методов +`begin()` и `end()`, HTML-кодирует его и выводит. + +```php +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()`. + +> Информация: При вызове метода [[yii\base\Widget::begin()]] будет создан новый экземпляр виджета, при этом +вызов метода `init()` произойдет сразу после выполнения остального кода в конструкторе виджета. +При вызове метода [[yii\base\Widget::end()]], будет вызван метод `run()`, а возвращенное им значение будет выведено +методом `end()`. + +Следующий фрагмент кода содержит пример использования модифицированного варианта `HelloWidget`: + +```php + + + + content that may contain 's + + +``` + +В некоторых случаях, виджету может потребоваться вывести крупный блок содержимого. И хотя это содержимое может +быть встроено непосредственно в метод `run()`, целесообразней поместить его в [представление](structure-views.md) +и вызвать метод [[yii\base\Widget::render()]] для его рендеринга. Например, + +```php +public function run() +{ + return $this->render('hello'); +} +``` + +По умолчанию, файлы представлений виджетов должны находиться в директории `WidgetPath/views`, где `WidgetPath` - +директория, содержащая файл класса виджета. Таким образом, в приведенном выше примере, для виджета будет +использован файл представления `@app/components/views/hello.php`, при этом файл с классом виджета расположен в +`@app/components`. Для того, что бы изменить директорию, в которой содержатся файлы-представления для виджета, +следует переопределить метод [[yii\base\Widget::getViewPath()]]. + + +## Лучшие Практики + +Виджеты представляют собой объектно-ориентированный подход к повторному использованию кода пользовательского +интерфейса. + +При создании виджетов, следует придерживаться основных принципов концепции MVC. В общем случае, основную логику +следует располагать в классе виджета, разделяя при этом код, отвечающий за разметку в [представления](structure-views.md). + +Разрабатываемые виджеты должны быть самодостаточными. Это означает, что для их использования должно быть +достаточно всего лишь добавить виджет в представление. Добиться этого бывает затруднительно в том случае, +когда для его функционирования требуются внешние ресурсы, такие как CSS, JavaScript, изображения и т.д. +К счастью, Yii предоставляет поддержку механизма для работы с ресурсами [asset bundles](structure-asset-bundles.md), +который может быть успешно использован для решения данной проблемы. + +В случае, когда виджет не содержит логики, а содержит только код, отвечающий за вывод разметки, он мало +отличается от [представления](structure-views.md). В действительности, единственное его отличие состоит в том, что +виджет представляет собой отдельный и удобный для распространения класс, в то время как представление - это +обычный PHP скрипт, подходящий для использования только лишь в конретном приложении. \ No newline at end of file