structure-modules.md 11.4 KB
Newer Older
1
Módulos
Larnu committed
2
=======
larnu committed
3 4 5 6 7 8
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.
Larnu committed
9 10 11

## Creación de Módulos<a name="creating-modules"></a>

larnu committed
12 13 14 15
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:
Larnu committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

```
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 <a name="module-classes"></a>

larnu committed
31 32 33 34 35
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.
Larnu committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

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 ...
    }
}
```

larnu committed
54 55
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()’:
Larnu committed
56 57 58 59 60 61 62 63 64 65

```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'));
}
```

larnu committed
66 67
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).
Larnu committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

```php
<?php
return [
    'components' => [
        // lista de configuraciones de componente
    ],
    'params' => [
        // lista de parámetros
    ],
];
```

### Controladores en Módulos <a name="controllers-in-modules"></a>

larnu committed
83 84 85 86 87
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:
Larnu committed
88 89 90 91 92 93 94 95 96 97 98 99

```php
namespace app\modules\forum\controllers;

use yii\web\Controller;

class PostController extends Controller
{
    // ...
}
```

larnu committed
100 101 102 103
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).
Larnu committed
104 105 106

### Vistas en Módulos <a name="views-in-modules"></a>

larnu committed
107 108 109 110 111
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.
Larnu committed
112

larnu committed
113 114 115 116
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.
Larnu committed
117 118 119

## Uso de los Módulos <a name="using-modules"></a>

larnu committed
120 121 122
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’:
Larnu committed
123 124 125 126 127 128 129 130 131 132 133 134

```php
[
    'modules' => [
        'forum' => [
            'class' => 'app\modules\forum\Module',
            // ... otras configuraciones para el módulo ...
        ],
    ],
]
```

larnu committed
135 136 137
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.
Larnu committed
138 139 140

### Rutas <a name="routes"></a>

larnu committed
141 142 143 144 145 146 147
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’.
Larnu committed
148 149 150

### Acceder a los Módulos <a name="accessing-modules"></a>

larnu committed
151 152
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:
Larnu committed
153 154 155 156 157

```php
$module = MyModuleClass::getInstance();
```

larnu committed
158 159 160 161
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.
Larnu committed
162

larnu committed
163 164 165 166
> Información: 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’.
Larnu committed
167 168 169 170

También se puede acceder a la instancia de un módulo usando las siguientes declaraciones:

```php
171
// obtiene el modulo hijo cuyo ID es “forum”
Larnu committed
172 173 174 175 176 177
$module = \Yii::$app->getModule('forum');

// obtiene el módulo al que pertenece la petición actual
$module = \Yii::$app->controller->module;
```

larnu committed
178 179
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.
Larnu committed
180

larnu committed
181 182
Una vez obtenida la instancia del módulo, se puede acceder a parámetros o componentes registrados con el módulo. Por 
ejemplo:
Larnu committed
183 184 185 186 187 188 189

```php
$maxPostCount = $module->params['maxPostCount'];
```

### Bootstrapping Módulos <a name="bootstrapping-modules"></a>

larnu committed
190 191 192
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.
Larnu committed
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209

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 <a name="nested-modules"></a>

larnu committed
210 211 212
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:
Larnu committed
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232

```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',
            ],
        ];
    }
}
```

larnu committed
233 234 235
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’. 
Larnu committed
236

larnu committed
237 238 239
> Información: 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.
Larnu committed
240 241 242

## Mejores Prácticas <a name="best-practices"></a>

larnu committed
243 244 245
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.
Larnu committed
246

larnu committed
247 248 249
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.