Browse Source

More Spanish Docs [skip ci]

ar-bug
Luciano Baraglia 8 years ago
parent
commit
52bd5790f1
  1. 27
      docs/guide-es/concept-aliases.md
  2. 208
      docs/guide-es/input-file-upload.md
  3. 19
      docs/guide-es/rest-error-handling.md
  4. 5
      docs/guide-es/rest-response-formatting.md
  5. 55
      docs/guide-es/runtime-handling-errors.md
  6. 383
      docs/guide-es/structure-views.md
  7. 11
      docs/guide-es/test-functional.md
  8. 118
      docs/guide-es/tutorial-yii-integration.md

27
docs/guide-es/concept-aliases.md

@ -1,15 +1,17 @@
Alias Alias
===== =====
Los alias son utilizados para representar las rutas de archivos o URLs para evitar su [hard-coding](http://es.wikipedia.org/wiki/Hard_code) Loa alias son utilizados para representar rutas o URLs de manera que no tengas que escribir explícitamente rutas absolutas o URLs en tu
en tu código. Un alias debe comenzar con un cáracter `@` para que así pueda ser diferenciado de las rutas de archivos y URLs. proyecto. Un alias debe comenzar con el signo `@` para ser diferenciado de una ruta normal de archivo y de URLs. Los alias definidos
Por ejemplo, el alias `@yii` representa la ruta de instalación de la librería Yii, mientras que `@web` representa la sin el `@` del principio, serán prefijados con el signo `@`.
URL base la aplicación que actualmente se está ejecutando.
Definiendo Alias <span id="defining-aliases"></span> Yii trae disponibles varios alias predefinidos. Por ejemplo, el alias `@yii` representa la ruta de instalación del
---------------- framework Yii; `@web` representa la URL base para la aplicación Web ejecutándose.
Puedes llamar a [[Yii::setAlias()]] para definir un alias para una determinada ruta de archivo o URL. Por ejemplo, Definir Alias <span id="defining-aliases"></span>
-------------
Para definir un alias puedes llamar a [[Yii::setAlias()]] para una determinada ruta de archivo o URL. Por ejemplo,
```php ```php
// un alias de una ruta de archivos // un alias de una ruta de archivos
@ -83,9 +85,10 @@ Si `@foo/bar` no está definido como un alias de raíz, la última declaración
Usando Alias <span id="using-aliases"></span> Usando Alias <span id="using-aliases"></span>
------------ ------------
Los alias son utilizados en muchos lugares en Yii sin necesidad de llamar [[Yii::getAlias()]] para convertirlos en rutas/URLs. Los alias son utilizados en muchos lugares en Yii sin necesidad de llamar [[Yii::getAlias()]] para convertirlos
Por ejemplo, [[yii\caching\FileCache::cachePath]] puede aceptar tanto una ruta de archivo como un alias que represente en rutas/URLs. Por ejemplo, [[yii\caching\FileCache::cachePath]] puede aceptar tanto una ruta de archivo como un alias
la ruta de archivo, gracias al prefijo `@` el cual permite diferenciar una ruta de archivo de un alias. que represente la ruta de archivo, gracias al prefijo `@` el cual permite diferenciar una ruta de archivo
de un alias.
```php ```php
use yii\caching\FileCache; use yii\caching\FileCache;
@ -121,10 +124,10 @@ mientras que el resto de los alias están definidos en el constructor de la apli
Alias en Extensiones <span id="extension-aliases"></span> Alias en Extensiones <span id="extension-aliases"></span>
-------------------- --------------------
Un alias se define automaticamente por cada [extensión](structure-extensions.md) que ha sido instalada a través de Composer. Un alias se define automáticamente por cada [extensión](structure-extensions.md) que ha sido instalada a través de Composer.
El alias es nombrado tras el `namespace` de raíz de la extensión instalada tal y como está declarada en su archivo `composer.json`, El alias es nombrado tras el `namespace` de raíz de la extensión instalada tal y como está declarada en su archivo `composer.json`,
y representa el directorio raíz de la extensión. Por ejemplo, si instalas la extensión `yiisoft/yii2-jui`, tendrás y representa el directorio raíz de la extensión. Por ejemplo, si instalas la extensión `yiisoft/yii2-jui`, tendrás
automaticamente definido el alias `@yii/jui` durante la etapa [bootstrapping](runtime-bootstrapping.md) de la aplicación: automáticamente definido el alias `@yii/jui` durante la etapa [bootstrapping](runtime-bootstrapping.md) de la aplicación:
```php ```php
Yii::setAlias('@yii/jui', 'VendorPath/yiisoft/yii2-jui'); Yii::setAlias('@yii/jui', 'VendorPath/yiisoft/yii2-jui');

208
docs/guide-es/input-file-upload.md

@ -0,0 +1,208 @@
Subir Archivos
==============
Subir archivos en Yii es normalmente realizado con la ayuda de [[yii\web\UploadedFile]], que encapsula cada archivo subido
en un objeto `UploadedFile`. Combinado con [[yii\widgets\ActiveForm]] y [modelos](structure-models.md),
puedes fácilmente implementar un mecanismo seguro de subida de archivos.
## Crear Modelos <span id="creating-models"></span>
Al igual que al trabajar con entradas de texto plano, para subir un archivo debes crear una clase de modelo y utilizar un atributo
de dicho modelo para mantener la instancia del archivo subido. Debes también declarar una regla para validar la subida del archivo.
Por ejemplo,
```php
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model
{
/**
* @var UploadedFile
*/
public $imageFile;
public function rules()
{
return [
[['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
public function upload()
{
if ($this->validate()) {
$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
return true;
} else {
return false;
}
}
}
```
En el código anterior, el atributo `imageFile` es utilizado para mantener una instancia del archivo subido. Este está asociado con
una regla de validación `file`, que utiliza [[yii\validators\FileValidator]] para asegurarse que el archivo a subir tenga extensión `png` o `jpg`.
El método `upload()` realizará la validación y guardará el archivo subido en el servidor.
El validador `file` te permite chequear las extensiones, el tamaño, el tipo MIME, etc. Por favor consulta
la sección [Validadores del Framework](tutorial-core-validators.md#file) para más detalles.
> Tip: Si estás subiendo una imagen, podrías considerar el utilizar el validador `image`. El validador `image` es
implementado a través de [[yii\validators\ImageValidator]], que verifica que un atributo haya recibido una imagen válida
que pueda ser tanto guardada como procesada utilizando la [Extensión Imagine](https://github.com/yiisoft/yii2-imagine).
## Renderizar Campos de Subida de Archivos <span id="rendering-file-input"></span>
A continuación, crea un campo de subida de archivo en la vista:
```php
<?php
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<button>Enviar</button>
<?php ActiveForm::end() ?>
```
Es importante recordad que agregues la opción `enctype` al formulario para que el archivo pueda ser subido apropiadamente.
La llamada a `fileInput()` renderizará un tag `<input type="file">` que le permitirá al usuario seleccionar el archivo a subir.
> Tip: desde la versión 2.0.8, [[yii\web\widgets\ActiveField::fileInput|fileInput]] agrega la opción `enctype` al formulario
automáticamente cuando se utiliza una campo de subida de archivo.
## Uniendo Todo <span id="wiring-up"></span>
Ahora, en una acción del controlador, escribe el código que una el modelo y la vista para implementar la subida de archivos:
```php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->imageFile = UploadedFile::getInstance($model, 'imageFile');
if ($model->upload()) {
// el archivo se subió exitosamente
return;
}
}
return $this->render('upload', ['model' => $model]);
}
}
```
En el código anterior, cuando se envía el formulario, el método [[yii\web\UploadedFile::getInstance()]] es llamado
para representar el archivo subido como una instancia de `UploadedFile`. Entonces dependemos de la validación del modelo
para asegurarnos que el archivo subido es válido y entonces subirlo al servidor.
## Uploading Multiple Files <span id="uploading-multiple-files"></span>
También puedes subir varios archivos a la vez, con algunos ajustes en el código de las subsecciones previas.
Primero debes ajustar la clase del modelo, agregando la opción `maxFiles` en la regla de validación `file` para limitar
el número máximo de archivos a subir. Definir `maxFiles` como `0` significa que no hay límite en el número de archivos
a subir simultáneamente. El número máximo de archivos permitidos para subir simultáneamente está también limitado
por la directiva PHP [`max_file_uploads`](http://php.net/manual/en/ini.core.php#ini.max-file-uploads),
cuyo valor por defecto es 20. El método `upload()` debería también ser modificado para guardar los archivos uno a uno.
```php
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model
{
/**
* @var UploadedFile[]
*/
public $imageFiles;
public function rules()
{
return [
[['imageFiles'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg', 'maxFiles' => 4],
];
}
public function upload()
{
if ($this->validate()) {
foreach ($this->imageFiles as $file) {
$file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
}
return true;
} else {
return false;
}
}
}
```
En el archivo de la vista, debes agregar la opción `multiple` en la llamada a `fileInput()` de manera que el campo
pueda recibir varios archivos:
```php
<?php
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'imageFiles[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
<button>Enviar</button>
<?php ActiveForm::end() ?>
```
Y finalmente en la acción del controlador, debes llamar `UploadedFile::getInstances()` en vez de
`UploadedFile::getInstance()` para asignar un array de instancias `UploadedFile` a `UploadForm::imageFiles`.
```php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->imageFiles = UploadedFile::getInstances($model, 'imageFiles');
if ($model->upload()) {
// el archivo fue subido exitosamente
return;
}
}
return $this->render('upload', ['model' => $model]);
}
}
```

19
docs/guide-es/rest-error-handling.md

@ -6,7 +6,8 @@ ocurre en el servidor, simplemente puedes lanzar una excepción para notificar a
Si puedes identificar la causa del error (p.e., el recurso solicitado no existe), debes considerar lanzar una excepción Si puedes identificar la causa del error (p.e., el recurso solicitado no existe), debes considerar lanzar una excepción
con el código HTTP de estado apropiado (p.e., [[yii\web\NotFoundHttpException]] representa un código de estado 404). con el código HTTP de estado apropiado (p.e., [[yii\web\NotFoundHttpException]] representa un código de estado 404).
Yii enviará la respuesta a continuación con el correspondiente código de estado HTTP y el texto. Yii puede incluir también Yii enviará la respuesta a continuación con el correspondiente código de estado HTTP y el texto. Yii puede incluir también
la representación serializada de la excepción en el cuerpo de la respuesta. Por ejemplo: la representación serializada de la excepción en el cuerpo de la respuesta.
Por ejemplo:
``` ```
HTTP/1.1 404 Not Found HTTP/1.1 404 Not Found
@ -17,7 +18,7 @@ Content-Type: application/json; charset=UTF-8
{ {
"name": "Not Found Exception", "name": "Not Found Exception",
"message": "El recurso solicitado no ha sido encontrado.", "message": "The requested resource was not found.",
"code": 0, "code": 0,
"status": 404 "status": 404
} }
@ -26,21 +27,23 @@ Content-Type: application/json; charset=UTF-8
La siguiente lista sumariza los códigos de estado HTTP que son usados por el framework REST: La siguiente lista sumariza los códigos de estado HTTP que son usados por el framework REST:
* `200`: OK. Todo ha funcionado como se esperaba. * `200`: OK. Todo ha funcionado como se esperaba.
* `201`: El recurso ha creado con éxito en respuesta a la petición `POST`. La cabecera de situación `Location` contiene la URL apuntando al nuevo recurso creado. * `201`: El recurso ha creado con éxito en respuesta a la petición `POST`. La cabecera de situación `Location`
contiene la URL apuntando al nuevo recurso creado.
* `204`: La petición ha sido manejada con éxito y el cuerpo de la respuesta no tiene contenido (como una petición `DELETE`). * `204`: La petición ha sido manejada con éxito y el cuerpo de la respuesta no tiene contenido (como una petición `DELETE`).
* `304`: El recurso no ha sido modificado. Puede usar la versión en caché. * `304`: El recurso no ha sido modificado. Puede usar la versión en caché.
* `400`: Petición errónea. Esto puede estar causado por varias acciones de el usuario, como proveer un JSON no válido en el cuerpo de la petición, proveyendo parámetros de acción no válidos, etc. * `400`: Petición errónea. Esto puede estar causado por varias acciones de el usuario, como proveer un JSON no válido
en el cuerpo de la petición, proveyendo parámetros de acción no válidos, etc.
* `401`: Autenticación fallida. * `401`: Autenticación fallida.
* `403`: El usuario autenticado no tiene permitido acceder a la API final. * `403`: El usuario autenticado no tiene permitido acceder a la API final.
* `404`: El recurso pedido no existe. * `404`: El recurso pedido no existe.
* `405`: Método no permitido. Por favor comprueba la cabecera `Allow` por los métodos HTTP permitidos. * `405`: Método no permitido. Por favor comprueba la cabecera `Allow` por los métodos HTTP permitidos.
* `415`: Tipo de medio no soportado. El tipo de contenido pedido o el número de versión no es válido. * `415`: Tipo de medio no soportado. El tipo de contenido pedido o el número de versión no es válido.
* `422`: La validación de datos ha fallado (en respuesta a una petición `POST` , por ejemplo). Por favor, comprobad en el cuerpo de la respuesta el mensaje detallado. * `422`: La validación de datos ha fallado (en respuesta a una petición `POST` , por ejemplo). Por favor, comprueba en el cuerpo de la respuesta el mensaje detallado.
* `429`: Demasiadas peticiones. La petición ha sido rechazada debido a un limitación de rango. * `429`: Demasiadas peticiones. La petición ha sido rechazada debido a un limitación de rango.
* `500`: Error interno del servidor. Esto puede estar causado por errores internos del programa. * `500`: Error interno del servidor. Esto puede estar causado por errores internos del programa.
## Personalizando la Respuesta al Error <span id="customizing-error-response"></span> ## Personalizar la Respuesta al Error <span id="customizing-error-response"></span>
A veces puedes querer personalizar el formato de la respuesta del error por defecto . Por ejemplo, en lugar de depender A veces puedes querer personalizar el formato de la respuesta del error por defecto . Por ejemplo, en lugar de depender
del uso de diferentes estados HTTP para indicar los diferentes errores, puedes querer usar siempre el estado HTTP 200 del uso de diferentes estados HTTP para indicar los diferentes errores, puedes querer usar siempre el estado HTTP 200
@ -64,7 +67,7 @@ Content-Type: application/json; charset=UTF-8
} }
``` ```
Para lograr este objetivo, puedes responder al evento `beforeSend` del componente `response` en la configuración de la aplicación: Para lograrlo, puedes responder al evento `beforeSend` del componente `response` en la configuración de la aplicación:
```php ```php
return [ return [
@ -74,7 +77,7 @@ return [
'class' => 'yii\web\Response', 'class' => 'yii\web\Response',
'on beforeSend' => function ($event) { 'on beforeSend' => function ($event) {
$response = $event->sender; $response = $event->sender;
if ($response->data !== null && !empty(Yii::$app->request->get['suppress_response_code'])) { if ($response->data !== null && Yii::$app->request->get('suppress_response_code')) {
$response->data = [ $response->data = [
'success' => $response->isSuccessful, 'success' => $response->isSuccessful,
'data' => $response->data, 'data' => $response->data,

5
docs/guide-es/rest-response-formatting.md

@ -9,8 +9,9 @@ con el formato de la respuesta:
2. La conversión de objetos recurso en arrays, como está descrito en la sección [Recursos (Resources)](rest-resources.md). 2. La conversión de objetos recurso en arrays, como está descrito en la sección [Recursos (Resources)](rest-resources.md).
Esto es realizado por la clase [[yii\rest\Serializer]]. Esto es realizado por la clase [[yii\rest\Serializer]].
3. La conversión de arrays en cadenas con el formato determinado por el paso de negociación de contenido. Esto es 3. La conversión de arrays en cadenas con el formato determinado por el paso de negociación de contenido. Esto es
realizado por los [[yii\web\ResponseFormatterInterface|response formatters]] registrados con el realizado por los [[yii\web\ResponseFormatterInterface|formatos de respuesta]] registrados
componente de la aplicación [[yii\web\Response::formatters|response]]. con la propiedad [[yii\web\Response::formatters|formatters]] del
[componente de la aplicación](structure-application-components.md) `response`.
## Negociación de contenido (Content Negotiation) <span id="content-negotiation"></span> ## Negociación de contenido (Content Negotiation) <span id="content-negotiation"></span>

55
docs/guide-es/runtime-handling-errors.md

@ -4,22 +4,20 @@ Gestión de Errores
Yii incluye un [[yii\web\ErrorHandler|error handler]] que permite una gestión de errores mucho más práctica que Yii incluye un [[yii\web\ErrorHandler|error handler]] que permite una gestión de errores mucho más práctica que
anteriormente. En particular, el gestor de errores de Yii hace lo siguiente para mejorar la gestión de errores: anteriormente. En particular, el gestor de errores de Yii hace lo siguiente para mejorar la gestión de errores:
* Todos los errores no fatales (ej. advertencias (warning), avisos (notices)) se convierten en excepciones * Todos los errores no fatales (ej. advertencias (warning), avisos (notices)) se convierten en excepciones capturables.
capturables.
* Las excepciones y los errores fatales de PHP se muestran con una pila de llamadas (call stack) de información * Las excepciones y los errores fatales de PHP se muestran con una pila de llamadas (call stack) de información
detallada y lineas de código fuente. detallada y lineas de código fuente.
* Soporta el uso de [acciones de controlador](structure-controllers.md#actions) dedicadas para mostrar errores. * Soporta el uso de [acciones de controlador](structure-controllers.md#actions) dedicadas para mostrar errores.
* Soporta diferentes formatos de respuesta (response) de errores. * Soporta diferentes formatos de respuesta (response) de errores.
El [[yii\web\ErrorHandler|error handler]] esta habilitado de forma predeterminada. Se puede deshabilitar definiendo la El [[yii\web\ErrorHandler|error handler]] esta habilitado de forma predeterminada. Se puede deshabilitar definiendo la
constante `YII_ENABLE_ERROR_HANDLER` con valor false en el constante `YII_ENABLE_ERROR_HANDLER` con valor false en el [script de entrada (entry script)](structure-entry-scripts.md) de la aplicación.
[script de entrada (entry script)](structure-entry-scripts.md) de la aplicación.
## Uso del Gestor de Errores <span id="using-error-handler"></span> ## Uso del Gestor de Errores <span id="using-error-handler"></span>
El [[yii\web\ErrorHandler|error handler]] se registra como un El [[yii\web\ErrorHandler|error handler]] se registra como un [componente de aplicación](structure-application-components.md) llamado `errorHandler`.
[componente de aplicación](structure-application-components.md) llamado `errorHandler`. Se puede configurar en la Se puede configurar en la configuración de la aplicación como en el siguiente ejemplo:
configuración de la aplicación como en el siguiente ejemplo:
```php ```php
return [ return [
@ -31,8 +29,7 @@ return [
]; ];
``` ```
Con la anterior configuración, el numero del lineas de código fuente que se mostrará en las páginas de excepciones Con la anterior configuración, el numero del lineas de código fuente que se mostrará en las páginas de excepciones será como máximo de 20.
será como máximo de 20.
Como se ha mencionado, el gestor de errores convierte todos los errores de PHP no fatales en excepciones capturables. Como se ha mencionado, el gestor de errores convierte todos los errores de PHP no fatales en excepciones capturables.
Esto significa que se puede usar el siguiente código para tratar los errores PHP: Esto significa que se puede usar el siguiente código para tratar los errores PHP:
@ -61,29 +58,27 @@ use yii\web\NotFoundHttpException;
throw new NotFoundHttpException(); throw new NotFoundHttpException();
``` ```
## Personalizar la Visualización de Errores <span id="customizing-error-display"></span> ## Personalizar la Visualización de Errores <span id="customizing-error-display"></span>
El [[yii\web\ErrorHandler|error handler]] ajusta la visualización del error conforme al valor de la constante El [[yii\web\ErrorHandler|error handler]] ajusta la visualización del error conforme al valor de la constante `YII_DEBUG`.
`YII_DEBUG`. Cuando `YII_DEBUG` es `true` (es decir, en modo depuración (debug)), el gestor de errores mostrara las Cuando `YII_DEBUG` es `true` (es decir, en modo depuración (debug)), el gestor de errores mostrara las
excepciones con una pila detallada de información y con lineas de código fuente para ayudar a depurar. Y cuando la excepciones con una pila detallada de información y con lineas de código fuente para ayudar a depurar. Y cuando la variable `YII_DEBUG` es `false`,
variable `YII_DEBUG` es `false`, solo se mostrará el mensaje de error para prevenir la revelación de información solo se mostrará el mensaje de error para prevenir la revelación de información sensible de la aplicación.
sensible de la aplicación.
> Info: Si una excepción es descendiente de [[yii\base\UserException]], no se mostrará la pila de llamadas > Info: Si una excepción es descendiente de [[yii\base\UserException]], no se mostrará la pila de llamadas
independientemente del valor de `YII_DEBUG`. Esto es debido a que se considera que estas excepciones se deben a independientemente del valor de `YII_DEBUG`. Esto es debido a que se considera que estas excepciones se deben a
errores cometidos por los usuarios y los desarrolladores no necesitan corregirlas. errores cometidos por los usuarios y los desarrolladores no necesitan corregirlas.
De forma predeterminada, el [[yii\web\ErrorHandler|error handler]] muestra los errores usando dos De forma predeterminada, el [[yii\web\ErrorHandler|error handler]] muestra los errores usando dos [vistas](structure-views.md):
[vistas](structure-views.md):
* `@yii/views/errorHandler/error.php`: se usa cuando deben mostrarse los errores SIN la información de la pila de * `@yii/views/errorHandler/error.php`: se usa cuando deben mostrarse los errores SIN la información de la pila de
llamadas. Cuando `YII_DEBUG` es falos, este es el único error que se mostrara. llamadas. Cuando `YII_DEBUG` es falos, este es el único error que se mostrara.
* `@yii/views/errorHandler/exception.php`: se usa cuando los errores deben mostrarse CON la información de la pila de * `@yii/views/errorHandler/exception.php`: se usa cuando los errores deben mostrarse CON la información de la pila de llamadas.
llamadas.
Se pueden configurar las propiedades [[yii\web\ErrorHandler::errorView|errorView]] y [[yii\web\ErrorHandler::exceptionView|exceptionView]]
el gestor de errores para usar nuestros propias vistas para personalizar la visualización de los errores.
Se pueden configurar las propiedades [[yii\web\ErrorHandler::errorView|errorView]] y
[[yii\web\ErrorHandler::exceptionView|exceptionView]] el gestor de errores para usar nuestros propias vistas para
personalizar la visualización de los errores.
### Uso de Acciones de Error <span id="using-error-actions"></span> ### Uso de Acciones de Error <span id="using-error-actions"></span>
@ -129,8 +124,7 @@ class SiteController extends Controller
El código anterior define la acción `error` usando la clase [[yii\web\ErrorAction]] que renderiza un error usando la El código anterior define la acción `error` usando la clase [[yii\web\ErrorAction]] que renderiza un error usando la
vista llamada `error`. vista llamada `error`.
Además, usando [[yii\web\ErrorAction]], también se puede definir la acción `error` usando un método de acción como en Además, usando [[yii\web\ErrorAction]], también se puede definir la acción `error` usando un método de acción como en el siguiente ejemplo,
el siguiente ejemplo,
```php ```php
public function actionError() public function actionError()
@ -150,8 +144,15 @@ a las siguientes variables si se define el error como un [[yii\web\ErrorAction]]
* `exception`: el objeto de excepción a través del cual se puede obtener más información útil, tal como el código de * `exception`: el objeto de excepción a través del cual se puede obtener más información útil, tal como el código de
estado HTTP, el código de error, la pila de llamadas del error, etc. estado HTTP, el código de error, la pila de llamadas del error, etc.
> Info: Tanto la [plantilla de aplicación básica](start-installation.md) como la > Info: Tanto la [plantilla de aplicación básica](start-installation.md) como la [plantilla de aplicación avanzada](tutorial-advanced-app.md),
[plantilla de aplicación avanzada](tutorial-advanced-app.md), ya incorporan la acción de error y la vista de error. ya incorporan la acción de error y la vista de error.
> Note: Si necesitas redireccionar en un gestor de error, hazlo de la siguiente manera:
> ```php
> Yii::$app->getResponse()->redirect($url)->send();
> return;
> ```
### Personalizar el Formato de Respuesta de Error <span id="error-format"></span> ### Personalizar el Formato de Respuesta de Error <span id="error-format"></span>

383
docs/guide-es/structure-views.md

@ -2,13 +2,18 @@ Vistas
====== ======
Las Vistas (views) son una parte de la arquitectura [MVC](http://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Las Vistas (views) son una parte de la arquitectura [MVC](http://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador).
Estas son el código responsable de presentar los datos al usuario final. En una aplicación Web, las vistas son usualmente creadas en términos de *templates* que son archivos PHP que contienen principalmente HTML y PHP. Estas son el código responsable de presentar los datos al usuario final. En una aplicación Web, las vistas son usualmente creadas
Son manejadas por el componente de la aplicación [[yii\web\View|view]], el cual provee métodos comúnmente utilizados para facilitar la composición y el renderizado de las mismas. Por simplicidad, a menudo las llamamos *templates* o *archivos de templates*. en términos de *templates* que son archivos PHP que contienen principalmente HTML y PHP.
Estas son manejadas por el [componente de la aplicación](structure-application-components.md) [[yii\web\View|view]], el cual provee los métodos comúnmente utilizados
para facilitar la composición y renderizado. Por simplicidad, a menudo nos referimos a los templates de vistas o archivos de templates
como vistas.
## Creando Vistas <span id="creating-views"></span> ## Crear Vistas <span id="creating-views"></span>
Como fue mencionado, una vista es simplemente un archivo PHP que mezcla código PHP y HTML. La siguiente es una vista que muestra un formulario de login. Como puedes ver, el código PHP utilizado es para generar contenido dinámico, como el título de la página y el formulario mismo, mientras que el código HTML organiza estos elementos en una página HTML mostrable. Como fue mencionado, una vista es simplemente un archivo PHP que mezcla código PHP y HTML. La siguiente es una vista
que muestra un formulario de login. Como puedes ver, el código PHP utilizado es para generar contenido dinámico, como el
título de la página y el formulario mismo, mientras que el código HTML organiza estos elementos en una página HTML mostrable.
```php ```php
<?php <?php
@ -32,18 +37,25 @@ $this->title = 'Login';
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>
``` ```
Dentro de una vista, puedes acceder a la variable `$this` referida al [[yii\web\View|componente view]] que maneja y renderiza la vista actual. Dentro de una vista, puedes acceder a la variable `$this` referida al [[yii\web\View|componente view]]
que maneja y renderiza la vista actual.
Además de `$this`, puede haber otras variables predefinidas en una vista, como `$form` y `$model` en el ejemplo anterior. Estas variables representan los datos que son *inyectados* a la vista desde el [controlador](structure-controllers.md) o algún otro objeto que dispara la [renderización de la vista](#rendering-views). Además de `$this`, puede haber otras variables predefinidas en una vista, como `$form` y `$model` en el
ejemplo anterior. Estas variables representan los datos que son *inyectados* a la vista desde el [controlador](structure-controllers.md)
o algún otro objeto que dispara la [renderización de la vista](#rendering-views).
> Tip: La lista de variables predefinidas están listadas en un bloque de comentario al principio de la vista así pueden ser reconocidas por las IDEs. Esto es también una buena manera de documentar tus propias vistas. > Tip: La lista de variables predefinidas están listadas en un bloque de comentario al principio de la vista así
pueden ser reconocidas por las IDEs. Esto es también una buena manera de documentar tus propias vistas.
### Seguridad <span id="security"></span> ### Seguridad <span id="security"></span>
Al crear vistas que generan páginas HTML, es importante que codifiques (encode) y/o filtres los datos provenientes de los usuarios antes de mostrarlos. De otro modo, tu aplicación puede estar expuesta a ataques tipo [cross-site scripting](http://es.wikipedia.org/wiki/Cross-site_scripting). Al crear vistas que generan páginas HTML, es importante que codifiques (encode) y/o filtres los datos
provenientes de los usuarios antes de mostrarlos. De otro modo, tu aplicación puede estar expuesta
a ataques tipo [cross-site scripting](http://es.wikipedia.org/wiki/Cross-site_scripting).
Para mostrar un texto plano, codifícalos previamente utilizando [[yii\helpers\Html::encode()]]. Por ejemplo, el siguiente código aplica una codificación del nombre de usuario antes de mostrarlo: Para mostrar un texto plano, codifícalos previamente utilizando [[yii\helpers\Html::encode()]]. Por ejemplo, el siguiente código aplica
una codificación del nombre de usuario antes de mostrarlo:
```php ```php
<?php <?php
@ -55,7 +67,8 @@ use yii\helpers\Html;
</div> </div>
``` ```
Para mostrar contenido HTML, utiliza [[yii\helpers\HtmlPurifier]] para filtrarlo antes. Por ejemplo, el siguiente código filtra el contenido del post antes de mostrarlo en pantalla: Para mostrar contenido HTML, utiliza [[yii\helpers\HtmlPurifier]] para filtrarlo antes. Por ejemplo, el siguiente código
filtra el contenido del post antes de mostrarlo en pantalla:
```php ```php
<?php <?php
@ -67,23 +80,31 @@ use yii\helpers\HtmlPurifier;
</div> </div>
``` ```
> Tip: Aunque HTMLPurifier hace un excelente trabajo al hacer la salida más segura, no es rápido. Deberías considerar utilizar [caching](caching-overview.md) al resultado de aplicar el filtro si tu aplicación requiere un gran desempeño (performance). > Tip: Aunque HTMLPurifier hace un excelente trabajo al hacer la salida más segura, no es rápido. Deberías considerar
el aplicar un [caching](caching-overview.md) al resultado de aplicar el filtro si tu aplicación requiere un gran desempeño (performance).
### Organizando Vistas <span id="organizing-views"></span> ### Organizar las Vistas <span id="organizing-views"></span>
Así como en [controladores](structure-controllers.md) y [modelos](structure-models.md), existen convenciones para organizar las vistas. Así como en [controladores](structure-controllers.md) y [modelos](structure-models.md), existen convenciones para organizar las vistas.
* Para vistas renderizadas por controladores, deberían colocarse en un directorio tipo `@app/views/ControllerID` por defecto, donde `ControllerID` se refiere al [ID del controlador](structure-controllers.md#routes). Por ejemplo, si la clase del controlador es `PostController`, el directorio sería `@app/views/post`; Si fuera `PostCommentController`, el directorio sería `@app/views/post-comment`. En caso de que el controlador pertenezca a un módulo, el directorio sería `views/ControllerID` bajo el [[yii\base\Module::basePath|directorio del módulo]]. * Para vistas renderizadas por controladores, deberían colocarse en un directorio tipo `@app/views/ControllerID` por defecto,
* Para vistas renderizadas por un [widget](structure-widgets.md), deberían ser puestas en un directorio tipo `WidgetPath/views` por defecto, donde `WidgetPath` se refiere al directorio que contiene a la clase del widget. donde `ControllerID` se refiere al [ID del controlador](structure-controllers.md#routes). Por ejemplo,
si la clase del controlador es `PostController`, el directorio sería `@app/views/post`; Si fuera `PostCommentController`,
el directorio sería `@app/views/post-comment`. En caso de que el controlador pertenezca a un módulo,
el directorio sería `views/ControllerID` bajo el [[yii\base\Module::basePath|directorio del módulo]].
* Para vistas renderizadas por un [widget](structure-widgets.md), deberían ser puestas en un directorio
tipo `WidgetPath/views` por defecto, donde `WidgetPath` se refiere al directorio que contiene a la clase del widget.
* Para vistas renderizadas por otros objetos, se recomienda seguir una convención similar a la utilizada con los widgets. * Para vistas renderizadas por otros objetos, se recomienda seguir una convención similar a la utilizada con los widgets.
Puedes personalizar estos directorios por defecto sobrescribiendo el método [[yii\base\ViewContextInterface::getViewPath()]] en el controlador o widget necesario. Puedes personalizar estos directorios por defecto sobrescribiendo el método [[yii\base\ViewContextInterface::getViewPath()]]
en el controlador o widget necesario.
## Renderizando Vistas <span id="rendering-views"></span> ## Renderizando Vistas <span id="rendering-views"></span>
Puedes renderizar vistas desde [controllers](structure-controllers.md), [widgets](structure-widgets.md), o cualquier otro lugar llamando a los métodos de renderización de vistas. Estos métodos comparten una firma similar, como se muestra a continuación: Puedes renderizar vistas desde [controllers](structure-controllers.md), [widgets](structure-widgets.md), o cualquier otro lugar
llamando a los métodos de renderización de vistas. Estos métodos comparten una firma similar, como se muestra a continuación:
``` ```
/** /**
@ -99,10 +120,15 @@ methodName($view, $params = [])
Dentro de los [controladores](structure-controllers.md), puedes llamar al siguiente método del controlador para renderizar una vista: Dentro de los [controladores](structure-controllers.md), puedes llamar al siguiente método del controlador para renderizar una vista:
* [[yii\base\Controller::render()|render()]]: renderiza la [vista nombrada](#named-views) y aplica un [layout](#layouts) al resultado de la renderización. * [[yii\base\Controller::render()|render()]]: renderiza la [vista nombrada](#named-views) y aplica un [layout](#layouts)
al resultado de la renderización.
* [[yii\base\Controller::renderPartial()|renderPartial()]]: renderiza la [vista nombrada](#named-views) sin ningún layout aplicado. * [[yii\base\Controller::renderPartial()|renderPartial()]]: renderiza la [vista nombrada](#named-views) sin ningún layout aplicado.
* [[yii\web\Controller::renderAjax()|renderAjax()]]: renderiza la [vista nombrada](#named-views) sin layout, e inyecta todos los scripts y archivos JS/CSS registrados. Esto sucede usualmente en respuestas a llamadas a AJAX `requests`. * [[yii\web\Controller::renderAjax()|renderAjax()]]: renderiza la [vista nombrada](#named-views) sin layout,
* [[yii\base\Controller::renderFile()|renderFile()]]: renderiza la vista especificada en términos de la ruta al archivo o [alias](concept-aliases.md). e inyecta todos los scripts y archivos JS/CSS registrados. Esto sucede usualmente en respuestas a peticiones AJAX.
* [[yii\base\Controller::renderFile()|renderFile()]]: renderiza la vista especificada en términos de la ruta al archivo o
[alias](concept-aliases.md).
* [[yii\base\Controller::renderContent()|renderContent()]]: renderiza un string fijo, inscrustándolo en
el [layout](#layouts) actualmente aplicable. Este método está disponible desde la versión 2.0.1.
Por ejemplo: Por ejemplo:
@ -137,7 +163,8 @@ class PostController extends Controller
Dentro de [widgets](structure-widgets.md), puedes llamar a cualquier de los siguientes métodos de widget para renderizar una vista. Dentro de [widgets](structure-widgets.md), puedes llamar a cualquier de los siguientes métodos de widget para renderizar una vista.
* [[yii\base\Widget::render()|render()]]: renderiza la [vista nombrada](#named-views). * [[yii\base\Widget::render()|render()]]: renderiza la [vista nombrada](#named-views).
* [[yii\base\Widget::renderFile()|renderFile()]]: renderiza la vista especificada en términos de ruta al archivo o [alias](concept-aliases.md). * [[yii\base\Widget::renderFile()|renderFile()]]: renderiza la vista especificada en términos de ruta al archivo
o [alias](concept-aliases.md).
Por ejemplo: Por ejemplo:
@ -162,22 +189,25 @@ class ListWidget extends Widget
``` ```
### Renderizando en Vistas <span id="rendering-in-views"></span> ### Renderizar en Vistas <span id="rendering-in-views"></span>
Puedes renderizar una vista dentro de otra vista llamando a algunos de los siguientes métodos provistos por el [[yii\base\View|componente view]]: Puedes renderizar una vista dentro de otra vista llamando a algunos de los siguientes métodos provistos por el [[yii\base\View|componente view]]:
* [[yii\base\View::render()|render()]]: renderiza la [vista nombrada](#named-views). * [[yii\base\View::render()|render()]]: renderiza la [vista nombrada](#named-views).
* [[yii\web\View::renderAjax()|renderAjax()]]: renderiza la [vista nombrada](#named-views) e inyecta todos los archivos y scripts JS/CSS. Esto sucede usualmente en respuestas a llamadas a AJAX `requests`. * [[yii\web\View::renderAjax()|renderAjax()]]: renderiza la [vista nombrada](#named-views) e inyecta
* [[yii\base\View::renderFile()|renderFile()]]: renderiza la vista especificada en términos de ruta al archivo o [alias](concept-aliases.md). todos los archivos y scripts JS/CSS. Esto sucede usualmente en respuestas a las peticiones AJAX.
* [[yii\base\View::renderFile()|renderFile()]]: renderiza la vista especificada en términos de ruta al archivo
o [alias](concept-aliases.md).
Por ejemplo, el siguiente código en una vista renderiza el template `_overview.php` encontrado en el mismo directorio de la vista renderizada actualmente. Recuerda que la variable `$this` en una vista se refiere al componente [[yii\base\View|view]]: Por ejemplo, el siguiente código en una vista renderiza el template `_overview.php` encontrado en el mismo directorio
de la vista renderizada actualmente. Recuerda que la variable `$this` en una vista se refiere al componente [[yii\base\View|view]]:
```php ```php
<?= $this->render('_overview') ?> <?= $this->render('_overview') ?>
``` ```
### Renderizando en Otros Lugares <span id="rendering-in-other-places"></span> ### Renderizar en Otros Lugares <span id="rendering-in-other-places"></span>
En cualquier lugar, puedes tener acceso al componente [[yii\base\View|view]] utilizando la expresión En cualquier lugar, puedes tener acceso al componente [[yii\base\View|view]] utilizando la expresión
`Yii::$app->view` y entonces llamar a los métodos previamente mencionados para renderizar una vista. Por ejemplo: `Yii::$app->view` y entonces llamar a los métodos previamente mencionados para renderizar una vista. Por ejemplo:
@ -190,25 +220,43 @@ echo \Yii::$app->view->renderFile('@app/views/site/license.php');
### Vistas Nombradas <span id="named-views"></span> ### Vistas Nombradas <span id="named-views"></span>
Cuando renderizas una vista, puedes especificar el template utilizando tanto el nombre de la vista o la ruta/alias al archivo. En la mayoría de los casos, utilizarías la primera porque es más concisa y flexible. *Vistas nombradas* son vistas especificadas mediante un nombre en vez de una ruta al archivo o alias. Cuando renderizas una vista, puedes especificar el template utilizando tanto el nombre de la vista o la ruta/alias al archivo. En la mayoría de los casos,
utilizarías la primera porque es más concisa y flexible. Las *vistas nombradas* son vistas especificadas mediante un nombre en vez de una ruta al archivo o alias.
Un nombre de vista es resuelto a su correspondiente ruta de archivo siguiendo las siguientes reglas: Un nombre de vista es resuelto a su correspondiente ruta de archivo siguiendo las siguientes reglas:
* Un nombre de vista puede omitir la extensión del archivo. En estos casos se utilizará `.php` como extensión del archivo. Por ejemplo, el nombre de vista `about` corresponde al archivo `about.php`. * Un nombre de vista puede omitir la extensión del archivo. En estos casos se utilizará `.php` como extensión del archivo. Por ejemplo,
el nombre de vista `about` corresponde al archivo `about.php`.
* Si el nombre de la vista comienza con doble barra (`//`), la ruta al archivo correspondiente será `@app/views/ViewName`. * Si el nombre de la vista comienza con doble barra (`//`), la ruta al archivo correspondiente será `@app/views/ViewName`.
Esto quiere decir que la vista es buscada bajo el [[yii\base\Application::viewPath|view path de la aplicación]]. Esto quiere decir que la vista es buscada bajo el [[yii\base\Application::viewPath|ruta de vistas de la aplicación]].
Por ejemplo, `//site/about` será resuelto como `@app/views/site/about.php`. Por ejemplo, `//site/about` será resuelto como `@app/views/site/about.php`.
* Si el nombre de la vista comienza con una barra simple `/`, la ruta al archivo de la vista utilizará como prefijo el nombre de la vista con el [[yii\base\Module::viewPath|view path]] del [módulo](structure-modules.md) utilizado actualmente. Si no hubiera módulo activo se utilizará `@app/views/ViewName`. Por ejemplo, `/user/create` será resuelto a `@app/modules/user/views/user/create.php` si el módulo activo es `user`. Si no hubiera módulo activo, la ruta al archivo será `@app/views/user/create.php`. * Si el nombre de la vista comienza con una barra simple `/`, la ruta al archivo de la vista utilizará como prefijo el nombre de la vista
* Si la vista es renderizada con un [[yii\base\View::context|context]] y dicho contexto implementa [[yii\base\ViewContextInterface]], la ruta al archivo se forma utilizando como prefijo el [[yii\base\ViewContextInterface::getViewPath()|view path]] del contexto de la vista. Esto principalmente aplica a vistas renderizadas en controladores y widgets. Por ejemplo, `site/about` será resuelto a `@app/views/site/about.php` si el contexto es el controlador `SiteController`. con el [[yii\base\Module::viewPath|view path]] del [módulo](structure-modules.md) utilizado actualmente.
* Si la vista es renderizada dentro de otra vista, el directorio que contiene la otra vista será prefijado al nuevo nombre de la vista para formar la ruta a la vista. Por ejemplo, `item` sera resuelto a `@app/views/post/item` si está siendo renderizado desde la vista `@app/views/post/index.php`. Si no hubiera módulo activo se utilizará `@app/views/ViewName`. Por ejemplo, `/user/create` será resuelto como
`@app/modules/user/views/user/create.php` si el módulo activo es `user`. Si no hubiera módulo activo,
De acuerdo a las reglas mencionadas, al llamar a `$this->render('view')` en el controlador `app\controllers\PostController` se renderizará el template `@app/views/post/view.php`, mientras que llamando a `$this->render('_overview')` en la vista renderizará el template `@app/views/post/_overview.php`. la ruta al archivo será `@app/views/user/create.php`.
* Si la vista es renderizada con un [[yii\base\View::context|context]] y dicho contexto implementa [[yii\base\ViewContextInterface]],
### Accediendo a Datos en la Vista <span id="accessing-data-in-views"></span> la ruta al archivo se forma utilizando como prefijo la [[yii\base\ViewContextInterface::getViewPath()|ruta de vistas]] del contexto
de la vista. Esto principalmente aplica a vistas renderizadas en controladores y widgets. Por ejemplo,
`about` será resuelto como `@app/views/site/about.php` si el contexto es el controlador `SiteController`.
* Si la vista es renderizada dentro de otra vista, el directorio que contiene la otra vista será prefijado
al nuevo nombre de la vista para formar la ruta a la vista. Por ejemplo, `item` sera resuelto como `@app/views/post/item`
si está siendo renderizado desde la vista `@app/views/post/index.php`.
De acuerdo a las reglas mencionadas, al llamar a `$this->render('view')` en el controlador `app\controllers\PostController`
se renderizará el template `@app/views/post/view.php`, mientras que llamando a `$this->render('_overview')` en la vista
renderizará el template `@app/views/post/_overview.php`.
### Acceder a Datos en la Vista <span id="accessing-data-in-views"></span>
Hay dos modos posibles de acceder a los datos en la vista: push (inyectar) y pull (traer). Hay dos modos posibles de acceder a los datos en la vista: push (inyectar) y pull (traer).
Al pasar los datos como segundo parámetro en algún método de renderización, estás utilizando el modo push. Los datos deberían ser representados como un array de pares clave-valor. Cuando la vista está siendo renderizada, la función PHP `extract()` será llamada sobre este array así se extraen las variables que contiene a la vista actual. Por ejemplo, el siguiente código de renderización en un controlador inyectará dos variables a la vista `report`: `$foo = 1` and `$bar = 2`. Al pasar los datos como segundo parámetro en algún método de renderización, estás utilizando el modo push.
Los datos deberían ser representados como un array de pares clave-valor. Cuando la vista está siendo renderizada, la función PHP `extract()`
será llamada sobre este array así se extraen las variables que contiene a la vista actual.
Por ejemplo, el siguiente código de renderización en un controlador inyectará dos variables a la vista `report`:
`$foo = 1` y `$bar = 2`.
```php ```php
echo $this->render('report', [ echo $this->render('report', [
@ -217,26 +265,34 @@ echo $this->render('report', [
]); ]);
``` ```
El modo pull obtiene los datos del [[yii\base\View|componente view]] u otros objetos accesibles en las vistas (ej. `Yii::$app`). Utilizando el código anterior como ejemplo, dentro de una vista puedes acceder al objeto del controlador a través de la expresión `$this->context`. Como resultado, te es posible acceder a cualquier propiedad o método del controlador en la vista `report`, tal como el ID del controlador como se muestra a continuación: El modo pull obtiene los datos del [[yii\base\View|componente view]] u otros objetos accesibles
en las vistas (ej. `Yii::$app`). Utilizando el código anterior como ejemplo, dentro de una vista puedes acceder al objeto del controlador
a través de la expresión `$this->context`. Como resultado, te es posible acceder a cualquier propiedad o método
del controlador en la vista `report`, tal como el ID del controlador como se muestra a continuación:
```php ```php
El ID del controlador es: <?= $this->context->id ?> El ID del controlador es: <?= $this->context->id ?>
?>
``` ```
Para acceder a datos en la vista, normalmente se prefiere el modo push, ya que hace a la vista menos dependiente de los objetos del contexto. La contra es que tienes que construir el array manualmente cada vez, lo que podría volverse tedioso y propenso al error si la misma vista es compartida y renderizada desde diferentes lugares. Para acceder a datos en la vista, normalmente se prefiere el modo push, ya que hace a la vista menos dependiente
de los objetos del contexto. La contra es que tienes que construir el array manualmente cada vez, lo que podría
volverse tedioso y propenso al error si la misma vista es compartida y renderizada desde diferentes lugares.
### Compartiendo Datos Entre las Vistas <span id="sharing-data-among-views"></span> ### Compartir Datos Entre las Vistas <span id="sharing-data-among-views"></span>
El [[yii\base\View|componente view]] provee la propiedad [[yii\base\View::params|params]] para que puedas compartir datos entre diferentes vistas. El [[yii\base\View|componente view]] provee la propiedad [[yii\base\View::params|params]] para que puedas compartir datos
entre diferentes vistas.
Por ejemplo, en una vista `about`, podrías tener el siguiente código que especifica el segmento actual del breadcrumbs (migas de pan). Por ejemplo, en una vista `about`, podrías tener el siguiente código que especifica el segmento actual
del breadcrumbs (migas de pan).
```php ```php
$this->params['breadcrumbs'][] = 'Acerca de Nosotros'; $this->params['breadcrumbs'][] = 'Acerca de Nosotros';
``` ```
Entonces, en el archivo del [layout](#layouts), que es también una vista, puedes mostrar el breadcrumbs utilizando los datos pasados a través de [[yii\base\View::params|params]]: Entonces, en el archivo del [layout](#layouts), que es también una vista, puedes mostrar el breadcrumbs utilizando los datos
pasados a través de [[yii\base\View::params|params]]:
```php ```php
<?= yii\widgets\Breadcrumbs::widget([ <?= yii\widgets\Breadcrumbs::widget([
@ -247,14 +303,22 @@ Entonces, en el archivo del [layout](#layouts), que es también una vista, puede
## Layouts <span id="layouts"></span> ## Layouts <span id="layouts"></span>
Los layouts son un tipo especial de vista que representan partes comunes de otras múltiples vistas. Por ejemplo, las páginas de la mayoría de las aplicaciones Web comparten el mismo encabezado y pie de página. Aunque puedes repetirlos en todas y cada una de las vistas, una mejor forma es hacerlo sólo en el layout e incrustar el resultado de la renderización de la vista en un lugar apropiado del mismo. Los layouts son un tipo especial de vista que representan partes comunes de otras múltiples vistas. Por ejemplo, las páginas
de la mayoría de las aplicaciones Web comparten el mismo encabezado y pie de página. Aunque puedes repetirlos en todas y cada una de las vistas,
una mejor forma es hacerlo sólo en el layout e incrustar el resultado de la renderización de la vista
en un lugar apropiado del mismo.
### Creando Layouts <span id="creating-layouts"></span> ### Crear Layouts <span id="creating-layouts"></span>
Dado que los layouts son también vistas, pueden ser creados de manera similar a las vistas comunes. Por defecto, los layouts son guardados en el directorio `@app/views/layouts`. Para layouts utilizados dentro de un [módulo](structure-modules.md), deberían ser guardados en el directorio `views/layouts` bajo el [[yii\base\Module::basePath|directorio del módulo]]. Puedes personalizar el directorio de layouts por defecto configurando la propiedad [[yii\base\Module::layoutPath]] de la aplicación o módulos. Dado que los layouts son también vistas, pueden ser creados de manera similar a las vistas comunes. Por defecto, los layouts
son guardados en el directorio `@app/views/layouts`. Para layouts utilizados dentro de un [módulo](structure-modules.md), deberían ser guardados
en el directorio `views/layouts` bajo el [[yii\base\Module::basePath|directorio del módulo]].
Puedes personalizar el directorio de layouts por defecto configurando la propiedad [[yii\base\Module::layoutPath]]
de la aplicación o módulos.
El siguiente ejemplo muestra cómo debe verse un layout. Ten en cuenta que por motivos ilustrativos, hemos simplificado bastante el código del layout. En la práctica, probablemente le agregues más contenido, como tags en el `head`, un menú principal, etc. El siguiente ejemplo muestra cómo debe verse un layout. Ten en cuenta que por motivos ilustrativos, hemos simplificado
bastante el código del layout. En la práctica, probablemente le agregues más contenido, como tags en el `head`, un menú principal, etc.
```php ```php
<?php <?php
@ -283,29 +347,51 @@ use yii\helpers\Html;
<?php $this->endPage() ?> <?php $this->endPage() ?>
``` ```
Como puedes ver, el layout genera los tags HTML comunes a todas las páginas. Dentro de la sección `<body>`,el layout imprime la variable `$content`, que representa el resultado de la renderización del contenido de cada vista y es incrustado dentro del layout cuando se llama al método [[yii\base\Controller::render()]]. Como puedes ver, el layout genera los tags HTML comunes a todas las páginas. Dentro de la sección `<body>`,
el layout imprime la variable `$content`, que representa el resultado de la renderización del contenido de cada vista
y es incrustado dentro del layout cuando se llama al método [[yii\base\Controller::render()]].
La mayoría de layouts deberían llamar a los siguientes métodos (como fue mostrado recién). Estos métodos principalmente disparan eventos acerca del proceso de renderizado así los scripts y tags registrados en otros lugares pueden ser propiamente inyectados en los lugares donde los métodos son llamados. La mayoría de layouts deberían llamar a los siguientes métodos (como fue mostrado recién). Estos métodos principalmente disparan eventos
acerca del proceso de renderizado así los scripts y tags registrados en otros lugares pueden ser propiamente inyectados
en los lugares donde los métodos son llamados.
- [[yii\base\View::beginPage()|beginPage()]]: Este método debería ser llamado bien al principio del layout. Esto dispara el evento [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]], el cual indica el comienzo de la página. - [[yii\base\View::beginPage()|beginPage()]]: Este método debería ser llamado bien al principio del layout.
- [[yii\base\View::endPage()|endPage()]]: Este método debería ser llamado al final del layout. Esto dispara el evento [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]], indicando el final de la página. Esto dispara el evento [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]], el cual indica el comienzo de la página.
- [[yii\web\View::head()|head()]]: Este método debería llamarse dentro de la sección `<head>` de una página HTML. Esto genera un espacio vacío que será reemplazado con el código del head HTML registrado (ej. link tags, meta tags) cuando una página finaliza el renderizado. - [[yii\base\View::endPage()|endPage()]]: Este método debería ser llamado al final del layout.
- [[yii\base\View::beginBody()|beginBody()]]: Este método debería llamarse al principio de la sección `<body>`. Esto dispara el evento [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] y genera un espacio vacío que será reemplazado con el código HTML registrado (ej. JavaScript) que apunta al principio del body. Esto dispara el evento [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]], indicando el final de la página.
- [[yii\base\View::endBody()|endBody()]]: Este método debería llamarse al final de la sección `<body>`. Esto dispara el evento [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]], que genera un espacio vacío a ser reemplazado por el código HTML registrado (ej. JavaScript) que apunta al final del body. - [[yii\web\View::head()|head()]]: Este método debería llamarse dentro de la sección `<head>` de una página HTML.
Esto genera un espacio vacío que será reemplazado con el código del head HTML registrado (ej. link tags, meta tags)
cuando una página finaliza el renderizado.
- [[yii\base\View::beginBody()|beginBody()]]: Este método debería llamarse al principio de la sección `<body>`.
Esto dispara el evento [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] y genera un espacio vacío que será reemplazado
con el código HTML registrado (ej. JavaScript) que apunta al principio del body.
- [[yii\base\View::endBody()|endBody()]]: Este método debería llamarse al final de la sección `<body>`.
Esto dispara el evento [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]], que genera un espacio vacío a ser reemplazado
por el código HTML registrado (ej. JavaScript) que apunta al final del body.
### Accediendo a Datos en Layouts <span id="accessing-data-in-layouts"></span> ### Acceder a Datos en Layouts <span id="accessing-data-in-layouts"></span>
Dentro de un layout, tienes acceso a dos variables predefinidas: `$this` y `$content`. La primera se refiere al componente [[yii\base\View|view]], como en cualquier vista, mientras que la última contiene el resultado de la renderización del contenido de la vista que está siendo renderizada all llamar al método [[yii\base\Controller::render()|render()]] en los controladores. Dentro de un layout, tienes acceso a dos variables predefinidas: `$this` y `$content`. La primera se refiere al componente [[yii\base\View|view]],
como en cualquier vista, mientras que la última contiene el resultado de la renderización del contenido de la vista que está siendo renderizada
al llamar al método [[yii\base\Controller::render()|render()]] en los controladores.
Si quieres acceder a otros datos en los layouts, debes utilizar el modo pull que fue descrito en la sub-sección [Accediendo a Datos en la Vista](#accessing-data-in-views). Si quieres pasar datos desde al contenido de la vista a un layout, puedes utilizar el método descrito en la sub-sección [Compartiendo Datos Entre las Vistas](#sharing-data-among-views). Si quieres acceder a otros datos en los layouts, debes utilizar el modo pull que fue descrito en la sub-sección [Accediendo a Datos en la Vista](#accessing-data-in-views).
Si quieres pasar datos desde al contenido de la vista a un layout, puedes utilizar el método descrito en la
sub-sección [Compartiendo Datos Entre las Vistas](#sharing-data-among-views).
### Utilizando Layouts <span id="using-layouts"></span> ### Utilizar Layouts <span id="using-layouts"></span>
Como se describe en la sub-sección [Renderizando en Controllers](#rendering-in-controllers), cuando renderizas una vista llamando al método [[yii\base\Controller::render()|render()]] en un controlador, al resultado de dicha renderización le será aplicado un layout. Por defecto, el layout `@app/views/layouts/main.php` será el utilizado. Como se describe en la sub-sección [Renderizando en Controllers](#rendering-in-controllers), cuando renderizas una vista
llamando al método [[yii\base\Controller::render()|render()]] en un controlador, al resultado de dicha renderización le será aplicado un layout.
Por defecto, el layout `@app/views/layouts/main.php` será el utilizado.
Puedes utilizar un layout diferente configurando la propiedad [[yii\base\Application::layout]] o [[yii\base\Controller::layout]]. El primero se refiere al layout utilizado por todos los controladores, mientras que el último sobrescribe el layout en controladores individuales. Por ejemplo, el siguiente código hace que el controlador `post` utilice `@app/views/layouts/post.php` como layout al renderizar sus vistas. Otros controladores, asumiendo que su propiedad `layout` no fue modificada, utilizarán `@app/views/layouts/main.php` como layout. Puedes utilizar un layout diferente configurando la propiedad [[yii\base\Application::layout]] o [[yii\base\Controller::layout]]. El primero
se refiere al layout utilizado por todos los controladores, mientras que el último sobrescribe el layout en controladores individuales.
Por ejemplo, el siguiente código hace que el controlador `post` utilice `@app/views/layouts/post.php` como layout al renderizar sus vistas.
Otros controladores, asumiendo que su propiedad `layout` no fue modificada,
utilizarán `@app/views/layouts/main.php` como layout.
```php ```php
namespace app\controllers; namespace app\controllers;
@ -320,20 +406,31 @@ class PostController extends Controller
} }
``` ```
Para controladores que pertencen a un módulo, puedes también configurar la propiedad [[yii\base\Module::layout|layout]] y así utilizar un layout en particular para esos controladores. Para controladores que pertencen a un módulo, puedes también configurar la propiedad [[yii\base\Module::layout|layout]] y así utilizar un layout
en particular para esos controladores.
Dado que la propiedad `layout` puede ser configurada en diferentes niveles (controladores, módulos, aplicación), detrás de escena Yii realiza dos pasos para determinar cuál es el archivo de layout siendo utilizado para un controlador en particular. Dado que la propiedad `layout` puede ser configurada en diferentes niveles (controladores, módulos, aplicación), detrás de escena
Yii realiza dos pasos para determinar cuál es el archivo de layout siendo utilizado para un controlador en particular.
En el primer paso, determina el valor del layout y el módulo de contexto: En el primer paso, determina el valor del layout y el módulo de contexto:
- Si la propiedad [[yii\base\Controller::layout]] no es `null`, la utiliza como valor del layout y el [[yii\base\Controller::module|módulo]] del controlador como el módulo de contexto. - Si la propiedad [[yii\base\Controller::layout]] no es `null`, la utiliza como valor del layout y el [[yii\base\Controller::module|módulo]]
- Si [[yii\base\Controller::layout|layout]] es `null`, busca a través de todos los módulos ancestros del controlador y encuentra el primer módulo cuya propiedad [[yii\base\Module::layout|layout]] no es `null`. Utiliza ese módulo y su valor de [[yii\base\Module::layout|layout]] como módulo de contexto y como layout seleccionado. Si tal módulo no puede ser encontrado, significa que no se aplicará ningún layout. del controlador como el módulo de contexto.
- Si [[yii\base\Controller::layout|layout]] es `null`, busca a través de todos los módulos ancestros del controlador
y encuentra el primer módulo cuya propiedad [[yii\base\Module::layout|layout]] no es `null`.
Utiliza ese módulo y su valor de [[yii\base\Module::layout|layout]] como módulo de contexto y como layout seleccionado.
Si tal módulo no puede ser encontrado, significa que no se aplicará ningún layout.
En el segundo paso, se determina el archivo de layout actual de acuerdo al valor de layout y el módulo de contexto determinado en el primer paso. El valor de layout puede ser: En el segundo paso, se determina el archivo de layout actual de acuerdo al valor de layout y el módulo de contexto determinado en el primer paso.
El valor de layout puede ser:
- un alias de ruta (ej. `@app/views/layouts/main`). - un alias de ruta (ej. `@app/views/layouts/main`).
- una ruta absoluta (ej. `/main`): el valor del layout comienza con una barra. El archivo de layout actual será buscado bajo el [[yii\base\Application::layoutPath|layout path]] de la aplicación, que es por defecto `@app/views/layouts`. - una ruta absoluta (ej. `/main`): el valor del layout comienza con una barra. El archivo de layout actual será buscado
- una ruta relativa (ej. `main`): El archivo de layout actual será buscado bajo el [[yii\base\Module::layoutPath|layout path]] del módulo de contexto, que es por defecto el directorio `views/layouts` bajo el [[yii\base\Module::basePath|directorio del módulo]]. bajo el [[yii\base\Application::layoutPath|layout path]] de la aplicación,
que es por defecto `@app/views/layouts`.
- una ruta relativa (ej. `main`): El archivo de layout actual será buscado bajo el [[yii\base\Module::layoutPath|layout path]]
del módulo de contexto, que es por defecto el directorio `views/layouts`
bajo el [[yii\base\Module::basePath|directorio del módulo]].
- el valor booleano `false`: no se aplicará ningún layout. - el valor booleano `false`: no se aplicará ningún layout.
Si el valor de layout no contiene una extensión de tipo de archivo, utilizará por defecto `.php`. Si el valor de layout no contiene una extensión de tipo de archivo, utilizará por defecto `.php`.
@ -341,7 +438,10 @@ Si el valor de layout no contiene una extensión de tipo de archivo, utilizará
### Layouts Anidados <span id="nested-layouts"></span> ### Layouts Anidados <span id="nested-layouts"></span>
A veces podrías querer anidar un layout dentro de otro. Por ejemplo, en diferentes secciones de un sitio Web, podrías querer utilizar layouts diferentes, mientras que todos esos layouts comparten el mismo layout básico que genera la estructura general de la página en HTML5. Esto es posible llamando a los métodos [[yii\base\View::beginContent()|beginContent()]] y [[yii\base\View::endContent()|endContent()]] en los layouts hijos como se muestra a continuación: A veces podrías querer anidar un layout dentro de otro. Por ejemplo, en diferentes secciones de un sitio Web,
podrías querer utilizar layouts diferentes, mientras que todos esos layouts comparten el mismo layout básico que genera
la estructura general de la página en HTML5. Esto es posible llamando a los métodos
[[yii\base\View::beginContent()|beginContent()]] y [[yii\base\View::endContent()|endContent()]] en los layouts hijos como se muestra a continuación:
```php ```php
<?php $this->beginContent('@app/views/layouts/base.php'); ?> <?php $this->beginContent('@app/views/layouts/base.php'); ?>
@ -351,14 +451,80 @@ A veces podrías querer anidar un layout dentro de otro. Por ejemplo, en diferen
<?php $this->endContent(); ?> <?php $this->endContent(); ?>
``` ```
Como se acaba de mostrar, el contenido del layout hijo debe ser encerrado dentro de [[yii\base\View::beginContent()|beginContent()]] y [[yii\base\View::endContent()|endContent()]]. El parámetro pasado a [[yii\base\View::beginContent()|beginContent()]] especifica cuál es el módulo padre. Este puede ser tanto un archivo layout como un alias. Como se acaba de mostrar, el contenido del layout hijo debe ser encerrado dentro de [[yii\base\View::beginContent()|beginContent()]]
y [[yii\base\View::endContent()|endContent()]]. El parámetro pasado a [[yii\base\View::beginContent()|beginContent()]]
especifica cuál es el módulo padre. Este puede ser tanto un archivo layout como un alias.
Utilizando la forma recién mencionada, puedes anidar layouts en más de un nivel. Utilizando la forma recién mencionada, puedes anidar layouts en más de un nivel.
## Utilizando Componentes de Vista <span id="using-view-components"></span> ### Utilizar Blocks <span id="using-blocks"></span>
Los bloques te permiten especificar el contenido de la vista en un lugar y mostrarlo en otro. Estos son a menudo utilizados junto a
los layouts. Por ejemplo, puedes definir un bloque un una vista de contenido y mostrarla en el layout.
Para definir un bloque, llamas a [[yii\base\View::beginBlock()|beginBlock()]] y [[yii\base\View::endBlock()|endBlock()]].
El bloque puede ser accedido vía `$view->blocks[$blockID]`, donde `$blockID` se refiere al ID único que le asignas
al bloque cuando lo defines.
El siguiente ejemplo muestra cómo utilizar bloques para personalizar partes especificas del layout in una vista.
Los [[yii\base\View|componentes de vista]] proveen características relacionadas a las vistas. Aunque puedes obtener componentes de vista creando instancias individuales de [[yii\base\View]] o sus clases hijas, en la mayoría de los casos utilizarías el componente `view` del a aplicación. Puedes configurar este componente en la [configuración de la aplicación](structure-applications.md#application-configurations) como a continuación: Primero, en una vista, define uno o varios bloques:
```php
...
<?php $this->beginBlock('block1'); ?>
...contenido de block1...
<?php $this->endBlock(); ?>
...
<?php $this->beginBlock('block3'); ?>
...contenido de block3...
<?php $this->endBlock(); ?>
```
Entonces, en la vista del layout, renderiza los bloques si están disponibles, o muestra un contenido por defecto si el bloque
no está definido.
```php
...
<?php if (isset($this->blocks['block1'])): ?>
<?= $this->blocks['block1'] ?>
<?php else: ?>
... contenido por defecto de block1 ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block2'])): ?>
<?= $this->blocks['block2'] ?>
<?php else: ?>
... contenido por defecto de block2 ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block3'])): ?>
<?= $this->blocks['block3'] ?>
<?php else: ?>
... contenido por defecto de block3 ...
<?php endif; ?>
...
```
## Utilizar Componentes de Vista <span id="using-view-components"></span>
Los [[yii\base\View|componentes de vista]] proveen características relacionadas a las vistas. Aunque puedes obtener componentes de vista
creando instancias individuales de [[yii\base\View]] o sus clases hijas, en la mayoría de los casos utilizarías el componente `view` del a aplicación.
Puedes configurar este componente en la [configuración de la aplicación](structure-applications.md#application-configurations)
como a continuación:
```php ```php
[ [
@ -386,13 +552,15 @@ Puedes también utilizar frecuentemente el siguiente menor pero útil grupo de c
### Definiendo Títulos de Página <span id="setting-page-titles"></span> ### Definiendo Títulos de Página <span id="setting-page-titles"></span>
Toda página Web debería tener un título. Normalmente el tag de título es generado en [layout](#layouts). De todos modos, en la práctica el título es determinado en el contenido de las vistas más que en layouts. Para resolver este problema, [[yii\web\View]] provee la propiedad [[yii\web\View::title|title]] para que puedas pasar información del título desde el contenido de la vista a los layouts. Toda página Web debería tener un título. Normalmente el tag de título es generado en [layout](#layouts). De todos modos, en la práctica
el título es determinado en el contenido de las vistas más que en layouts. Para resolver este problema, [[yii\web\View]] provee
la propiedad [[yii\web\View::title|title]] para que puedas pasar información del título desde el contenido de la vista a los layouts.
Para utilizar esta característica, en cada contenido de la vista, puedes definir el título de la siguiente manera: Para utilizar esta característica, en cada contenido de la vista, puedes definir el título de la siguiente manera:
```php ```php
<?php <?php
$this->title = 'Mi título de página'; $this->title = 'Título de mi página';
?> ?>
``` ```
@ -403,11 +571,13 @@ Entonces en el layout, asegúrate de tener el siguiente código en la sección `
``` ```
### Registrando Meta Tags <span id="registering-meta-tags"></span> ### Registrar Meta Tags <span id="registering-meta-tags"></span>
Las páginas Web usualmente necesitan generar varios meta tags necesarios por diferentes grupos (ej. Facebook, motores de búsqueda, etc). Cómo los títulos de página, los meta tags aparecen en la sección `<head>` y son usualmente generado en los layouts. Las páginas Web usualmente necesitan generar varios meta tags necesarios para diferentes grupos. Cómo los títulos de página, los meta tags
aparecen en la sección `<head>` y son usualmente generado en los layouts.
Si quieres especificar cuáles meta tags generar en las vistas, puedes llamar a [[yii\web\View::registerMetaTag()]] dentro de una de ellas, como se muestra a continuación: Si quieres especificar cuáles meta tags generar en las vistas, puedes llamar a [[yii\web\View::registerMetaTag()]]
dentro de una de ellas, como se muestra a continuación:
```php ```php
<?php <?php
@ -415,25 +585,31 @@ $this->registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php'
?> ?>
``` ```
El código anterior registrará el meta tag "keywords" a través del componente view. El meta tag registrado no se renderiza hasta que finaliza el renderizado del layout. Para entonces, el siguiente código HTML será insertado en el lugar donde llamas a [[yii\web\View::head()]] en el layout, generando el siguiente HTML: El código anterior registrará el meta tag "keywords" a través del componente view. El meta tag registrado
no se renderiza hasta que finaliza el renderizado del layout. Para entonces, el siguiente código HTML será insertado
en el lugar donde llamas a [[yii\web\View::head()]] en el layout, generando el siguiente HTML:
```php ```php
<meta name="keywords" content="yii, framework, php"> <meta name="keywords" content="yii, framework, php">
``` ```
Ten en cuenta que si llamas a [[yii\web\View::registerMetaTag()]] varias veces, esto registrará varios meta tags, sin tener en cuenta si los meta tags son los mismo o no. Ten en cuenta que si llamas a [[yii\web\View::registerMetaTag()]] varias veces, esto registrará varios meta tags,
sin tener en cuenta si los meta tags son los mismo o no.
Para asegurarte de que sólo haya una instancia de cierto tipo de meta tag, puedes especificar una clave al llamar al método. Por ejemplo, el siguiente código registra dos meta tags "description", aunque sólo el segundo será renderizado. Para asegurarte de que sólo haya una instancia de cierto tipo de meta tag, puedes especificar una clave al llamar al método.
Por ejemplo, el siguiente código registra dos meta tags "description", aunque sólo el segundo será renderizado.
```html ```php
$this->registerMetaTag(['name' => 'description', 'content' => 'Este es mi sitio Web cool hecho con Yii!'], 'description'); $this->registerMetaTag(['name' => 'description', 'content' => 'Este es mi sitio Web cool hecho con Yii!'], 'description');
$this->registerMetaTag(['name' => 'description', 'content' => 'Este sitio Web es sobre mapaches graciosos.'], 'description'); $this->registerMetaTag(['name' => 'description', 'content' => 'Este sitio Web es sobre mapaches graciosos.'], 'description');
``` ```
### Registrando Link Tags <span id="registering-link-tags"></span> ### Registrar Link Tags <span id="registering-link-tags"></span>
Tal como los [meta tags](#adding-meta-tags), los link tags son útiles en muchos casos, como personalizar el ícono (favicon) del sitio, apuntar a una fuente de RSS o delegar OpenID a otro servidor. Puedes trabajar con link tags, al igual que con meta tags, utilizando [[yii\web\View::registerLinkTag()]]. Por ejemplo, en el contenido de una vista, puedes registrar un link tag como se muestra a continuación: Tal como los [meta tags](#adding-meta-tags), los link tags son útiles en muchos casos, como personalizar el ícono (favicon) del sitio,
apuntar a una fuente de RSS o delegar OpenID a otro servidor. Puedes trabajar con link tags, al igual que con meta tags,
utilizando [[yii\web\View::registerLinkTag()]]. Por ejemplo, en el contenido de una vista, puedes registrar un link tag como se muestra a continuación:
```php ```php
$this->registerLinkTag([ $this->registerLinkTag([
@ -450,16 +626,20 @@ El resultado del código es el siguiente:
<link title="Noticias en Vivo de Yii" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/"> <link title="Noticias en Vivo de Yii" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/">
``` ```
Al igual que con [[yii\web\View::registerMetaTag()|registerMetaTags()]], puedes especificar una clave al llamar a [[yii\web\View::registerLinkTag()|registerLinkTag()]] para evitar registrar link tags repetidos. Al igual que con [[yii\web\View::registerMetaTag()|registerMetaTags()]], puedes especificar una clave al llamar
a [[yii\web\View::registerLinkTag()|registerLinkTag()]] para evitar registrar link tags repetidos.
## Eventos de Vistas <span id="view-events"></span> ## Eventos de Vistas <span id="view-events"></span>
Los [[yii\base\View|componentes de vistas]] disparan varios eventos durante el proceso de renderizado de la vista. Puedes responder a estos eventos para inyectar contenido a la vista o procesar el resultado de la renderización antes de que sea enviada al usuario final. Los [[yii\base\View|componentes de vistas]] disparan varios eventos durante el proceso de renderizado de la vista. Puedes responder
a estos eventos para inyectar contenido a la vista o procesar el resultado de la renderización antes de que sea enviada al usuario final.
- [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: disparado al principio del renderizado de un archivo en un controlador. Los manejadores de este evento pueden definir [[yii\base\ViewEvent::isValid]] como `false` para cancelar el proceso de renderizado. - [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: disparado al principio del renderizado de un archivo
- [[yii\base\View::EVENT_AFTER_RENDER|EVENT_AFTER_RENDER]]: disparado por la llamada a [[yii\base\View::beginPage()]] en layouts. en un controlador. Los manejadores de este evento pueden definir [[yii\base\ViewEvent::isValid]] como `false` para cancelar el proceso de renderizado.
Los manejadores de este evento pueden obtener el resultado de la renderización a través de [[yii\base\ViewEvent::output]] y entonces modificar esta propiedad para así cambiar el mismo. - [[yii\base\View::EVENT_AFTER_RENDER|EVENT_AFTER_RENDER]]: disparado luego de renderizar un archivo con la llamada de [[yii\base\View::afterRender()]].
Los manejadores de este evento pueden obtener el resultado del renderizado a través de [[yii\base\ViewEvent::output]] y modificar
esta propiedad para cambiar dicho resultado.
- [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]]: disparado por la llamada a [[yii\base\View::beginPage()]] en layouts. - [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]]: disparado por la llamada a [[yii\base\View::beginPage()]] en layouts.
- [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]]: disparado por la llamada a [[yii\base\View::endPage()]] en layouts. - [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]]: disparado por la llamada a [[yii\base\View::endPage()]] en layouts.
- [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]]: disparado por la llamada a [[yii\web\View::beginBody()]] en layouts. - [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]]: disparado por la llamada a [[yii\web\View::beginBody()]] en layouts.
@ -474,9 +654,10 @@ Por ejemplo, el siguiente código inyecta la fecha actual al final del body de l
``` ```
## Renderizando Páginas Estáticas <span id="rendering-static-pages"></span> ## Renderizar Páginas Estáticas <span id="rendering-static-pages"></span>
Con páginas estáticas nos referimos a esas páginas cuyo contenido es mayormente estático y sin necesidad de acceso a datos dinámicos enviados desde los controladores. Con páginas estáticas nos referimos a esas páginas cuyo contenido es mayormente estático y sin necesidad de acceso
a datos dinámicos enviados desde los controladores.
Puedes generar páginas estáticas utilizando un código como el que sigue dentro de un controlador: Puedes generar páginas estáticas utilizando un código como el que sigue dentro de un controlador:
@ -487,7 +668,9 @@ public function actionAbout()
} }
``` ```
Si un sitio Web contiene muchas páginas estáticas, resultaría tedioso repetir el mismo código en muchos lados. Para resolver este problema, puedes introducir una [acción independiente](structure-controllers.md#standalone-actions) llamada [[yii\web\ViewAction]] en el controlador. Por ejemplo, Si un sitio Web contiene muchas páginas estáticas, resultaría tedioso repetir el mismo código en muchos lados.
Para resolver este problema, puedes introducir una [acción independiente](structure-controllers.md#standalone-actions)
llamada [[yii\web\ViewAction]] en el controlador. Por ejemplo,
```php ```php
namespace app\controllers; namespace app\controllers;
@ -507,13 +690,16 @@ class SiteController extends Controller
} }
``` ```
Ahora, si creamos una vista llamada `about` bajo el directorio `@app/views/site/pages`, serás capáz de mostrarla en la siguiente URL: Ahora, si creamos una vista llamada `about` bajo el directorio `@app/views/site/pages`, serás capáz de mostrarla
en la siguiente URL:
``` ```
http://localhost/index.php?r=site/page&view=about http://localhost/index.php?r=site%2Fpage&view=about
``` ```
El parámetro `GET` `view` le comunica a [[yii\web\ViewAction]] cuál es la vista solicitada. La acción entonces buscará esta vista dentro de `@app/views/site/pages`. Puedes configurar la propiedad [[yii\web\ViewAction::viewPrefix]] para cambiar el directorio en el que se buscarán dichas páginas. El parámetro `GET` `view` le comunica a [[yii\web\ViewAction]] cuál es la vista solicitada. La acción entonces buscará
esta vista dentro de `@app/views/site/pages`. Puedes configurar la propiedad [[yii\web\ViewAction::viewPrefix]]
para cambiar el directorio en el que se buscarán dichas páginas.
## Buenas Prácticas <span id="best-practices"></span> ## Buenas Prácticas <span id="best-practices"></span>
@ -523,12 +709,15 @@ Las vistas son responsables de la presentación de modelos en el formato que el
* deberían contener principalmente sólo código de presentación, como HTML, y PHP simple para recorrer, dar formato y renderizar datos. * deberían contener principalmente sólo código de presentación, como HTML, y PHP simple para recorrer, dar formato y renderizar datos.
* no deberían contener código que realiza consultas a la base de datos. Ese tipo de código debe ir en los modelos. * no deberían contener código que realiza consultas a la base de datos. Ese tipo de código debe ir en los modelos.
* deberían evitar el acceso directo a datos del `request`, como `$_GET` y/o `$_POST`. Esto es una responsabilidad de los controladores. * deberían evitar el acceso directo a datos del `request`, como `$_GET` y/o `$_POST`. Esto es una responsabilidad de los controladores.
Si se necesitan datos del `request`, deben ser inyectados a la vista desde el controlador. Si se necesitan datos del `request`, deben ser inyectados a la vista desde el controlador.
* pueden leer propiedades del modelo, pero no debería modificarlas. * pueden leer propiedades del modelo, pero no debería modificarlas.
Para hacer las vistas más manejables, evita crear vistas que son demasiado complejas o que contengan código redundante. Puedes utilizar estas técnicas para alcanzar dicha meta: Para hacer las vistas más manejables, evita crear vistas que son demasiado complejas o que contengan código redundante.
Puedes utilizar estas técnicas para alcanzar dicha meta:
* utiliza [layouts](#layouts) para representar secciones comunes (ej. encabezado y footer de la página). * utiliza [layouts](#layouts) para representar secciones comunes (ej. encabezado y footer de la página).
* divide una vista compleja en varias más simples. Las vistas pequeñas pueden ser renderizadas y unidas una mayor utilizando los métodos de renderización antes descritos. * divide una vista compleja en varias más simples. Las vistas pequeñas pueden ser renderizadas y unidas una mayor
utilizando los métodos de renderización antes descritos.
* crea y utiliza [widgets](structure-widgets.md) como bloques de construcción de la vista. * crea y utiliza [widgets](structure-widgets.md) como bloques de construcción de la vista.
* crea y utilizar helpers para transformar y dar formato a los datos en la vista. * crea y utilizar helpers para transformar y dar formato a los datos en la vista.

11
docs/guide-es/test-functional.md

@ -0,0 +1,11 @@
Tests Funcionales
=================
> Note: Esta sección se encuentra en desarrollo.
- [Tests Funcionales de Codeception](http://codeception.com/docs/04-FunctionalTests)
Ejecutar test funcionales de templates básicos y avanzados
----------------------------------------------------------
Por favor consulta las instrucciones provistas en `apps/advanced/tests/README.md` y `apps/basic/tests/README.md`.

118
docs/guide-es/tutorial-yii-integration.md

@ -1,23 +1,27 @@
Trabajando con código de terceros Trabajar con código de terceros
================================= ===============================
De tiempo en tiempo, puede necesitar usar algún código de terceros en sus aplicaciones Yii. O puedes querer usar Yii como una librería en otros sistemas de terceros. En esta sección, te enseñaremos cómo conseguir estos objetivos. De tiempo en tiempo, puede necesitar usar algún código de terceros en sus aplicaciones Yii. O puedes querer
utilizar Yii como una librería en otros sistemas de terceros. En esta sección, te enseñaremos cómo conseguir estos objetivos.
## Usando librerías de terceros en Yii <span id="using-libs-in-yii"></span> Utilizar librerías de terceros en Yii <span id="using-libs-in-yii"></span>
-------------------------------------
Para usar una librería en una aplicación Yii, primeramente debes de asegurarte que las clases een la librería son incluidas adecuadamente o pueden ser cargadas de forma automática.
Para usar una librería en una aplicación Yii, primeramente debes de asegurarte que las clases en la librería
son incluidas adecuadamente o pueden ser cargadas de forma automática.
### Usando Paquetes de Composer <span id="using-composer-packages"></span> ### Usando Paquetes de Composer <span id="using-composer-packages"></span>
Muchas librerías de terceros son liberadas en términos de paquetes [Composer](https://getcomposer.org/). Muchas librerías de terceros son liberadas en términos de paquetes [Composer](https://getcomposer.org/).
Puedes instalar este tipo de librerias siguiendo dos sencillos pasos: Puedes instalar este tipo de librerías siguiendo dos sencillos pasos:
1. modificar el fichero `composer.json` de tu aplicación y especificar que paquetes Composer quieres instalar. 1. modificar el fichero `composer.json` de tu aplicación y especificar que paquetes Composer quieres instalar.
2. ejecuta `composer install` para instalar los paquetes específicados. 2. ejecuta `composer install` para instalar los paquetes especificados.
Las clases en los paquetes Composer instalados pueden ser autocargados usando el cargador automatizado de Composer autoloader. Asegúrate que el fichero [script de entrada](structure-entry-scripts.md) de tu aplicación contiene las siguientes líneas para instalar el cargador automático de Composer: Las clases en los paquetes Composer instalados pueden ser autocargados usando el cargador automatizado de Composer autoloader.
Asegúrate que el fichero [script de entrada](structure-entry-scripts.md) de tu aplicación contiene las siguientes líneas
para instalar el cargador automático de Composer:
```php ```php
// instalar el cargador automático de Composer // instalar el cargador automático de Composer
@ -27,15 +31,21 @@ require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php'); require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
``` ```
### Usando librerías Descargadas <span id="using-downloaded-libs"></span> ### Usando librerías Descargadas <span id="using-downloaded-libs"></span>
Si la librería no es liberada como un paquete de Composer, debes de seguir sus instrucciones de instalación para instalarla. Si la librería no es liberada como un paquete de Composer, debes de seguir sus instrucciones de instalación para instalarla.
En muchos casos, puedes necesitar descargar manualmente el fichero de la versión y desempaquetarlo en el directorio `BasePath/vendor` , donde `BasePath` representa el [camino base (base path)](structure-applications.md#basePath) de tu aplicación. En muchos casos, puedes necesitar descargar manualmente el fichero de la versión y desempaquetarlo en el directorio `BasePath/vendor`,
donde `BasePath` representa el [camino base (base path)](structure-applications.md#basePath) de tu aplicación.
Si la librería lleva su propio cargador automático (autoloader), puedes instalarlo en [script de entrada](structure-entry-scripts.md) de tu aplicación. Es recomendable que la instalación se termine antes de incluir el fichero `Yii.php` de forma que el cargador automático tenga precedencia al cargar de forma automática las clases. Si la librería lleva su propio cargador automático (autoloader), puedes instalarlo en [script de entrada](structure-entry-scripts.md) de tu aplicación.
Es recomendable que la instalación se termine antes de incluir el fichero `Yii.php` de forma que el cargador automático tenga precedencia al cargar
de forma automática las clases.
Si la librería no provee un cargador automático de clases, pero la denominación de sus clases sigue el [PSR-4](http://www.php-fig.org/psr/psr-4/), puedes usar el cargador automático de Yii para cargar de forma automática las clases. Todo lo que necesitas es declarar un [alias raiz](concept-aliases.md#defining-aliases) para cada espacio de nombres (namespace) raiz usado en sus clases. Por ejemplo, asume que has instalado una librería en el directorio `vendor/foo/bar`, y que las clases de la librería están bajo el espacio de nombres raiz `xyz`. Puedes incluir el siguiente código en la configuración de tu aplicación: Si la librería no provee un cargador automático de clases, pero la denominación de sus clases sigue el [PSR-4](http://www.php-fig.org/psr/psr-4/),
puedes usar el cargador automático de Yii para cargar de forma automática las clases. Todo lo que necesitas
es declarar un [alias raíz](concept-aliases.md#defining-aliases) para cada espacio de nombres (namespace) raiz usado en sus clases. Por ejemplo,
asume que has instalado una librería en el directorio `vendor/foo/bar`, y que las clases de la librería están bajo el espacio de nombres raiz `xyz`.
Puedes incluir el siguiente código en la configuración de tu aplicación:
```php ```php
[ [
@ -45,30 +55,61 @@ Si la librería no provee un cargador automático de clases, pero la denominaci
] ]
``` ```
Si ninguno de lo anterior es el caso, estaría bien que la librería dependa del camino de inclusión (include path) de configuración de PHP para localizar correctamente e incluir los ficheros de las clases. Simplemente siguiendo estas instrucciones de cómo configurar el camino de inclusión de PHP. Si ninguno de lo anterior es el caso, estaría bien que la librería dependa del camino de inclusión (include path) de configuración de PHP
para localizar correctamente e incluir los ficheros de las clases. Simplemente siguiendo estas instrucciones de cómo configurar el camino de inclusión de PHP.
En el caso más grave en el que la librería necesite incluir cada uno de sus ficheros de clases, puedes usar el siguiente método para incluir las clases según se pidan: En el caso más grave en el que la librería necesite incluir cada uno de sus ficheros de clases, puedes usar el siguiente método
para incluir las clases según se pidan:
* Identificar que clases contiene la librería. * Identificar que clases contiene la librería.
* Listar las clases y el camino a los ficheros correspondientes en `Yii::$classMap` en el script de entrada [script de entrada](structure-entry-scripts.md) de la aplicación. Por ejemplo, * Listar las clases y el camino a los archivos correspondientes en `Yii::$classMap` en el script de entrada [script de entrada](structure-entry-scripts.md)
de la aplicación. Por ejemplo,
```php ```php
Yii::$classMap['Class1'] = 'path/to/Class1.php'; Yii::$classMap['Class1'] = 'path/to/Class1.php';
Yii::$classMap['Class2'] = 'path/to/Class2.php'; Yii::$classMap['Class2'] = 'path/to/Class2.php';
``` ```
## Usando Yii en Sistemas de Terceros <span id="using-yii-in-others"></span> Utilizar Yii en Sistemas de Terceros <span id="using-yii-in-others"></span>
------------------------------------
Debido a que Yii provee muchas posibilidades excelentes, a veces puedes querer usar alguna de sus características para permitir el desarrollo o mejora de sistemas de terceros, como es WordPress, Joomla, o aplicaciones desarrolladas usando otros frameworks de PHP. Por ejemplo, puedes queres usar la clase [[yii\helpers\ArrayHelper]] o usar la característica [Active Record](db-active-record.md) en un sistema de terceros. Para lograr este objetivo, principalmente necesitas realizar dos pasos: instalar Yii , e iniciar Yii. Debido a que Yii provee muchas posibilidades excelentes, a veces puedes querer usar alguna de sus características para permitir
el desarrollo o mejora de sistemas de terceros, como es WordPress, Joomla, o aplicaciones desarrolladas usando otros frameworks de PHP.
Por ejemplo, puedes querer utilizar la clase [[yii\helpers\ArrayHelper]] o usar la característica [Active Record](db-active-record.md)
en un sistema de terceros. Para lograr este objetivo, principalmente necesitas realizar dos pasos:
instalar Yii , e iniciar Yii.
Si el sistema de terceros usa Composer para manejar sus dependencias, simplemente ejecuta estos comandos para instalar Yii: Si el sistema de terceros usa Composer para manejar sus dependencias, simplemente ejecuta estos comandos
para instalar Yii:
composer global require "fxp/composer-asset-plugin:~1.1.1"
composer require yiisoft/yii2
composer install
El primer comando instala el [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/),
que permite administrar paquetes bower y npm a través de Composer. Incluso si sólo quieres utilizar la capa de base de datos
u otra característica de Yii no relacionada a assets, requiere que instales el paquete composer de Yii.
Si quieres utilizar la [publicación de Assets de Yii](structure-assets.md) deberías agregar también la siguiente configuración
a la sección `extra` de tu `composer.json`:
```json
{
...
"extra": {
"asset-installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
}
}
``` ```
composer require "yiisoft/yii2:*"
composer install
```
En otro caso, puedes [descargar](http://www.yiiframework.com/download/) el fichero de la edición de Yii y desempaquetarla en el directorio `BasePath/vendor`. Visita también la [sección de cómo instalar Yii](start-installation.md#installing-via-composer) para más información
sobre Composer y sobre cómo solucionar posibles problemas que surjan durante la instalación.
En otro caso, puedes [descargar](http://www.yiiframework.com/download/) el archivo de la edición de Yii
y desempaquetarla en el directorio `BasePath/vendor`.
Después, debes de modificar el script de entrada de sistema de terceros para incluir el siguiente código al principio: Después, debes de modificar el script de entrada de sistema de terceros para incluir el siguiente código al principio:
@ -79,24 +120,32 @@ $yiiConfig = require(__DIR__ . '/../config/yii/web.php');
new yii\web\Application($yiiConfig); // No ejecutes run() aquí new yii\web\Application($yiiConfig); // No ejecutes run() aquí
``` ```
Como puedes ver, el código anterior es muy similar al que puedes ver en [script de entrada](structure-entry-scripts.md) de una aplicación típica. La única diferencia es que después de que se crea la instancia de la aplicación, el método `run()` no es llamado. Esto es así porque llamando a `run()`, Yii se haría cargo del control del flujo de trabajo del manejo de las peticiones, lo cual no es necesario en este caso por estar ya es manejado por la aplicación existente. Como puedes ver, el código anterior es muy similar al que puedes ver en [script de entrada](structure-entry-scripts.md)
de una aplicación típica. La única diferencia es que después de que se crea la instancia de la aplicación, el método `run()` no es llamado.
Esto es así porque llamando a `run()`, Yii se haría cargo del control del flujo de trabajo del manejo de las peticiones,
lo cual no es necesario en este caso por estar ya es manejado por la aplicación existente.
Como en una aplicación Yii, debes configurar la instancia de la aplicación basándose en el entorno que se está ejecutando del sistema de terceros. Por ejemplo, para usar la característica [Active Record](db-active-record.md) , necesitas configurar `db` [componente de la aplicación](structure-application-components.md) con los parámetros de la conexión de base de datos usados por el sistema de terceros. Como en una aplicación Yii, debes configurar la instancia de la aplicación basándose en el entorno que se está
ejecutando del sistema de terceros. Por ejemplo, para usar la característica [Active Record](db-active-record.md), necesitas configurar
el [componente de la aplicación](structure-application-components.md) `db` con los parámetros de la conexión a la BD del sistema de terceros.
Ahora puedes usar muchas características provistas por Yii. Por ejemplo, puedes crear clases Active Record y usarlas para trabajar con bases de datos. Ahora puedes usar muchas características provistas por Yii. Por ejemplo, puedes crear clases Active Record y usarlas
para trabajar con bases de datos.
## Usando Yii 2 con Yii 1 <span id="using-both-yii2-yii1"></span> Utilizar Yii 2 con Yii 1 <span id="using-both-yii2-yii1"></span>
------------------------
Si estaba usando Yii 1 previamente, es como si tuvieras una aplicación Yii 1 funcionando. En vez de reescribir toda la aplicación en Yii 2, puedes solamente mejorarla usando alguna de las características sólo disponibles en Yii 2.
Si estaba usando Yii 1 previamente, es como si tuvieras una aplicación Yii 1 funcionando. En vez de reescribir
toda la aplicación en Yii 2, puedes solamente mejorarla usando alguna de las características sólo disponibles en Yii 2.
Esto se puede lograr tal y como se describe abajo. Esto se puede lograr tal y como se describe abajo.
> Note: Yii 2 requiere PHP 5.4 o superior. Debes de estar seguro que tanto tu servidor como la aplicación existente lo soportan. > Note: Yii 2 requiere PHP 5.4 o superior. Debes de estar seguro que tanto tu servidor como la aplicación
> existente lo soportan.
Primero, instala Yii 2 en tu aplicación siguiendo las instrucciones descritas en la [última subsección](#using-yii-in-others). Primero, instala Yii 2 en tu aplicación siguiendo las instrucciones descritas en la [última subsección](#using-yii-in-others).
Segundo,modifica el script de entrada de la aplicación como sigue, Segundo, modifica el script de entrada de la aplicación como sigue,
```php ```php
// incluir la clase Yii personalizada descrita debajo // incluir la clase Yii personalizada descrita debajo
@ -112,7 +161,6 @@ Yii::createWebApplication($yii1Config)->run();
``` ```
Debido a que ambos Yii 1 y Yii 2 tiene la clase `Yii` , debes crear una versión personalizada para combinarlas. Debido a que ambos Yii 1 y Yii 2 tiene la clase `Yii` , debes crear una versión personalizada para combinarlas.
El código anterior incluye el fichero con la clase `Yii` personalizada, que tiene que ser creada como sigue. El código anterior incluye el fichero con la clase `Yii` personalizada, que tiene que ser creada como sigue.
```php ```php
@ -128,15 +176,17 @@ class Yii extends \yii\BaseYii
} }
Yii::$classMap = include($yii2path . '/classes.php'); Yii::$classMap = include($yii2path . '/classes.php');
// registrar el autoloader de Yii2 autoloader via Yii1 // registrar el autoloader de Yii 2 vía Yii 1
Yii::registerAutoloader(['Yii', 'autoload']); Yii::registerAutoloader(['Yii', 'autoload']);
// crear el contenedor de inyección de dependencia // crear el contenedor de inyección de dependencia
Yii::$container = new yii\di\Container; Yii::$container = new yii\di\Container;
``` ```
¡Esto es todo!. Ahora, en cualquier parte de tu código, puedes usar `Yii::$app` para acceder a la instancia de la aplicación de Yii 2, mientras `Yii::app()` proporciona la instancia de la aplicación de Yii 1 : ¡Esto es todo!. Ahora, en cualquier parte de tu código, puedes usar `Yii::$app` para acceder a la instancia de la aplicación de Yii 2,
mientras `Yii::app()` proporciona la instancia de la aplicación de Yii 1 :
```php ```php
echo get_class(Yii::app()); // genera 'CWebApplication' echo get_class(Yii::app()); // genera 'CWebApplication'
echo get_class(Yii::$app); // genera 'yii\web\Application' echo get_class(Yii::$app); // genera 'yii\web\Application'
``` ```

Loading…
Cancel
Save