phptwitter-bootstrapyiiyii-modules

Unload bootstrap in error view of main site controller


My admin module is using bootstrap:

'admin'=>array(
        'preload'=>array('bootstrap'),
        'components'=>array(
            'bootstrap'=>array(
                'class'=>'ext.bootstrap.components.Bootstrap',
            ),
        )
    ),

But it also is using the error handler of the main site:

public function init() {
    $this->setImport(array(
        'admin.models.*',
        'admin.components.*',
    ));

    Yii::app()->setComponents(array(
       'errorHandler'=>array('errorAction'=>'site/error'),
    ));

    $this->layout = 'admin';
}

The problem is that when an error is generated, the bootstrap css is getting loaded screwing the layout out. How do I unload bootstrap just in the error action?


Solution

  • In general to unload a component, you can use setComponent, passing the 2nd parameter as null. An example:

    Yii::app()->getModule('admin')->setComponent('bootstrap', null);
    

    However in your case, the version of bootstrap-extension you are using, already registers the css/js as soon as the component is loaded1. Therefore even if you unload the component, the bootstrap css will still be included and ofcourse styles will still be applied.

    But we can remove the css/js registered by bootstrap, and thus remove the effect of the bootstrap component. The simplest way to do this is by resetting the clientScript as already discussed in comments, and the best place to reset the clientScript is in the actionError() like so:

    public function actionError() {
        if($error=Yii::app()->errorHandler->error) {
            Yii::app()->clientScript->reset();
            // ... more code ...
        }
    } 
    

    Why this will work is because, most of the register* functions to register css/js will be encountered in the views, and layouts, so any css/js registered there will be loaded, but bootstrap will be omitted. Moreover any widgets that you might be using, will register their css/js only when they are encountered by render.


    1See extensions/bootstrap/components/Bootstrap.php's init():

    if ($this->coreCss !== false)
        $this->registerCoreCss();
    
    if ($this->responsiveCss !== false)
        $this->registerResponsiveCss();
    
    if ($this->yiiCss !== false)
        $this->registerYiiCss();
    
    if ($this->enableJS !== false)
        $this->registerCoreScripts();
    

    With newer versions (since 1.0.1) of the extension, you have to register the css/js explicitly.