Fecshop 2016-07-08 09:16:04 7162次浏览 3条评论 3 1 0

fecshop 使用了多模板view文件优先级加载,在view和layout文件比较容易解决

原文链接:

yii2 多模板路径优先级加载view方式下- js和css 的解决

比较难弄的是js和css部分,用yii2提供的yii\web\AssetBundle; 做了很多尝试都没有解决,最后自己写了一个来最终实现多模板下 js和css,也根据模板路径优先级下载。

首先说一下多模板路径,下面有多个模板路径,按照优先级依次如下:

@appfront/theme/terry/theme01/

@fecshop/theme/base/front/

@fecshop/theme/base/base/

如果我要加载的view文件为 cms/index/index, 首先查看 @appfront/theme/terry/theme01/cms/index/index.php文件是否存在,如果不存在,则查看@fecshop/theme/base/front/cms/index/index.php,如果还不存在,则看文件@fecshop/theme/base/base/cms/index/index.php 是否存在,如果不存在则报错返回。

上面是多模板的思路,为了是解决view文件,在fecshop系统模板升级和用户二次开发模板的矛盾冲突。

现在我想要css和js也这样,通过优先级加载css和js,

下面是我的实现:定义组件配置 :


          'asset' => [
            'class' =>  'fecshop\services\page\Asset',
            # js config
            'jsOptions'  => [
              # js config 1
              [
                'options' => [
                  'position' =>  'POS_END',
                //  'condition'=> 'lt IE 9',
                ],
                'js'  =>[
                  'js/jquery-3.0.0.min.js',
                  'js/js.js',
                ],
              ],
              # js config 2
              [
                'options' => [
                  'condition'=> 'lt IE 9',
                ],
                'js'  =>[
                  'js/ie9js.js'
                ],
              ],
            ],
            # css config
            'cssOptions'  => [
              # css config 1.
              [
                'css'  =>[
                  'css/style.css',
                  'css/ie.css',
                ],
              ],
              
              # css config 2.
              [
                'options' => [
                  'condition'=> 'lt IE 9',
                ],
                'css'  =>[
                  'css/ltie9.css',
                ],
                
              ],
              
            ],
            
            //'cssOptions' => [
            //  'condition'
            //],
            //'jsOptions' => [
            //  'position' =>  'POS_END',
            //]
            
          ],

  1. 组件部分:

    <?php
    /**
     * FecShop file.
     *
     * @link http://www.fecshop.com/
     * @copyright Copyright (c) 2016 FecShop Software LLC
     * @license http://www.fecshop.com/license/
     */
    namespace fecshop\services\page;
    use Yii;
    use yii\base\Component;
    use yii\helpers\ArrayHelper;
    use yii\helpers\Url;
    /**
     * Breadcrumbs services
     * @author Terry Zhao <2358269014@qq.com>
     * @since 1.0
     extends AssetBundle
     */
    class Asset extends Component
    {
      public $cssOptions;
      public $jsOptions; 
      /**
       * 在模板路径下的相对文件夹。
       * 譬如模板路径为@fecshop/app/theme/base/front
       * 那么js,css路径默认为@fecshop/app/theme/base/front/assets
       */
      public $defaultDir = 'assets';
        /**
       * 文件路径默认放到模板路径下面的assets里面
       */
      public function register($view){
        $assetArr = [];
        $themeDir = Yii::$app->page->theme->getThemeDirArr();
        if( is_array($themeDir) && !empty($themeDir)){
          if( is_array($this->jsOptions) && !empty($this->jsOptions)){
            foreach($this->jsOptions as $jsOption){
              if( isset($jsOption['js']) && is_array($jsOption['js']) && !empty($jsOption['js'])){
          
                foreach($jsOption['js'] as $jsPath){
                  foreach($themeDir as $dir){
                    $dir = $dir.'/'.$this->defaultDir.'/';
                    $jsAbsoluteDir = $dir.$jsPath;
                    if(file_exists($jsAbsoluteDir)){
                        $assetArr[$dir]['jsOptions'][] = [
                        'js'     =>  $jsPath,
                        'options'   =>  $this->initOptions($jsOption['options']),
                      ];
                      break;
                    }
                  }
                }
              }
            }  
          }
          
          if( is_array($this->cssOptions) && !empty($this->cssOptions)){
            foreach($this->cssOptions as $cssOption){
              if( isset($cssOption['css']) && is_array($cssOption['css']) && !empty($cssOption['css'])){
                foreach($cssOption['css'] as $cssPath){    
                  foreach($themeDir as $dir){
                    $dir = $dir.'/'.$this->defaultDir.'/';
                    $cssAbsoluteDir = $dir.$cssPath;
                    if(file_exists($cssAbsoluteDir)){
                      $assetArr[$dir]['cssOptions'][] = [
                        'css'     =>  $cssPath,
                        'options'   =>  $this->initOptions($cssOption['options']),
                      ];
                      break;
                    }
                  }
                }
              }
            }  
          }
        }
        if(!empty($assetArr)){
          foreach($assetArr as $fileDir=>$as){
            $cssConfig = $as['cssOptions'];
            $jsConfig = $as['jsOptions'];
            $publishDir = $view->assetManager->publish($fileDir);
            if(!empty($jsConfig) && is_array($jsConfig)){
              foreach($jsConfig as $c){
                $view->registerJsFile($publishDir[1].'/'.$c['js'],$c['options']);
              }
            }
            if(!empty($cssConfig) && is_array($cssConfig)){
              foreach($cssConfig as $c){
                $view->registerCssFile($publishDir[1].'/'.$c['css'],$c['options']);
              }
            }
          }
        }
      }
      
      
      public function initOptions($options){
        if(isset($options['position'])){
          if($options['position'] == 'POS_HEAD'){
            $options['position'] =  \yii\web\View::POS_HEAD;
          }else if($options['position'] == 'POS_END'){
            $options['position'] =  \yii\web\View::POS_END;
          }
        }
        return $options;
      }
    }

上面的 Yii::$app->page->theme->getThemeDirArr() 表示得到多模板路径数组。

在layout文件中使用



    \Yii::$app->page->asset->register($this);

经过测试,可以在多个模板路径的assets下面查找js,找到后返回,找不到,继续到下一个模板路径中找js或者css文件。最后发布。

觉得很赞
您需要登录后才可以评论。登录 | 立即注册