@@ -27,8 +27,7 @@ Las propiedades del widget son fácilmente modificables porque la clase se extie
...
@@ -27,8 +27,7 @@ Las propiedades del widget son fácilmente modificables porque la clase se extie
Mientras que los componentes son muy potentes, son un poco más pesados que los objetos normales, debido al hecho de que necesitan más memoria y tiempo de CPU para poder soportar [eventos](concept-events.md) y [comportamientos](concept-behaviors.md) en particular.
Mientras que los componentes son muy potentes, son un poco más pesados que los objetos normales, debido al hecho de que necesitan más memoria y tiempo de CPU para poder soportar [eventos](concept-events.md) y [comportamientos](concept-behaviors.md) en particular.
Si tus componentes no necesitan estas dos características, deberías considerar extender tu componente directamente de [[yii\base\Object]] en vez de [[yii\base\Component]]. De esta manera harás que tus componentes sean mucho más eficientes que objetos PHP normales, pero con el añadido soporte para [propiedades](concept-properties.md).
Si tus componentes no necesitan estas dos características, deberías considerar extender tu componente directamente de [[yii\base\Object]] en vez de [[yii\base\Component]]. De esta manera harás que tus componentes sean mucho más eficientes que objetos PHP normales, pero con el añadido soporte para [propiedades](concept-properties.md).
Cuando extiendes tu clase de [[yii\base\Component]] o [[yii\base\Object]], se recomienda que sigas las siguientes
Cuando extiendes tu clase de [[yii\base\Component]] o [[yii\base\Object]], se recomienda que sigas las siguientes convenciones:
convenciones:
- Si sobrescribes el constructor, especifica un parámetro `$config` como el *último* parámetro del constructor, y después pasa este parámetro al constructor de la clase "padre".
- Si sobrescribes el constructor, especifica un parámetro `$config` como el *último* parámetro del constructor, y después pasa este parámetro al constructor de la clase "padre".
- Siempre llama al constructor del "padre" al *final* de su propio constructor.
- Siempre llama al constructor del "padre" al *final* de su propio constructor.
Un localizador de servicios es un objeto que sabe cómo proporcionar todo tipo de servicios (o componentes) que puede necesitar una aplicación. Dentro de un localizador de servicios, existe en cada componente como una única instancia, únicamente identificado por un ID. Se utiliza el ID para recuperar un componente desde el localizador de servicios.
En Yii, un localizador de servicio es simplemente una instancia de [[yii\di\ServiceLocator]], o de una clase hija.
El localizador de servicio más utilizado en Yii es el objeto *aplicación*, que se puede acceder a través de `\Yii::$app`. Los servicios que prestá son llamadas *componentes de la aplicación*, como los componentes `request`, `response`, and `urlManager`. Usted puede configurar estos componentes, o incluso cambiarlos por sus propias implementaciones fácilmente a través de la funcionalidad proporcionada por el localizador de servicios.
Además del objeto de aplicación, cada objeto módulo es también un localizador de servicios.
Para utilizar un localizador de servicios, el primer paso es registrar los componentes de la misma. Un componente se puede registrar a través de [[yii\di\ServiceLocator::set()]]. El código siguiente muestra diferentes maneras de registrarse componentes:
```php
useyii\di\ServiceLocator;
useyii\caching\FileCache;
$locator=newServiceLocator;
// register "cache" using a class name that can be used to create a component
$locator->set('cache','yii\caching\ApcCache');
// register "db" using a configuration array that can be used to create a component
$locator->set('db',[
'class'=>'yii\db\Connection',
'dsn'=>'mysql:host=localhost;dbname=demo',
'username'=>'root',
'password'=>'',
]);
// register "search" using an anonymous function that builds a component
$locator->set('search',function(){
returnnewapp\components\SolrService;
});
// register "pageCache" using a component
$locator->set('pageCache',newFileCache);
```
Una vez que el componente se ha registrado, usted puede acceder a él utilizando su ID, en una de las dos formas siguientes:
```php
$cache=$locator->get('cache');
// or alternatively
$cache=$locator->cache;
```
Como puede observarse, [[yii\di\ServiceLocator]] le permite acceder a un componente como una propiedad utilizando el ID de componente. Cuando acceda a un componente, por primera vez, [[yii\di\ServiceLocator]] utilizará la información de registro de componente para crear una nueva instancia del componente y devolverlo. Más tarde, si se accede de nuevo al componente, el localizador de servicio devolverá la misma instancia.
Usted puede utilizar [[yii\di\ServiceLocator::has()]] para comprobar si un ID de componente ya ha sido registrada.
Si llama [[yii\di\ServiceLocator::get()]] con una identificación válida, se produce una excepción.
Debido a que los localizadores de servicios a menudo se crean con [configuraciones](concept-configurations.md), se proporciona una propiedad que puede escribir el nombre [[yii\di\ServiceLocator::setComponents()|components]]. Esto le permite configurar y registrar varios componentes a la vez. El siguiente código muestra un arreglo de configuración que se puede utilizar para configurar una aplicación, al mismo tiempo que el registro de la "db", "cache" y "buscar" componentes:
@@ -8,8 +8,7 @@ Son manejadas por el componente de la aplicación [[yii\web\View|view]], el cual
...
@@ -8,8 +8,7 @@ Son manejadas por el componente de la aplicación [[yii\web\View|view]], el cual
## Creando Vistas <a name="creating-views"></a>
## Creando Vistas <a name="creating-views"></a>
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
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.
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
...
@@ -35,8 +34,7 @@ $this->title = 'Login';
...
@@ -35,8 +34,7 @@ $this->title = 'Login';
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)
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).
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.
...
@@ -57,8 +55,7 @@ use yii\helpers\Html;
...
@@ -57,8 +55,7 @@ use yii\helpers\Html;
</div>
</div>
```
```
Para mostrar contenido HTML, utiliza [[yii\helpers\HtmlPurifier]] para filtrarlo antes. Por ejemplo, el siguiente
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:
código filtra el contenido del post antes de mostrarlo en pantalla:
```php
```php
<?php
<?php
...
@@ -77,23 +74,16 @@ use yii\helpers\HtmlPurifier;
...
@@ -77,23 +74,16 @@ use yii\helpers\HtmlPurifier;
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,
* 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]].
donde `ControllerID` se refiere al [ID del controlador](structure-controllers.md#routes). Por ejemplo, si
* 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.
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()]]
Puedes personalizar estos directorios por defecto sobrescribiendo el método [[yii\base\ViewContextInterface::getViewPath()]] en el controlador o widget necesario.
Puedes renderizar vistas desde [controllers](structure-controllers.md), [widgets](structure-widgets.md), o cualquier
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:
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:
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,
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.
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.
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:
...
@@ -209,23 +198,17 @@ Un nombre de vista es resuelto a su correspondiente ruta de archivo siguiendo la
...
@@ -209,23 +198,17 @@ Un nombre de vista es resuelto a su correspondiente ruta de archivo siguiendo la
* 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|view path 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 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 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 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`.
* 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`.
* 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 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`.
De acuerdo a las reglas mencionadas, al llamar a `$this->render('view')` en el controlador `app\controllers\PostController`
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`.
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`.
### Accediendo a Datos en la Vista <a name="accessing-data-in-views"></a>
### Accediendo a Datos en la Vista <a name="accessing-data-in-views"></a>
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.
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`.
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`.
```php
```php
echo$this->render('report',[
echo$this->render('report',[
...
@@ -261,14 +244,15 @@ Entonces, en el archivo del [layout](#layouts), que es también una vista, puede
...
@@ -261,14 +244,15 @@ Entonces, en el archivo del [layout](#layouts), que es también una vista, puede
])?>
])?>
```
```
## Layouts <a name="layouts"></a>
## Layouts <a name="layouts"></a>
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.
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]].
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.
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.
...
@@ -299,43 +283,29 @@ use yii\helpers\Html;
...
@@ -299,43 +283,29 @@ 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>`,
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()]].
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.
-[[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.
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::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.
-[[yii\base\View::endPage()|endPage()]]: Este método debería ser llamado al final del layout.
-[[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.
Esto dispara el evento [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]], indicando el final de la página.
-[[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\web\View::head()|head()]]: Este método debería llamarse dentro de la sección `<head>` de una página HTML.
-[[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.
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 <a name="accessing-data-in-layouts"></a>
### Accediendo a Datos en Layouts <a name="accessing-data-in-layouts"></a>
Dentro de un layout, tienes acceso a dos variables predefinidas: `$this` y `$content`. La primera se refiere
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.
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.
Si quieres acceder a otros datos en los layouts, debes utilizar el modo pull que fue descrito en la sub-sección
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).
[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).
Como se describe en la sub-sección [Renderizando en Controllers](#rendering-in-controllers), cuando renderizas una vista
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.
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]].
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.
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
namespaceapp\controllers;
namespaceapp\controllers;
...
@@ -350,31 +320,20 @@ class PostController extends Controller
...
@@ -350,31 +320,20 @@ 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í
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.
utilizar un layout en particular para esos controladores.
Dado que la propiedad `layout` puede ser configurada en diferentes niveles (controladores, módulos, aplicación),
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.
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
- 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.
el [[yii\base\Controller::module|módulo]] 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.
- 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
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:
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á
- 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`.
buscado bajo el [[yii\base\Application::layoutPath|layout path]] de la aplicación, que es por defecto
- 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]].
`@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`.
...
@@ -382,10 +341,7 @@ Si el valor de layout no contiene una extensión de tipo de archivo, utilizará
...
@@ -382,10 +341,7 @@ Si el valor de layout no contiene una extensión de tipo de archivo, utilizará
A veces podrías querer anidar un layout dentro de otro. Por ejemplo, en diferentes secciones de un sitio Web, podrías
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:
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:
@@ -395,19 +351,14 @@ estructura general de la página en HTML5. Esto es posible llamando a los métod
...
@@ -395,19 +351,14 @@ estructura general de la página en HTML5. Esto es posible llamando a los métod
<?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
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.
[[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 <a name="using-view-components"></a>
## Utilizando Componentes de Vista <a name="using-view-components"></a>
Los [[yii\base\View|componentes de vista]] proveen características relacionadas a las vistas. Aunque puedes obtener componentes de 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:
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
[
[
...
@@ -435,9 +386,7 @@ Puedes también utilizar frecuentemente el siguiente menor pero útil grupo de c
...
@@ -435,9 +386,7 @@ Puedes también utilizar frecuentemente el siguiente menor pero útil grupo de c
### Definiendo Títulos de Página <a name="setting-page-titles"></a>
### Definiendo Títulos de Página <a name="setting-page-titles"></a>
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
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.
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:
...
@@ -456,11 +405,9 @@ Entonces en el layout, asegúrate de tener el siguiente código en la sección `
...
@@ -456,11 +405,9 @@ Entonces en el layout, asegúrate de tener el siguiente código en la sección `
### Registrando Meta Tags <a name="registering-meta-tags"></a>
### Registrando Meta Tags <a name="registering-meta-tags"></a>
Las páginas Web usualmente necesitan generar varios meta tags necesarios por diferentes grupos (ej. Facebook, motores de búsqueda, etc).
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.
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()]]
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:
dentro de una de ellas, como se muestra a continuación:
El código anterior registrará el meta tag "keywords" a través del componente view. El meta tag registrado no
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:
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:
Ten en cuenta que si llamas a [[yii\web\View::registerMetaTag()]] varias veces, esto registrará varios meta tags,
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.
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.
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.
Por ejemplo, el siguiente código registra dos meta tags "description", aunque sólo el segundo será renderizado.
```html
```html
$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');
...
@@ -490,9 +433,7 @@ $this->registerMetaTag(['name' => 'description', 'content' => 'Este sitio Web es
...
@@ -490,9 +433,7 @@ $this->registerMetaTag(['name' => 'description', 'content' => 'Este sitio Web es
### Registrando Link Tags <a name="registering-link-tags"></a>
### Registrando Link Tags <a name="registering-link-tags"></a>
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
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:
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([
...
@@ -509,8 +450,7 @@ El resultado del código es el siguiente:
...
@@ -509,8 +450,7 @@ El resultado del código es el siguiente:
<linktitle="Noticias en Vivo de Yii"rel="alternate"type="application/rss+xml"href="http://www.yiiframework.com/rss.xml/">
<linktitle="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
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.
[[yii\web\View::registerLinkTag()|registerLinkTag()]] para evitar registrar link tags repetidos.
## Eventos de Vistas <a name="view-events"></a>
## Eventos de Vistas <a name="view-events"></a>
...
@@ -547,8 +487,7 @@ public function actionAbout()
...
@@ -547,8 +487,7 @@ public function actionAbout()
}
}
```
```
Si un sitio Web contiene muchas páginas estáticas, resultaría tedioso repetir el mismo código en muchos lados.
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,
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
namespaceapp\controllers;
namespaceapp\controllers;
...
@@ -587,11 +526,9 @@ Las vistas son responsables de la presentación de modelos en el formato que el
...
@@ -587,11 +526,9 @@ Las vistas son responsables de la presentación de modelos en el formato que el
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.
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:
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.