Yii2 Module Development

Yii2 provides a modular structure, allowing developers to create independent, reusable, and self-contained modules. A module in Yii2 is like a mini-application, having its own controllers, models, views, and configurations.

In this tutorial, we will cover:

  • Default behavior of Yii2 modules
  • Using a custom database connection inside a module
  • Adding a custom theme for a module

1. Creating a Basic Yii2 Module

1.1 Generate Module via Gii

1. Run Gii by visiting:

http://your-app.com/index.php?r=gii

2 Select Module Generator.

3. Set:

  • Module ID: admin
  • Module Namespace: app\modules\admin

4. Click Generate to create the module.

1.2 Manually Create Module Structure

Alternatively, create the module manually under modules/admin:

modules/
    admin/
        controllers/
            DefaultController.php
        models/
        views/
            default/
                index.php
        AdminModule.php

1.3 Define the Module Class

In modules/admin/AdminModule.php:

namespace app\modules\admin;

class AdminModule extends \yii\base\Module
{
    public $controllerNamespace = 'app\modules\admin\controllers';

    public function init()
    {
        parent::init();
        // Custom initialization code
    }
}

1.4 Create the Default Controller

In modules/admin/controllers/DefaultController.php:

namespace app\modules\admin\controllers;

use yii\web\Controller;

class DefaultController extends Controller
{
    public function actionIndex()
    {
        return $this->render('index');
    }
}

1.5 Create the Default View

In modules/admin/views/default/index.php:

<h1>Welcome to Admin Module</h1>

1.6 Register the Module in config/web.php

'modules' => [
    'admin' => [
        'class' => 'app\modules\admin\AdminModule',
    ],
],

Now, visit:

http://your-app.com/index.php?r=admin/default/index

You should see "Welcome to Admin Module".


2. Console Commands in Yii2 Module

Yii2 allows modules to have their own console commands for tasks like database migrations, cron jobs, and batch processing.

2.1 Define Console Commands in the Module

Modify AdminModule.php to set a separate namespace for console commands:

namespace app\modules\admin;

use Yii;

class AdminModule extends \yii\base\Module
{
    public $controllerNamespace = 'app\modules\admin\controllers';

    public function init()
    {
        parent::init();

        // If the request is coming from the console (CLI)
        if (Yii::$app->request->isConsoleRequest) {
            \Yii::configure($this, [
                'controllerNamespace' => 'app\modules\admin\commands'
            ]);
        }
    }
}

2.2 Create the Console Command Directory

Inside the admin module, create a commands directory:

modules/
    admin/
        commands/
            TestController.php

2.3 Create a Console Command

In modules/admin/commands/TestController.php:

namespace app\modules\admin\commands;

use yii\console\Controller;

class TestController extends Controller
{
    public function actionIndex()
    {
        echo "Admin module console command is working!\n";
    }
}

2.4 Run the Console Command

Navigate to your Yii2 project root and run:

php yii admin/test

Output:

Admin module console command is working!

This allows each module to have isolated CLI functionalities, making it useful for background jobs and scheduled tasks.


3. Database Configuration via main-local.php

Instead of hardcoding database configurations inside the module, we can use an external configuration file (main-local.php).

3.1 Load the Configuration in AdminModule.php

Modify AdminModule.php to include the external config file if it exists:

namespace app\modules\admin;

use Yii;

class AdminModule extends \yii\base\Module
{
    public $controllerNamespace = 'app\modules\admin\controllers';

    public function init()
    {
        parent::init();

        // Load local database config if available
        if (file_exists(__DIR__ . '/config/main-local.php')) {
            Yii::configure($this, require(__DIR__ . '/config/main-local.php'));
        }
    }
}

3.2 Create the main-local.php Configuration File

Inside modules/admin/config/main-local.php:

<?php

return [
    'components' => [
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=admin_db',
            'username' => 'root',
            'password' => 'Password#3',
            'charset' => 'utf8',
        ],
    ],
];

3.3 Use the Custom Database Connection in Models

Modify User.php in modules/admin/models/:

namespace app\modules\admin\models;

use Yii;
use yii\db\ActiveRecord;

class User extends ActiveRecord
{
    public static function getDb()
    {
        return \yii::$app->getModule('admin')->db;
    }

    public static function tableName()
    {
        return 'users';
    }
}

3.4 Test the Custom Database Connection

Modify DefaultController.php in modules/admin/controllers/:

use app\modules\admin\models\User;

public function actionUsers()
{
    $users = User::find()->all();
    return $this->render('users', ['users' => $users]);
}

Now, visit:

http://your-app.com/index.php?r=admin/default/users

This method ensures that database configurations are environment-specific and easier to manage.


4. Custom Theme & Layout for the Module

Each module can have its own theme, ensuring a separate UI layout and styling.

4.1 Define the Custom Theme in AdminModule.php

Modify AdminModule.php to configure the theme dynamically:

namespace app\modules\admin;

use Yii;

class AdminModule extends \yii\base\Module
{
    public $controllerNamespace = 'app\modules\admin\controllers';

    public function init()
    {
        parent::init();

        // Apply module-specific theme
        Yii::$app->view->theme = new \yii\base\Theme([
            'pathMap' => ['@app/views' => dirname(__FILE__) . '/themes/views'],
            'baseUrl' => dirname(__FILE__) . '/themes/views',
        ]);
    }
}

4.2 Create a Theme Folder for the Module

Inside modules/admin/themes/, create the structure:

modules/
    admin/
        themes/
            views/
                layouts/
                    main.php
        views/
            default/
                index.php

4.3 Define a Custom Layout for the Module

Create modules/admin/themes/views/layouts/main.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Admin Panel</title>
    <link rel="stylesheet" href="/css/admin.css">
</head>
<body>
    <header><h1>Admin Panel</h1></header>
    <div class="content">
        <?= $content ?>
    </div>
</body>
</html>

4.4 Modify Module Views 

Modify modules/admin/themes/views/default/index.php:

<h2>Welcome to the Admin Dashboard</h2>

4.5 Test the Custom Theme

Now, visit:

http://your-app.com/index.php?r=admin

Your module will now use the custom theme and layout.


5. Module-Level Access Control

Restrict access to the admin module using Yii2 Access Control Filter (ACF).

Modify AdminModule.php:

use yii\filters\AccessControl;

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::class,
            'only' => ['*'],
            'rules' => [
                [
                    'allow' => true,
                    'roles' => ['@'], // Only logged-in users
                ],
            ],
        ],
    ];
}

What We Achieved?

  • Basic Module Development – Created an admin module. 
  • Created Console Commands for the Module – Allowing CLI execution of module tasks
  • Configured Database via main-local.php – Making database settings environment-specific
  •  Implemented a Custom Theme & Layout – Keeping module UI separate from the main application
  • Access Control – Restricted module access to authenticated users.

This approach makes the Yii2 module more modular, scalable, and reusable.