mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-01 03:26:36 +08:00 
			
		
		
		
	 0041f034fd
			
		
	
	0041f034fd
	
	
	
		
			
			* Replace https://secure.php.net with https://www.php.net * Replace http://www.php.net with https://www.php.net
		
			
				
	
	
		
			221 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| Widgets
 | |
| =======
 | |
| 
 | |
| Los _widgets_ son bloques de código reutilizables que se usan en las [vistas](structure-views.md)
 | |
| para crear elementos de interfaz de usuario complejos y configurables, de forma orientada a objetos.
 | |
| Por ejemplo, un _widget_ de selección de fecha puede generar un selector de fechas bonito que
 | |
| permita a los usuarios seleccionar una fecha.  Todo lo que hay que hacer es insertar el siguiente
 | |
| código en una vista:
 | |
| 
 | |
| ```php
 | |
| <?php
 | |
| use yii\jui\DatePicker;
 | |
| ?>
 | |
| <?= DatePicker::widget(['name' => 'date']) ?>
 | |
| ```
 | |
| 
 | |
| Yii incluye un buen número de _widgets_, tales como
 | |
| [[yii\widgets\ActiveForm|formulario activo]],
 | |
| [[yii\widgets\Menu|menú]],
 | |
| [_widgets_ de jQuery UI](https://www.yiiframework.com/extension/yiisoft/yii2-jui), y
 | |
| [_widgets_ de Twitter Bootstrap](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap).
 | |
| A continuación presentaremos las nociones básicas de de los _widgets_.  Por favor, refiérase a la
 | |
| documentación de la API de clases si quiere aprender más acerca del uso de un _widget_ en particular.
 | |
| 
 | |
| 
 | |
| ## Uso de los _widgets_ <span id="using-widgets"></span>
 | |
| 
 | |
| Los _widgets_ se usan 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 toma un _array_ de
 | |
| [configuración](concept-configurations.md) para inicializar el _widget_ y devuelve la representación
 | |
| resultante del _widget_.  Por ejemplo, el siguiente código inserta un _widget_ de selección de fecha
 | |
| configurado para usar el idioma ruso y guardar la selección en el atributo `from_date` de `$model`.
 | |
| 
 | |
| ```php
 | |
| <?php
 | |
| use yii\jui\DatePicker;
 | |
| ?>
 | |
| <?= DatePicker::widget([
 | |
|     'model' => $model,
 | |
|     'attribute' => 'from_date',
 | |
|     'language' => 'ru',
 | |
|     'dateFormat' => 'php:Y-m-d',
 | |
| ]) ?>
 | |
| ```
 | |
| 
 | |
| 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 se llame a `begin()` y `end()`
 | |
| respectivamente. Cualquier cosa que este en medio se representará tal cual.
 | |
| 
 | |
| ```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_.
 | |
| 
 | |
| > Nota: Algunos _widgets_ utilizan un [búfer de salida](https://www.php.net/manual/es/book.outcontrol.php)
 | |
| > para ajustar el contenido rodeado al invocar [[yii\base\Widget::end()]].  Por este motivo se espera
 | |
| > que las llamadas a [[yii\base\Widget::begin()]] y [[yii\base\Widget::end()]] tengan lugar en el
 | |
| > mismo fichero de vista.
 | |
| > No seguir esta regla puede desembocar en una salida distinta a la esperada.
 | |
| 
 | |
| 
 | |
| ### Configuración de las variables globales predefinidas
 | |
| 
 | |
| Las variables globales predefinidas de un _widget_ se pueden configurar por medio del contenedor
 | |
| de inyección de dependencias:
 | |
| 
 | |
| ```php
 | |
| \Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);
 | |
| ```
 | |
| 
 | |
| Consulte la [sección "Uso práctico" de la Guía del contenedor de inyección de dependencias](concept-di-container.md#practical-usage) para más detalles.
 | |
| 
 | |
| 
 | |
| ## Creación de _widgets_ <span id="creating-widgets"></span>
 | |
| 
 | |
| Para crear un _widget_, extienda la clase [[yii\base\Widget]] y sobrescriba 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 inicializa las propiedades del _widget_, mientras que el método `run()`
 | |
| debería contener el código que genera la representación resultante del _widget_.  La representación
 | |
| resultante del método `run()` puede pasarse directamente a `echo` o devolverse como una cadena.
 | |
| 
 | |
| 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 omisión.
 | |
| 
 | |
| ```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` que toma el contenido insertado entre las llamadas a
 | |
| `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 de PHP es iniciado en `init()` para que toda salida
 | |
| entre las llamadas de `init()` y `run()` puede ser capturada, procesada y devuelta en `run()`.
 | |
| 
 | |
| > Info: Cuando llame a [[yii\base\Widget::begin()]], se creará una nueva instancia del _widget_ y se
 | |
| > llamará a su método `init()` al final del constructor del _widget_.  Cuando llame a
 | |
| > [[yii\base\Widget::end()]], se invocará el método `run()` y el resultado que devuelva será pasado
 | |
| > a `echo` por `end()`.
 | |
| 
 | |
| El siguiente código muestra cómo usar esta nueva variante de `HelloWidget`:
 | |
| 
 | |
| ```php
 | |
| <?php
 | |
| use app\components\HelloWidget;
 | |
| ?>
 | |
| <?php HelloWidget::begin(); ?>
 | |
| 
 | |
|     contenido que puede contener <etiqueta>s
 | |
| 
 | |
| <?php HelloWidget::end(); ?>
 | |
| ```
 | |
| 
 | |
| A veces, un _widget_ puede necesitar representar un gran bloque de contenido.  Aunque que se
 | |
| podría incrustar el contenido dentro del método `run()`, es preferible ponerlo dentro de una
 | |
| [vista](structure-views.md) y llamar al método [[yii\base\Widget::render()]] para representarlo.
 | |
| Por ejemplo:
 | |
| 
 | |
| ```php
 | |
| public function run()
 | |
| {
 | |
|     return $this->render('hello');
 | |
| }
 | |
| ```
 | |
| 
 | |
| Por omisión, 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 ejemplo anterior representará el fichero de vista
 | |
| `@app/components/views/hello.php`, suponiendo 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 contiene los ficheros de vista del _widget_.
 | |
| 
 | |
| 
 | |
| ## Buenas prácticas <span id="best-practices"></span>
 | |
| 
 | |
| Los _widgets_ son una manera orientada a objetos de reutilizar código de las vistas.
 | |
| 
 | |
| Al crear _widgets_, debería continuar suguiendo el patrón MVC.  En general, se debería mantener la
 | |
| lógica en las clases del widget y la presentación en las [vistas](structure-views.md).
 | |
| 
 | |
| Los _widgets_ deberían diseñarse para ser autosuficientes.  Es decir, cuando se use un _widget_, se
 | |
| debería poder ponerlo 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 [paquetes de recursos](structure-asset-bundles.md) (_asset bundles_)
 | |
| que se pueden utilizar para resolver este problema.
 | |
| 
 | |
| Cuando un _widget_ sólo contiene código de vista, 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 simple script PHP que prefiere mantener dentro de su aplicación.
 |