6

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'),
            ),
...

これにより、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);

私にとって、これは完璧とは言えない解決策のように感じます。将来、私たちがやったことを忘れたり、別のテーマや別のプロジェクトで同じようなことをしなければならないときに問題が発生する可能性があります。

非常に多くの異なるソースからCSSを提供できる場合、CSSを効果的に管理するためのより良い方法はありますか?

編集:

CClientScriptを拡張して、「オーバーライド」のようなオプションを提供することを検討しています。このオプションでは、登録するファイルの後に含める必要のあるCSSファイルの配列を指定できます。少し不安定な気がしますが...

4

2 に答える 2

5

z-indexの動作と同様のアプローチを使用して、次の解決策を考え出しました。どんなに完璧でもありません。

スタイルシートはデフォルトで優先度0に設定されており、andを使用してこれを正または負の整数に設定できregisterCssますregisterCssFile。負の整数はCSSの残りの部分の前にファイルを挿入し、正の整数はファイルを最後に送信します。

config/main.phpで、新しいクラスを使用するようにclientScriptを設定します。

    'clientScript'=>array(
        'class' => 'components\ClientScript',
        ...

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;
            }
        }
    }

}
于 2012-07-26T09:33:30.203 に答える
0

@bcmcfc関数を拡張するためのより良い方法は、優先順位のあるものが機能することを確認しながら、デフォルトの順序のままにすることだと思います。

ここでrenderHead()関数を変更します。

public function renderHead(&$output)
{
    $cssFilesOrdered = array();
    $currentCssFiles = $this->cssFiles;
    //print_r($currentCssFiles);
    if (!empty($this->priority))
    {
        // sort priority array according to value (priority number)
        asort($this->priority);
        $tmp = array_values($this->priority);
        $startPriority = $tmp[0];
        # 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);
        $startCounter = $startPriority-count($currentCssFiles);
        foreach ($currentCssFiles as $path => $v)
        {
            if (!in_array($path, $cssFilesWithPrioritySet))
            {
                $this->priority[$path] = $startCounter++;
            }
        }

        asort($this->priority);
        foreach ($this->priority as $path => $id)
        {
            $cssFilesOrdered[$path] = $currentCssFiles[$path];
            unset($currentCssFiles[$path]);
        }
    }

    if (!empty($cssFilesOrdered)){
        $this->cssFiles = $cssFilesOrdered;
    }
    # add any remaining CSS files that didn't have an order specified
    $cssFilesOrdered += $currentCssFiles;
    parent::renderHead($output);
}
于 2015-12-10T15:53:27.303 に答える