another classic project directory for your project .
this is a portable version for yii1- WebApplicationEnd to yii2 .
Requirements ¶
yii2
Usage ¶
config your web.php file as following :
'id' => 'basic',
'basePath' => dirname(__DIR__),
'language'=>'zh-CN',
'bootstrap' => [
'log',
],
'as modulePathChanger'=>[
'class' => 'app\behaviors\WebApplicationEndBehavior',
],
the extension code :
<?php
/**
* User: yiqing
*/
namespace app\behaviors;
use Yii ;
use yii\base\Module ;
use yii\base\Application;
use yii\base\BootstrapInterface;
// used by WebApplicationEndBehavior class
use yii\base\Behavior;
use yii\base\Event;
class WebApplicationEndBehavior extends Behavior implements BootstrapInterface
{
/**
* @var string
*/
public $eventId = 'changeModulePaths';
/**
* Bootstrap method to be called during application bootstrap stage.
* @param Application $app the application currently running
*/
public function bootstrap($app)
{
$app->attachBehavior($this->eventId, new WebApplicationEndBehavior());
}
// Web application end's name.
private $_endName;
// Getter.
// Allows to get the current -end's name
// this way: Yii::app()->endName;
public function getEndName()
{
return $this->_endName;
}
// Run application's end.
public function runEnd($name)
{
$this->_endName = $name;
// Attach the changeModulePaths event handler
// and raise it.
Yii::$app->on($this->eventId, [$this, 'changeModulePaths']);
// $this->onModuleCreate = array($this, 'changeModulePaths');
$this->owner->trigger($this->eventId, new Event(array('sender' => $this->owner)));
$this->owner->run(); // Run application.
}
/**
* for backward compatible to the old version
* or Module instances are being initialized.
* This event should be raised when Application
*
* @param Event $event
*/
public function onModuleCreate($event)
{
$this->owner->trigger($this->eventId, $event);
}
/**
* onModuleCreate event handler.
* A sender must have controllerPath and viewPath properties.
*
* @param Event|Module $eventOrModule
*/
public function changeModulePaths( $eventOrModule)
{
/** @var Application|Module $app */
$appOrModule = null ;
if($eventOrModule instanceof Event){
$appOrModule = $eventOrModule->sender ;
}else{
$appOrModule = $eventOrModule ;
}
// custom initialization code goes here
$appEnd = Yii::$app->getEndName() ;
$appOrModule->controllerNamespace = str_replace('\controllers', sprintf('\controllers\%s',$appEnd),$appOrModule->controllerNamespace);
$appOrModule->viewPath .= DIRECTORY_SEPARATOR.$this->_endName;
}
}
We usually have backend and frontend functionality . the official directory structure is yii2-app-advanced project boilerplate template .
when we have multiple modules , you will have to separate the frontend and backend parts to different top directories (frontend and backend ) . say we will use a module which is developed by third party , a module is a logic unit of system . but you will have to separate the directory as two parts for deploy ,one for frontend another for backend .
the WebApplicationEndBehavior make your module as a logic and physical unit . the front and the admin functionality are mainly reflected in " controllers " and "views" , they will share the others things (models , components etc ..) .
the front entry script :
<?php
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
$config = require(__DIR__ . '/../config/web.php');
$app = (new yii\web\Application($config));
// Yii::setAlias('@year',Yii::getAlias('@app/year')) ;
$app->runEnd('front');
the backend entry point (admin.php):
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
/** @var Composer\Autoload\ClassLoader() $loader */
$loader = require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
$config = require(__DIR__ . '/../config/back.php');
$app = (new yii\web\Application($config));
// $app = (new admin\web\Application($config));
$app->runEnd('back');
the back.php file will config the WebApplicationEnd same as the front config file (normally is the app/config/web.php)
now you will have two separate entry points for your system ,one is frontend application ,another is backend application .
modify your directory structure :
webroot/
web/
...
admin.php
index.php
components/
..
controllers/
/front
SiteController.php
/back
SiteController.php
views/
/front
/layouts
column1.php
column2.php
main.php
/site
/pages
about.php
contact.php
error.php
index.php
login.php
/back
/layouts
main.php
/site
error.php
index.php
login.php
the different from the normal parts is the controller namespace ,you should have to notice it :
namespace app\controllers\front;
use Yii;
...
class SiteController extends Controller
{
...
}
// back end controller have different namespace
namespace app\controllers\back;
use Yii;
...
class SiteController extends Controller
{
...
}
now if you want to apply it to the module , just do it like this .
this is my user module :
namespace app\modules\user;
use Yii ;
class Module extends \yii\base\Module
{
public $controllerNamespace = 'app\modules\user\controllers';
public function init()
{
parent::init();
if(\Yii::$app instanceof \yii\web\Application){
Yii::$app->changeModulePaths($this);
}
}
}
the controllerNamespace property should be given as normal .
for more detail knowledge you can refer here : Organize directories for applications with front-end and back-end using WebApplicationEnd behavior
bonus : your will have the gii support naturally
Resources ¶
external resources for this extension
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.