2 Similar Widgets With 2 Different Css On 1 Site

hi,

is it possible to use 2 instances of a widget with 2 different css on 1 site?

for example:




<?php

  $this->widget('application.extensions.mbmenu.MbMenu',array(

      'items' => $items1;

      'cssFile' => Yii::app()->request->baseUrl . '/css/mbmenu1.css',

  ));


  $this->widget('application.extensions.mbmenu.MbMenu',array(

      'items' => $items2;

      'cssFile' => Yii::app()->request->baseUrl . '/css/mbmenu2.css',

  ));

?>




yii includes both css files perfectly… but the problme is, that both css definitions overwrite each other, because both contains the same css classes

you understnad my problem?

is there any solution?

you must put both widgets in some element with differtent class/id and prepare css rules based on that context:




<div id="firstMenu">

<?php

  $this->widget('application.extensions.mbmenu.MbMenu',array(

      'items' => $items1;

      'cssFile' => Yii::app()->request->baseUrl . '/css/mbmenu1.css',

  ));

?>

</div>

<div id="secondMenu">

<?php

  $this->widget('application.extensions.mbmenu.MbMenu',array(

      'items' => $items2;

      'cssFile' => Yii::app()->request->baseUrl . '/css/mbmenu2.css',

  ));

?>

</div>



and corresponding css:




#firstMenu .nav {

}


#secondMenu .nav {

}

...



There is however problem with mbmenu widget which disallows it to be used more than once on one page - it creates html code with "id" attributes which are not unique. This makes your page not compliant with html standards if you use this widget twice or more.

thanks for your answer

damn… i thought about this solution, but i hoped for soemthing better

ohh thanks for lettign me know about this… any adwice for a good alternative drop-down-menu component?

i don’t know if anyone else needs this…

i wrote a widget, which do all this #id stuff in css automatically:


class CssSection extends CWidget {


    public $tagName = 'div';

    public $id;

    public $cssFile;


    public function init() {

        parent::init();

        $this->publishCssFile();

        echo CHtml::openTag($this->tagName, array('id' => $this->id));

    }


    private function publishCssFile() {

        //path stuff

        $cssPathParts = pathinfo($this->cssFile);

        $cssFileName = $this->id . '_' . $cssPathParts['filename'];

        $cssSourceDir = $cssPathParts['dirname'];

        $cssRuntimeDir = Yii::app()->getRuntimePath() . '/' . $cssFileName;


        //only process css stuff when folder does not exist or in debug mode

        $refresh=!is_dir($cssRuntimeDir) || YII_DEBUG == TRUE;

        if ($refresh) {

            Yii::import('application.vendors.*');


            //autoloader for the use-statements in Sabberworm

            spl_autoload_register(function($class) {

                        require_once ($class . ".php");

                    });

            $cssParser = new Sabberworm\CSS\Parser(file_get_contents($this->cssFile));

            $cssDocument = $cssParser->parse();


            $this->setPrefixIdsToCssBlocks($cssDocument, $this->id);

            $urls = $this->substituteUrlsInCss($cssDocument);


            //create dir if not exist

            if (!is_dir($cssRuntimeDir)) {

                mkdir($cssRuntimeDir);

            }


            //save css document ot file

            $cssFileContent = $cssDocument->__toString();

            file_put_contents($cssRuntimeDir . '/' . $cssFileName . ".css", $cssFileContent);


            //copy linked resources to runtime folder

            foreach ($urls as $url => $newUrlId) {

                copy($cssSourceDir . '/' . $url, $cssRuntimeDir . '/' . $newUrlId);

            }


            //spl_autoload_register(array('YiiBase', 'autoload'));

        }

    

        //publish css and linked resources

        $cssAssetPath = Yii::app()->assetManager->publish($cssRuntimeDir,true,-1,$refresh);


        //

        echo '<link rel="stylesheet" type="text/css" href="' . $cssAssetPath . '/' . $cssFileName . '.css" />';

    }


    /**

     * adds a prefix before to every css block

     * 

     * @param type $cssDocument css documnt

     * @param type $prefixId prefix

     */

    private function setPrefixIdsToCssBlocks($cssDocument, $prefixId) {

        //add #id to all css blocks

        foreach ($cssDocument->getAllDeclarationBlocks() as $oBlock) {

            foreach ($oBlock->getSelectors() as $oSelector) {

                $oSelector->setSelector('#' . $prefixId . ' ' . $oSelector->getSelector());

            }

        }

    }


    /**

     * @param type $cssDocument css document

     * @return array (key = old url, value = new url id)

     */

    private function substituteUrlsInCss($cssDocument) {

        $urls = array();

        $urlId = 0;


        foreach ($cssDocument->getAllValues() as $value) {

            if ($value instanceof Sabberworm\CSS\Value\URL) {

                $url = $value->getURL();


                //remove quotes from url

                $url = str_replace('"', "", $url);

                $url = str_replace("'", "", $url);


                //evaluate new url id

                if (array_key_exists($url, $urls)) {

                    $newUrlId = $urls[$url];

                } else {

                    $urlPathParts = pathinfo($url);

                    $urlExtension = $urlPathParts['extension'];

                    $newUrlId = $urls[$url] = $urlId . '.' . $urlExtension;

                    $urlId++;

                }


                //change url to new url id

                $value->setURL(new Sabberworm\CSS\Value\String($newUrlId));

            }

        }

        return $urls;

    }


    public function run() {

        parent::run();

        echo CHtml::closeTag($this->tagName);

    }


}

it uses the Sabberworm CSS Parser (https://github.com/sabberworm/PHP-CSS-Parser)

it can be used like this:


$this->beginWidget('CssSection', array(

    'id' => 'menu2',

    'cssFile'=>Yii::app()->getBasePath() . '/../css/mbmenu_orig/mbmenu.css'));


    $this->widget('application.extensions.mbmenu.MbMenu', array(

        'items' => $this->menuItems,

    ));


$this->endWidget('CssSection');

this generates a surrounding div with a id (menu2) and creates a new css file with this ids (and publish it to assets)

any advices?