Commit b62d2c20 by Larnu

translate spanish docs

parent 169a2a39
Script de Entrada
=============
El script de entrada es el primer eslabón en el proceso de arranque de la aplicación. Una aplicación (ya sea una aplicación Web o una aplicación de consola) tiene un único script de entrada. Los usuarios finales hacen peticiones al script de entrada que instancia instancias de aplicación y remite la petición a estos.
El script de entrada para aplicaciones Web tiene que estar alojado bajo niveles de directorios accesibles para la Web de manera que puedan ser accesibles para los usuarios. Normalmente se nombra como 'index.php', pero también pueden usar cualquier otro nombre, los servidores Web proporcionados pueden localizarlo.
El script de entrada para aplicaciones de consola normalmente está alojado bajo la [ruta base](structure-applications.md#yiibaseapplicationbasepathbasepath-) de las aplicaciones y es nombrado como 'yii' (con el sufijo '.php'). Estos deberían ser ejecutables para que los usuarios puedan ejecutar las aplicaciones de consola a través del comando './yii <ruta> [argumentos] [opciones]'.
El script de entrada principalmente hace los siguientes trabajos:
* Definir las constantes globales;
* Registrar el [cargador automático de Composer](http://getcomposer.org/doc/01-basic-usage.md#autoloading);
* Incluir el archivo de clase [[Yii]];
* Cargar la configuración de la aplicación;
* Crear y configurar una instancia de [aplicación](structure-applications.md);
* Llamar a [[yii\base\Application::run()]] para procesar la petición entrante.
## Aplicaciones Web <a name="web-applications"></a>
El siguiente código es el script de entrada para la [Plantilla de Aplicación web Básica](start-installation.md).
```php
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
// registrar el cargador automático de Composer
require(__DIR__ . '/../vendor/autoload.php');
// incluir el fichero de clase Yii
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
// cargar la configuración de la aplicación
$config = require(__DIR__ . '/../config/web.php');
// crear, configurar y ejecutar la aplicación
(new yii\web\Application($config))->run();
```
## Aplicaciones de consola <a name="console-applications"></a>
De la misma manera, el siguiente código es el script de entrada para la [aplicación de consola](tutorial-console.md):
```php
#!/usr/bin/env php
<?php
/**
* Yii console bootstrap file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
defined('YII_DEBUG') or define('YII_DEBUG', true);
// el fcgi no tiene STDIN y STDOUT definidos por defecto
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w'));
// registrar el cargador automático de Composer
require(__DIR__ . '/vendor/autoload.php');
// incluir el fichero de clase Yii
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
// cargar la configuración de la aplicación
$config = require(__DIR__ . '/config/console.php');
$application = new yii\console\Application($config);
$exitCode = $application->run();
exit($exitCode);
```
## Definición de Constantes <a name="defining-constants"></a>
El script de entrada es el mejor lugar para definir constantes globales. Yii soporta las siguientes tres constantes:
* `YII_DEBUG`: especifica si la aplicación se está ejecutando en modo depuración. Cuando esta en modo depuración, una aplicación mantendrá más información de registro, y revelará detalladas pilas de errores si se lanza una excepción. Por esta razón, el modo depuración debería ser usado principalmente durante el desarrollo. El valor por defecto de 'YII_DEBUG' es falso.
* `YII_ENV`: especifica en que entorno se esta ejecutando la aplicación. Se puede encontrar una descripción más detallada en la sección [Configuraciones](concept-configurations.md#environment-constants).
El Valor por defecto de 'YII_ENV' es ''prod'', que significa que la aplicación se esta ejecutando en el entorno de producción.
* `YII_ENABLE_ERROR_HANDLER`: especifica si se habilita el gestor de errores proporcionado por Yii. El valor por defecto de esta constante es verdadero.
Cuando se define una constante, a menudo se usa código como el siguiente:
```php
defined('YII_DEBUG') or define('YII_DEBUG', true);
```
que es equivalente al siguiente código:
```php
if (!defined('YII_DEBUG')) {
define('YII_DEBUG', true);
}
```
Claramente el primero es más breve y fácil de entender.
La definición de constantes debería hacerse al principio del script de entrada para que pueda tener efecto cuando se incluyan otros archivos PHP.
Filtros
======
Los Filtros son objetos que se ejecutan antes y/o después de las [acciones de controlador](structure-controllers.md#actions). Por ejemplo, un filtro de control de acceso puede ejecutarse antes de las acciones para asegurar que un usuario final tiene permitido acceder a estas; un filtro de compresión de contenido puede ejecutarse después de las acciones para comprimir el contenido de la respuesta antes de ser enviado al usuario final.
Un filtro puede consistir en un pre-filtro(lógica de filtrado aplicada *antes* de las acciones) y/o un post-filtro(lógica de filtro aplicada *después* de las acciones).
## Uso de Filtros <a name="using-filters"></a>
Los filtros son esencialmente un tipo especial de [comportamientos](concept-behaviors.md).
Por lo tanto, usar filtros es lo mismo que [uso de comportamientos](concept-behaviors.md#attaching-behaviors). Se pueden declarar los filtros en una clase controlador sobrescribiendo el método [[yii\base\Controller::behaviors()|behaviors()]] como en el siguiente ejemplo:
```php
public function behaviors()
{
return [
[
'class' => 'yii\filters\HttpCache',
'only' => ['index', 'view'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('user')->max('updated_at');
},
],
];
}
```
Por defecto, los filtros declarados en una clase controlador, serán aplicados en *todas* las acciones de este controlador. Sin embargo, se puede especificar explícitamente en que acciones serán aplicadas configurando la propiedad [[yii\base\ActionFilter::only|only]]. En el anterior ejemplo, el filtro 'HttpCache' solo se aplica a las acciones 'index' y 'view'. También se puede configurar la propiedad [[yii\base\ActionFilter::except|except]] para prevenir que ciertas acciones sean filtradas.
Además de en los controladores, se pueden declarar filtros en [modulos](structure-modules.md) o [aplicaciones](structure-applications.md).
Una vez hecho, los filtros serán aplicados a *todas* las acciones de controlador que pertenezcan a ese modulo o aplicación, a menos que las propiedades [[yii\base\ActionFilter::only|only]] y [[yii\base\ActionFilter::except|except]] sean configuradas como se ha descrito anteriormente.
>Nota: Cuando se declaran filtros en módulos o aplicaciones, deben usarse [rutas](structure-controllers.md#routes) en lugar de identificadores de acciones en las propiedades [[yii\base\ActionFilter::only|only]] y [[yii\base\ActionFilter::except|except]].
Esto es debido a que los identificadores de acciones no pueden especificar acciones dentro del ámbito de un modulo o una aplicación por si mismos.
Cuando se configuran múltiples filtros para una misma acción, se aplican de acuerdo a las siguientes reglas:
* Pre-filtrado
- Aplica filtros declarados en la aplicación en orden de aparición en `behaviors()`.
- Aplica filtros declarados en el modulo en orden de aparición en `behaviors()`.
- Aplica filtros declarados en el controlador en orden de aparición en `behaviors()`.
- Si hay algún filtro que cancele la ejecución de la acción, los filtros(tanto pre-filtros como post-filtros) posteriores a este no serán aplicados.
* Ejecución de la acción si pasa el pre-filtro.
* Post-filtrado
- Aplica los filtros declarados en el controlador en el controlador en orden inverso al de aparición en `behaviors()`.
- Aplica los filtros declarados en el modulo en orden inverso al de aparición en `behaviors()`.
- Aplica los filtros declarados en la aplicación en orden inverso al de aparición en `behaviors()`.
##Creación de Filtros <a name="creating-filters"></a>
Para crear un nuevo filtro de acción, hay que extender a [[yii\base\ActionFilter]] y sobrescribir los métodos [[yii\base\ActionFilter::beforeAction()|beforeAction()]] y/o [[yii\base\ActionFilter::afterAction()|afterAction()]]. El primero será ejecutado antes de la acción mientras que el segundo lo hará una vez ejecutada la acción.
El valor devuelto por [[yii\base\ActionFilter::beforeAction()|beforeAction()]] determina si una acción debe ejecutarse o no. Si el valor es falso, los filtros posteriores a este serán omitidos y la acción no será ejecutada.
El siguiente ejemplo muestra un filtro que registra el tiempo de ejecución de una acción:
```php
namespace app\components;
use Yii;
use yii\base\ActionFilter;
class ActionTimeFilter extends ActionFilter
{
private $_startTime;
public function beforeAction($action)
{
$this->_startTime = microtime(true);
return parent::beforeAction($action);
}
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("Action '{$action->uniqueId}' spent $time second.");
return parent::afterAction($action, $result);
}
}
```
## Filtros del Núcleo <a name="core-filters"></a>
Yii proporciona una serie de filtros de uso general, que se encuentran principalmente en `yii\filters` namespace. En adelante introduciremos estos filtros brevemente.
### [[yii\filters\AccessControl|AccessControl]] <a name="access-control"></a>
AccessControl proporciona control de acceso simple basado en un conjunto de [[yii\filters\AccessControl::rules|rules]].
En concreto, antes de ejecutar una acción, AccessControl examinará la lista de reglas y encontrará la primera que concuerde con las actuales variables de contexto(tales como dirección IP de usuario, estado de inicio de sesión del usuario, etc.). La regla que concuerde dictara si se permite o deniega la ejecución de la acción solicitada. Si ninguna regla concuerda, el acceso será denegado.
El siguiente ejemplo muestra como habilitar el acceso a los usuarios autenticados a las acciones 'create' y 'update' mientras deniega a todos los otros usuarios el acceso a estas dos acciones.
```php
use yii\filters\AccessControl;
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['create', 'update'],
'rules' => [
// allow authenticated users
[
'allow' => true,
'roles' => ['@'],
],
// everything else is denied by default
],
],
];
}
```
Para conocer más detalles acerca del control de acceso en general, refiérase a la sección de [Autorización](security-authorization.md)
### Filtros del Método de Autenticación <a name="auth-method-filters"></a>
Los filtros del método de autenticación se usan para autenticar a un usuario utilizando varios métodos, tales como la [Autenticación de acceso básica HTTP](http://es.wikipedia.org/wiki/Autenticaci%C3%B3n_de_acceso_b%C3%A1sica), [Oauth 2](http://oauth.net/2/). Estas clases de filtros se encuentran en el espacio de nombres `yii\filters\auth`.
El siguiente ejemplo muestra como usar [[yii\filters\auth\HttpBasicAuth]] para autenticar un usuario usando un token de acceso basado en el método de Autenticación de acceso básica HTTP. Tenga en cuenta que para que esto funcione, la clase [[yii\web\User::identityClass|user identity class]] debe implementar el método [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] .
```php
use yii\filters\auth\HttpBasicAuth;
public function behaviors()
{
return [
'basicAuth' => [
'class' => HttpBasicAuth::className(),
],
];
}
```
Los filtros del método de autenticación se usan a menudo para implementar APIs RESTful. Para más detalles, por favor refiérase a la sección [Autenticación RESTful](rest-authentication.md).
[[yii\filters\ContentNegotiator|ContentNegotiator]]
El filtro ContentNegotiator da soporte a la negociación del formato de respuesta y a la negociación del idioma de la aplicación. Este determinara el formato de respuesta y/o el idioma examinando los parámetros 'GET' y 'Accept' del encabezado HTTP.
En el siguiente ejemplo, el filtro ContentNegotiator se configura para soportar los formatos de respuesta 'JSON' y 'XML', y los idiomas Ingles(Estados Unidos) y Alemán.
```php
use yii\filters\ContentNegotiator;
use yii\web\Response;
public function behaviors()
{
return [
[
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
'languages' => [
'en-US',
'de',
],
],
];
}
```
Los formatos de respuesta y los idiomas a menudo precisan ser determinados mucho antes durante el [ciclo de vida de la aplicación](structure-applications.md#application-lifecycle). Por esta razón, ContentNegotiator esta diseñado de tal manera que se pueda usar como componente de [bootstrapping](structure-applications.md#bootstrap) así como de filtro. Por ejemplo, ContentNegotiator se puede configurar en la configuración de la aplicación como en el siguiente ejemplo:
```php
use yii\filters\ContentNegotiator;
use yii\web\Response;
[
'bootstrap' => [
[
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
'languages' => [
'en-US',
'de',
],
],
],
];
```
> Info: En el caso que el tipo preferido de contenido y el idioma no puedan ser determinados por una petición, será utilizando el primer elemento de formato e idioma de la lista [[formats]] y [[lenguages]].
### [[yii\filters\HttpCache|HttpCache]] <a name="http-cache"></a>
HttpCache implementa un almacenamiento caché del lado del cliente utilizando las cabeceras HTTP 'Last-Modified' y 'Etag'. Por ejemplo:
```php
use yii\filters\HttpCache;
public function behaviors()
{
return [
[
'class' => HttpCache::className(),
'only' => ['index'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('user')->max('updated_at');
},
],
];
}
```
Para conocer más detalles acerca de HttpCache refiérase a la sección [almacenamiento caché HTTP](caching-http.md).
### [[yii\filters\PageCache|PageCache]] <a name="page-cache"></a>
PageCache implementa una caché por parte del servidor de paginas enteras. En el siguiente ejemplo, se aplica PageCache a la acción 'index' para generar una cache de la pagina entera durante 60 segundos como máximo o hasta que el contador de entradas de la tabla 'post' varíe. Tambien se encarga de almacenar diferentes versiones de la pagina dependiendo del idioma de la aplicación seleccionado.
```php
use yii\filters\PageCache;
use yii\caching\DbDependency;
public function behaviors()
{
return [
'pageCache' => [
'class' => PageCache::className(),
'only' => ['index'],
'duration' => 60,
'dependency' => [
'class' => DbDependency::className(),
'sql' => 'SELECT COUNT(*) FROM post',
],
'variations' => [
\Yii::$app->language,
]
],
];
}
```
Por favor refiérase a [Caché de Páginas](caching-page.md) para obtener más detalles acerca de como usar PageCache.
### [[yii\filters\RateLimiter|RateLimiter]] <a name="rate-limiter"></a>
RateLimiter implementa un algoritmo de para limitar la tasa de descarga basándose en (leaky bucket algorithm)[http://en.wikipedia.org/wiki/Leaky_bucket]. Este se utiliza sobre todo en la implementación de APIs RESTful. Por favor, refiérase a la seccion (limite de tasa)[rest-rate-limiting.md] para obtener más detalles acerda de el uso de este filtro.
### [[yii\filters\VerbFilter|VerbFilter]] <a name="verb-filter"></a>
VerbFilter comprueba que los métodos de las peticiones HTTP estén permitidas para las acciones solicitadas. Si no están permitidas, lanzara una excepción de tipo HTTP 405. En el siguiente ejemplo, se declara VerbFilter para especificar el conjunto típico métodos de petición permitidos para acciones CRUD.
```php
use yii\filters\VerbFilter;
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
'view' => ['get'],
'create' => ['get', 'post'],
'update' => ['get', 'put', 'post'],
'delete' => ['post', 'delete'],
],
],
];
}
```
### [[yii\filters\Cors|Cors]] <a name="cors"></a>
(CORS)[https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS] es un mecanismo que permite a diferentes recursos (por ejemplo: fuentes, JavaScript, etc) de una pagina Web ser solicitados por otro dominio diferente al dominio que esta haciendo la petición. En particular las llamadas AJAX de JavasCript pueden utilizar el mecanismo XMLHttpRequest. De otro modo esta petición de dominio cruzado seria prohibida por los navegadores Web, por la misma pollita de seguridad de origen. CORS establece la manera en que el navegador y el servidor pueden interaccionar para determinar si se permite o no la petición de dominio cruzado.
El filtro [[yii\filters\Cors|Cors filter]] puede ser definido antes de los filtros Autenticación / Autorización para asegurar que las cabeceras de CORS siempre serán enviadas.
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
],
], parent::behaviors());
}
```
El filtrado CORS puede ser ajustado utilizando la propiedad 'cors'.
* `cors['Origin']`: array utilizado para definir los origenes permitidos. Puede ser `['*']` (everyone) o `['http://www.myserver.net', 'http://www.myotherserver.com']`. Por defecto `['*']`.
* `cors['Access-Control-Request-Method']`: array de los verbos permitidos como `['GET', 'OPTIONS', 'HEAD']`. Por defecto `['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']`.
* `cors['Access-Control-Request-Headers']`: array de las cabeceras permitidas. Puede ser `['*']` todas las cabeceras o algunas especificas `['X-Request-With']`. Por defecto `['*']`.
* `cors['Access-Control-Allow-Credentials']`: define si la petición actual puede hacer uso de credenciales. Puede ser `true`, `false` o `null` (not set). Por defecto `null`.
* `cors['Access-Control-Max-Age']`: define el tiempo de vida del la petición pref-flight. Por defecto `86400`.
Por ejemplo, habilitar CORS para el origen: `http://www.myserver.net` con metodos `GET`, `HEAD` y `OPTIONS` :
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
'cors' => [
'Origin' => ['http://www.myserver.net'],
'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
],
],
], parent::behaviors());
}
```
Se pueden ajustar las cabeceras de CORS sobrescribiendo los parámetros por defecto de una acción. Por ejemplo añadir `Access-Control-Allow-Credentials` a la acción 'login', se podría hacer así:
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
'cors' => [
'Origin' => ['http://www.myserver.net'],
'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
],
'actions' => [
'login' => [
'Access-Control-Allow-Credentials' => true,
]
]
],
], parent::behaviors());
}
```
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 selector de fechas puede generar un selector de fechas 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 selector de fechas 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 generara 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 pude ser "pitada" 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 esta establecida, mostrara "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']) ?>
```
A se muestra una variante de 'HelloWidget' obtiene el contenido 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 creara una nueva instancia del widget y el método 'init()' sera llamado al final del constructor del widget. Cuando se llama [[yii\base\Widget::end()]], el método 'run()' será llamado el resultado que devuelva sera 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 representara el fichero de 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 vista del widget.
## Mejores Practicas <a name="best-practices"></a>
Los widgets son una manera orientada a objetos de reutilizar código de 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 [paquetes asset](structure-asset-bundles.md) que pueden ser utilizados para resolver el problema.
Cuando un widget solo 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 solo un script PHP llano que prefiere mantener dentro de su aplicación.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment