mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-15 14:50:56 +08:00
250 lines
12 KiB
Markdown
250 lines
12 KiB
Markdown
Módulos
|
||
=======
|
||
Los módulos son unidades de software independientes que consisten en [modelos](structure-models.md),
|
||
[vistas](structure-views.md), [controladores](structure-controllers.md), y otros componentes de apoyo. Los usuarios
|
||
finales pueden acceder a los controladores de un módulo cuando éste está instalado en la
|
||
[aplicación](structure-applications.md). Por éstas razones, los módulos a menudo se considerados como
|
||
mini-aplicaciones. Los módulos difieren de las [aplicaciones](structure-applications.md) en que los módulos no pueden
|
||
ser desplegados solos y tienen que residir dentro de aplicaciones.
|
||
|
||
## Creación de Módulos<span id="creating-modules"></span>
|
||
|
||
Un módulo está organizado de tal manera que contiene un directorio llamado [[yii\base\Module::basePath|base path]] del
|
||
módulo. Dentro de este directorio, hay subdirectorios tales como 'controllers', 'models', 'views', que contienen
|
||
controladores, modelos, vistas y otro código, exactamente como una aplicación. El siguiente ejemplo muestra el
|
||
contenido dentro de un módulo:
|
||
|
||
```
|
||
forum/
|
||
Module.php archivo clase módulo
|
||
controllers/ contiene archivos de la clase controlador
|
||
DefaultController.php archivo clase controlador por defecto
|
||
models/ contiene los archivos de clase modelo
|
||
views/ contiene las vistas de controlador y los archivos de diseño
|
||
layouts/ contiene los archivos de diseño de las vistas
|
||
default/ contiene los archivos de vista del DefaultController
|
||
index.php archivo de vista del index
|
||
```
|
||
|
||
### Clases Módulo <span id="module-classes"></span>
|
||
|
||
Cada módulo debe tener una única clase módulo que extiende a [[yii\base\Module]]. La clase debe encontrarse
|
||
directamente debajo del [[yii\base\Module::basePath|base path]] y debe ser [autocargable](concept-autoloading.md).
|
||
Cuando se está accediendo a un módulo, se creará una única instancia de la clase módulo correspondiente. Como en las
|
||
[instancias de aplicación](structure-applications.md), las instancias de módulo se utilizan para compartir datos y
|
||
componentes de código dentro de los módulos.
|
||
|
||
El siguiente ejemplo muestra como podría ser una clase módulo.
|
||
|
||
```php
|
||
namespace app\modules\forum;
|
||
|
||
class Module extends \yii\base\Module
|
||
{
|
||
public function init()
|
||
{
|
||
parent::init();
|
||
|
||
$this->params['foo'] = 'bar';
|
||
// ... otro código de inicialización ...
|
||
}
|
||
}
|
||
```
|
||
|
||
Si el método 'init()' contiene mucho código de inicialización de las propiedades del módulo, también se puede guardar
|
||
en términos de configuración y cargarlo con el siguiente código ‘init()’:
|
||
|
||
```php
|
||
public function init()
|
||
{
|
||
parent::init();
|
||
// inicializa el módulo con la configuración cargada desde config.php
|
||
\Yii::configure($this, require __DIR__ . '/config.php');
|
||
}
|
||
```
|
||
|
||
donde el archivo de configuración ‘config.php’ puede contener el siguiente contenido, similar al de
|
||
[configuraciones de aplicación](structure-applications.md#application-configurations).
|
||
|
||
```php
|
||
<?php
|
||
return [
|
||
'components' => [
|
||
// lista de configuraciones de componente
|
||
],
|
||
'params' => [
|
||
// lista de parámetros
|
||
],
|
||
];
|
||
```
|
||
|
||
### Controladores en Módulos <span id="controllers-in-modules"></span>
|
||
|
||
Cuando se crean controladores en un modelo, una convención es poner las clases controlador debajo del sub-espacio de
|
||
nombres de ‘controllers’ del espacio de nombres de la clase módulo. Esto también significa que los archivos de la
|
||
clase controlador deben ponerse en el directorio ‘controllers’ dentro del [[yii\base\Module::basePath|base path]] del
|
||
módulo. Por ejemplo, para crear un controlador ‘post’ en el módulo ‘forum’ mostrado en la última subdivisión, se debe
|
||
declarar la clase controlador de la siguiente manera:
|
||
|
||
```php
|
||
namespace app\modules\forum\controllers;
|
||
|
||
use yii\web\Controller;
|
||
|
||
class PostController extends Controller
|
||
{
|
||
// ...
|
||
}
|
||
```
|
||
|
||
Se puede personalizar el espacio de nombres de las clases controlador configurando la propiedad
|
||
[[yii\base\Module::controllerNamespace]]. En el caso que alguno de los controladores esté fuera del espacio de
|
||
nombres, se puede hacer accesible configurando la propiedad [[yii\base\Module::controllerMap]], similar a
|
||
[como se hace en una aplicación](structure-applications.md#controller-map).
|
||
|
||
### Vistas en Módulos <span id="views-in-modules"></span>
|
||
|
||
Las vistas en un módulo deben alojarse en el directorio ‘views’ dentro del módulo del
|
||
[[yii\base\Module::basePath|base path]]. Las vistas renderizadas por un controlador en el módulo, deben alojarse en el
|
||
directorio ‘views/ControllerID’, donde el ‘ControllerID’ hace referencia al
|
||
[ID del controlador](structure-controllers.md#routes). Por ejemplo, si la clase controlador es ‘PostController’, el
|
||
directorio sería ‘views/post’ dentro del [[yii\base\Module::basePath|base path]] del módulo.
|
||
|
||
Un modulo puede especificar un [layout](structure-views.md#layouts) que se aplica a las vistas renderizadas por los
|
||
controladores del módulo. El layout debe alojarse en el directorio ‘views/layouts’ por defecto, y se puede configurar
|
||
la propiedad [[yii\base\Module::layout]] para apuntar al nombre del layout. Si no se configura la propiedad ‘layout’,
|
||
se usar el layout de la aplicación.
|
||
|
||
## Uso de los Módulos <span id="using-modules"></span>
|
||
|
||
Para usar un módulo en una aplicación, simplemente se tiene que configurar la aplicación añadiendo el módulo en la
|
||
propiedad [[yii\base\Application::modules|modules]] de la aplicación. El siguiente ejemplo de la
|
||
[configuración de la aplicación](structure-applications.md#application-configurations) usa el modelo ‘forum’:
|
||
|
||
```php
|
||
[
|
||
'modules' => [
|
||
'forum' => [
|
||
'class' => 'app\modules\forum\Module',
|
||
// ... otras configuraciones para el módulo ...
|
||
],
|
||
],
|
||
]
|
||
```
|
||
|
||
La propiedad [[yii\base\Application::modules|modules]] contiene un array de configuraciones de módulo. Cada clave del
|
||
array representa un *ID de módulo* que identifica de forma única el módulo de entre todos los módulos de la
|
||
aplicación, y el correspondiente valor del array es la [configuración](concept-configurations.md) para crear el módulo.
|
||
|
||
### Rutas <span id="routes"></span>
|
||
|
||
De Igual manera que el acceso a los controladores en una aplicación, las [rutas](structure-controllers.md#routes) se
|
||
utiliza para dirigirse a los controladores en un módulo. Una ruta para un controlador dentro de un módulo debe empezar
|
||
con el ID del módulo seguido por el ID del controlador y el ID de la acción. Por ejemplo, si una aplicación usa un
|
||
módulo llamado ‘forum’, la ruta ‘forum/post/index’ representaría la acción ‘index’ del controlador ‘post’ en el
|
||
módulo. Si la ruta sólo contiene el ID del módulo, entonces la propiedad [[yii\base\Module::defaultRoute]] que por
|
||
defecto es ‘default’, determinara que controlador/acción debe usarse. Esto significa que la ruta ‘forum’ representaría
|
||
el controlador ‘default’ en el módulo ‘forum’.
|
||
|
||
### Acceder a los Módulos <span id="accessing-modules"></span>
|
||
|
||
Dentro de un módulo, se puede necesitar obtener la instancia de la [clase módulo](#module-classes) para poder acceder
|
||
al ID del módulo, componentes del módulo, etc. Se puede hacer usando la siguiente declaración:
|
||
|
||
```php
|
||
$module = MyModuleClass::getInstance();
|
||
```
|
||
|
||
Dónde ‘MyModuleClass’ hace referencia al nombre de la clase módulo en la que estemos interesados. El método
|
||
‘getInstance()’ devolverá la instancia actualmente solicitada de la clase módulo. Si no se solicita el módulo, el
|
||
método devolverá nulo. Hay que tener en cuenta que si se crea una nueva instancia del módulo, esta será diferente a la
|
||
creada por Yii en respuesta a la solicitud.
|
||
|
||
> Info: Cuando se desarrolla un módulo, no se debe dar por sentado que el módulo usará un ID fijo. Esto se debe
|
||
a que un módulo puede asociarse a un ID arbitrario cuando se usa en una aplicación o dentro de otro módulo. Para
|
||
obtener el ID del módulo, primero se debe usar el código del anterior ejemplo para obtener la instancia y luego el
|
||
ID mediante ‘$modeule->id’.
|
||
|
||
También se puede acceder a la instancia de un módulo usando las siguientes declaraciones:
|
||
|
||
```php
|
||
// obtiene el modulo hijo cuyo ID es “forum”
|
||
$module = \Yii::$app->getModule('forum');
|
||
|
||
// obtiene el módulo al que pertenece la petición actual
|
||
$module = \Yii::$app->controller->module;
|
||
```
|
||
|
||
El primer ejemplo sólo es útil cuando conocemos el ID del módulo, mientras que el segundo es mejor usarlo cuando
|
||
conocemos los controladores que se están solicitando.
|
||
|
||
Una vez obtenida la instancia del módulo, se puede acceder a parámetros o componentes registrados con el módulo. Por
|
||
ejemplo:
|
||
|
||
```php
|
||
$maxPostCount = $module->params['maxPostCount'];
|
||
```
|
||
|
||
### Bootstrapping Módulos <span id="bootstrapping-modules"></span>
|
||
|
||
Puede darse el caso en que necesitemos que un módulo se ejecute en cada petición. El módulo [[yii\debug\Module|debug]]
|
||
es un ejemplo. Para hacerlo, tenemos que listar los IDs de los módulos en la propiedad
|
||
[[yii\base\Application::bootstrap|bootstrap]] de la aplicación.
|
||
|
||
Por ejemplo, la siguiente configuración de aplicación se asegura de que el módulo ‘debug’ siempre se cargue:
|
||
|
||
```php
|
||
[
|
||
'bootstrap' => [
|
||
'debug',
|
||
],
|
||
|
||
'modules' => [
|
||
'debug' => 'yii\debug\Module',
|
||
],
|
||
]
|
||
```
|
||
|
||
## Módulos anidados <span id="nested-modules"></span>
|
||
|
||
Los módulos pueden ser anidados sin límite de niveles. Es decir, un módulo puede contener un módulo y éste a la vez
|
||
contener otro módulo. Nombramos *padre* al primero mientras que al segundo lo nombramos *hijo*. Los módulos hijo se
|
||
tienen que declarar en la propiedad [[yii\base\Module::modules|modules]] de sus módulos padre. Por ejemplo:
|
||
|
||
```php
|
||
namespace app\modules\forum;
|
||
|
||
class Module extends \yii\base\Module
|
||
{
|
||
public function init()
|
||
{
|
||
parent::init();
|
||
|
||
$this->modules = [
|
||
'admin' => [
|
||
// debe considerarse usar un nombre de espacios más corto!
|
||
'class' => 'app\modules\forum\modules\admin\Module',
|
||
],
|
||
];
|
||
}
|
||
}
|
||
```
|
||
|
||
En un controlador dentro de un módulo anidado, la ruta debe incluir el ID de todos los módulos antecesores. Por
|
||
ejemplo, la ruta ‘forum/admin/dashboard/index’ representa la acción ‘index’ del controlador ‘dashboard’ en el módulo
|
||
‘admin’ que es el módulo hijo del módulo ‘forum’.
|
||
|
||
> Info: El método [[yii\base\Module::getModule()|getModule()]] sólo devuelve el módulo hijo que pertenece
|
||
directamente a su padre. La propiedad [[yii\base\Application::loadedModules]] contiene una lista de los módulos
|
||
cargados, incluyendo los hijos directos y los anidados, indexados por sus nombres de clase.
|
||
|
||
## Mejores Prácticas <span id="best-practices"></span>
|
||
|
||
Es mejor usar los módulos en grandes aplicaciones en las que sus funcionalidades puedan ser divididas en diferentes
|
||
grupos, cada uno compuesto por funcionalidades directamente relacionadas. Cada grupo de funcionalidades se puede
|
||
desarrollar como un módulo que puede ser desarrollado y mantenido por un programador o equipo específico.
|
||
|
||
Los módulos también son una buena manera de reutilizar código a nivel de grupo de funcionalidades. Algunas
|
||
funcionalidades de uso común, tales como la gestión de usuarios o la gestión de comentarios, pueden ser desarrollados
|
||
como módulos para que puedan ser fácilmente reutilizados en futuros proyectos.
|