|
|
|
Widgets
|
|
|
|
=======
|
|
|
|
|
|
|
|
Los Widgets son bloques de código reutilizables utilizados en las [vistas](structure-views.md) para crear elementos de
|
|
|
|
interfaz de usuario complejos y configurables de forma orientada a objetos. Por ejemplo, widget DatePicker puede
|
|
|
|
generar un DatePicker de lujo que permita a los usuarios seleccionar una fecha. Todo lo que se tiene que hacer es
|
|
|
|
insertar el siguiente código en una vista.
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
use yii\jui\DatePicker;
|
|
|
|
?>
|
|
|
|
<?= DatePicker::widget(['name' => 'date']) ?>
|
|
|
|
```
|
|
|
|
|
|
|
|
Hay un buen número de widgets incluidos en Yii, tales como [[yii\widgets\ActiveForm|active form]],
|
|
|
|
[[yii\widgets\Menu|menu]], [Widgets de jQuery UI](widget-jui.md), [widgets de Twitter Bootstrap](widget-bootstrap.md).
|
|
|
|
En adelante, introduciremos las nociones básicas acerca de los widgets. Por favor, refiérase a la documentación de la
|
|
|
|
API de clases si quiere aprender más acerca de el uso de un widget en particular.
|
|
|
|
|
|
|
|
## Uso de los Widgets <a name="using-widgets"></a>
|
|
|
|
|
|
|
|
Los Widgets son usados principalmente en las [vistas](structure-views.md). Se puede llamar al método
|
|
|
|
[[yii\base\Widget::widget()]] para usar un widget en una vista. El método obtiene un array de
|
|
|
|
[configuración](concept-configurations.md) para inicializar el widget y retorna la representación resultante del
|
|
|
|
widget. Por ejemplo, el siguiente código inserta un widget DatePicker que esta configurado para usar el idioma Ruso y
|
|
|
|
mantener la entrada en atributo 'form_date' del '$model'.
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
use yii\jui\DatePicker;
|
|
|
|
?>
|
|
|
|
<?= DatePicker::widget([
|
|
|
|
'model' => $model,
|
|
|
|
'attribute' => 'from_date',
|
|
|
|
'language' => 'ru',
|
|
|
|
'clientOptions' => [
|
|
|
|
'dateFormat' => 'yy-mm-dd',
|
|
|
|
],
|
|
|
|
]) ?>
|
|
|
|
```
|
|
|
|
|
|
|
|
Algunos widgets pueden coger un bloque de contenido que debería encontrarse entre la invocación de
|
|
|
|
[[yii\base\Widget::begin()]] y [[yii\base\Widget::end()]]. Por ejemplo, el siguiente código usa el widget
|
|
|
|
[[yii\widgets\ActiveForm]] para generar un formulario de inicio de sesión. El widget generará las etiquetas '<form>'
|
|
|
|
de apertura y cierre donde sean llamados 'begin()' y 'end()', respectivamente. Cualquier cosa que este en medio será
|
|
|
|
representado como tal.
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?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(); ?>
|
|
|
|
```
|
|
|
|
|
|
|
|
Hay que tener en cuenta que a diferencia de [[yii\base\Widget::widget()]] que devuelve la representación resultante
|
|
|
|
del widget, el método [[yii\base\Widget::begin()]] devuelve una instancia del widget que se puede usar para generar el
|
|
|
|
contenido del widget.
|
|
|
|
|
|
|
|
## Creación Widgets <a name="creating-widgets"></a>
|
|
|
|
|
|
|
|
Para crear un widget, se debe extender a [[yii\base\Widget]] y sobrescribir los métodos [[yii\base\Widget::init()]]
|
|
|
|
y/o [[yii\base\Widget::run()]]. Normalmente el método 'init()' debería contener el código que estandariza las
|
|
|
|
propiedades del widget, mientras que el método 'run()' debería contener el código que genere la representación
|
|
|
|
resultante del widget. La representación resultante puede ser "pintada" directamente o devuelta como una cadena por el
|
|
|
|
método 'run()'.
|
|
|
|
|
|
|
|
En el siguiente ejemplo, 'HelloWidget' codifica en HTML y muestra el contenido asignado a su propiedad 'message'. Si
|
|
|
|
la propiedad no está establecida, mostrará "Hello World" por defecto.
|
|
|
|
|
|
|
|
```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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Para usar este widget, simplemente inserte el siguiente código en una vista:
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
use app\components\HelloWidget;
|
|
|
|
?>
|
|
|
|
<?= HelloWidget::widget(['message' => 'Good morning']) ?>
|
|
|
|
```
|
|
|
|
|
|
|
|
Abajo se muestra una variante de 'HelloWidget' obtiene el contenido entre las llamadas 'begin()' y 'end()', lo
|
|
|
|
codifica en HTML y posteriormente lo muestra.
|
|
|
|
|
|
|
|
```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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Como se puede observar, el búfer de salida PHP es iniciado en 'init()' por tanto cualquier salida entre las llamadas
|
|
|
|
de 'init()' y 'run()' puede ser capturada, procesada y devuelta en 'run()'.
|
|
|
|
|
|
|
|
> Info: Cuando se llama a [[yii\base\Widget::begin()]], se creará una nueva instancia del widget y el método 'init()'
|
|
|
|
será llamado al final del constructor del widget. Cuando se llama [[yii\base\Widget::end()]], el método 'run()' será
|
|
|
|
llamado el resultado que devuelva será escrito por 'end()'.
|
|
|
|
|
|
|
|
El siguiente código muestra como usar esta nueva variante de 'HelloWidget':
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
use app\components\HelloWidget;
|
|
|
|
?>
|
|
|
|
<?php HelloWidget::begin(); ?>
|
|
|
|
|
|
|
|
content that may contain <tag>'s
|
|
|
|
|
|
|
|
<?php HelloWidget::end(); ?>
|
|
|
|
```
|
|
|
|
|
|
|
|
A veces, un widget puede necesitar representar una gran cantidad de contenido. Mientras que se puede incrustar el
|
|
|
|
contenido dentro del método 'run()', ponerlo dentro de una [vista](structure-views.md) y llamar
|
|
|
|
[[yii\base\Widget::render()]] para representarla, es un mejor enfoque. Por ejemplo:
|
|
|
|
|
|
|
|
```php
|
|
|
|
public function run()
|
|
|
|
{
|
|
|
|
return $this->render('hello');
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Por defecto, las vistas para un widget deberían encontrarse en ficheros dentro del directorio 'WidgetPath/views',
|
|
|
|
donde 'WidgetPath' representa el directorio que contiene el fichero de clase del widget. Por lo tanto, el anterior
|
|
|
|
ejemplo representará el fichero de la vista `@app/components/views/hello.php`, asumiendo que la clase del widget se
|
|
|
|
encuentre en `@app/components`. Se puede sobrescribir el método [[yii\base\Widget::getViewPath()]] para personalizar
|
|
|
|
el directorio que contenga los ficheros de la vista del widget.
|
|
|
|
|
|
|
|
## Mejores Prácticas <a name="best-practices"></a>
|
|
|
|
|
|
|
|
Los widgets son una manera orientada a objetos de reutilizar código de las vistas.
|
|
|
|
|
|
|
|
Cuando se crean widgets, se debería continuar manteniendo el patrón MVC. En general, se debería mantener la lógica en
|
|
|
|
las clases del widget y mantener la presentación en las [vistas](structure-views.md).
|
|
|
|
|
|
|
|
Los widgets deberían ser diseñados para ser autónomos. Es decir, cuando se usa un widget, se debería poder poner en
|
|
|
|
una vista sin hacer nada más. Esto puede resultar complicado si un widget requiere recursos externos, tales como CSS,
|
|
|
|
JavaScript, imágenes, etc. Afortunadamente Yii proporciona soporte para
|
|
|
|
[asset bundles](structure-asset-bundles.md) que pueden ser utilizados para resolver el problema.
|
|
|
|
|
|
|
|
Cuando un widget sólo contiene código de vista, este es muy similar a una [vista](structure-views.md). De hecho, en
|
|
|
|
este caso, su única diferencia es que un widget es una clase redistribuible, mientras que una vista es sólo un script
|
|
|
|
PHP llano que prefiere mantenerse dentro de su aplicación.
|