如何在Yii Framework中严格控制CSS文件的顺序

bcm*_*cfc 6 css yii

在Yii中,有许多不同的方法可以将CSS加入到您的页面中.

问题是,一旦你开始使用扩展,小部件,主题等,它们都有自己的样式表(足够公平),CSS处理和插入HTML的顺序根据它们是否设置在控制器,视图或布局,或正在使用Yii资产管理器或Yii包管理器.

最近,我们的Yii项目被改变为使用注册的包config/main.php,这样:

'clientScript'=>array(
        'packages'=> array(
            'theme'=>array(
                'basePath'=>'yii.themes.default',
                'css'=>array('css/reset.css','css/main.css','css/form.css'),
                'js'=>array('js/lib.js'),
                'depends'=>array('jquery'),
            ),
...
Run Code Online (Sandbox Code Playgroud)

这导致CSS文件中断,因为它被设计为覆盖网格视图样式,现在它被包含在CGridView样式表之前.

解决方案是在底部添加以下行layouts/main.php:

$path = Yii::getPathOfAlias('yii.themes.default').'/css/style.css';
$cssFile = Yii::app()->getAssetManager()->publish($path);
Yii::app()->getClientScript()->registerCssFile($cssFile);
Run Code Online (Sandbox Code Playgroud)

对我来说,这感觉就像一个不太完美的解决方案,我希望将来当我们忘记我们已经完成的工作时,我们可能会遇到问题,或者我们必须完全用不同的主题或不同的项目做类似的事情.

有什么更好的方法可以有效地管理CSS,因为它可以从很多不同的来源提供?

编辑:

我正在考虑扩展CClientScript以提供"覆盖"类型的选项,您可以在其中指定一个CSS文件数组,您之后应该包含您正在注册的文件.感觉它可能有点片状但是......

bcm*_*cfc 5

我提出了以下解决方案,使用类似于z-index工作方式的方法.尽管如此,它并不完美.

样式表默认设置为优先级为0,您可以使用registerCssregisterCssFile将其设置为正整数或负整数.负整数将在CSS的其余部分之前插入文件,正整数将其发送到结尾.

config/main.php,设置clientScript以使用新类:

    'clientScript'=>array(
        'class' => 'components\ClientScript',
        ...
Run Code Online (Sandbox Code Playgroud)

components/ClientScript.php:

我正在玩这个想法,指定注册文件之间的依赖关系,而不是基于整数的优先级,但没有遵循它.我现在已经将代码保留在这里以防万一有人想要接受它.

class ClientScript extends CClientScript
{

    protected $dependencies = array();
    protected $priority = array();

    public function renderHead(&$output)
    {
        $cssFilesOrdered = array();
        $currentCssFiles = $this->cssFiles;

        if (!empty($this->priority)){
            # assign 0 to anything without a specific priority
            # can't do this in the register method because not every CSS file that ends up here used it
            $cssFilesWithPrioritySet = array_keys($this->priority);
            foreach ($currentCssFiles as $path => $v){
                if (!in_array($path, $cssFilesWithPrioritySet)){
                    $this->priority[$path] = 0;
                }
            }

            asort($this->priority);
            foreach ($this->priority as $path => $id){
                $cssFilesOrdered[$path] = $currentCssFiles[$path];
                unset($currentCssFiles[$path]);
            }
            # add any remaining CSS files that didn't have an order specified
            $cssFilesOrdered += $currentCssFiles;
        }

        if (!empty($cssFilesOrdered)){
            $this->cssFiles = $cssFilesOrdered;
        }

        parent::renderHead($output);
    }

    public function registerCssFile($url, $media = '', $order = null)
    {
        $this->setOrder($url, $order);
        return parent::registerCssFile($url, $media);
    }

    public function registerCss($id, $css, $media = '', $order = null)
    {
        $this->setOrder($id, $order);
        return parent::registerCss($id, $css, $media);
    }

    private function setOrder($identifier, $order)
    {
        if (!is_null($order)){
            if (is_array($order)){
                $this->dependencies[$identifier] = $order;
            } elseif (is_numeric($order)){
                $this->priority[$identifier] = $order;
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)