【问题标题】:Using Phalcon Tags to dynamically load CSS and Javascript files使用 Phalcon 标签动态加载 CSS 和 Javascript 文件
【发布时间】:2012-11-07 00:35:23
【问题描述】:

我猜这个问题的结果可能和How do I use "Main Layout" views in a multi module Phalcon application?一样

我的 Main Layout 视图具有整个应用程序的基本 html 结构,并且我使用 controller layout 视图来呈现该控制器的内容。我相信到目前为止我做得对吗?

但现在我需要在 Main Layout 视图中加载与该模块控制器相关的特定 JS 和 CSS 文件。

目前我将所有 CSS 和 JS 加载到我的 Main Layout 文件中,但这完全违背了多模块方法。每个模块都应该能够加载 css/js 文件,而无需修改核心布局文件。

理想情况下,我希望采用与设置页面标题相同的方法

控制器: Phalcon\Tag::setStylesheetLink("http://fonts.googleapis.com/css?family=Rosario", false);

视图: echo Phalcon\Tag::getStylesheetLink();

有没有其他我可能会错过的方法来完成这个?

【问题讨论】:

    标签: php phalcon


    【解决方案1】:

    目前没有办法创建某种排序功能(样式表按照您设置的顺序打印出来)或一个收集工具,您只需将样式表添加到\Phalcon\Tag::stylesheetLink() 就可以打印出来。

    但是,您可以使用如下自定义类来实现您所需要的:

    在你的 config.ini 中有这个部分

    [resource]
    css.bootstrap = "/public/css/bootstrap.css"
    css.index     = "/public/css/index.css"
    css.about     = "/public/css/about.css"
    css.contact   = "/public/css/contact.css"
    

    创建一个类\MyApp\Tag

    namespace MyApp;
    
    class Tag
    {
        private $_css = array();
    
        public function add($css)
        {
            $this->_css[$css] = true;
        }
    
        public function remove($css)
        {
            $this->_css[$css] = false;
        }
    
        public function clear()
        {
            $this->_css = array();
        }
    
        public function generate()
        {
            $config = \Phalcon\DI::getDefault()->get('config');
            $output = '';
    
            foreach ($this->_css as $css => $active)
            {
                if ($active)
                {
                    if (isset($config->resource->css->$css))
                    {
                        $output .= \Phalcon\Tag::stylesheetLink($config->resource->css->$css);
                }
            }
    
            return $output;
        }
    }
    

    然后在您的控制器中,您可以执行以下操作:

    $style = new \MyApp\Tag();
    $style->add('bootstrap');
    $style->add('about');
    
    $this->view->setVar('stylesheets', $style->generate();
    

    在你看来:

    <?php echo $stylesheets; ?>
    

    【讨论】:

    • 您好 Nikolaos,抱歉花了这么长时间才回复,我一直在处理项目。不幸的是,我在打电话时遇到问题。我应该将它添加到 DI 中吗?目前我只是像你上面所说的那样调用它,我的错误是:PHP 致命错误:找不到类'MyApp\Tag'。我显然用“MyApp”代替了我的应用程序的名称,但我想不出还有什么我做错了?
    • @Tim 您需要注册MyApp 命名空间,以便可以找到它。你可以给它起任何你喜欢的名字。如果您将其添加到 DI 容器中,您只需:$obj = \Phalcon\DI::getDefault()-&gt;get('mytag')。如果时间在这里不是问题,您可能要等到 12 月初,那里 0.7 出来了。此功能包含在该版本中。
    • 嗨 Nikolaos,我发现了问题,我没有在自动加载器中注册命名空间。太棒了,这个功能很快就会内置!!帮助我学习的快速问题。我在上面的类中遇到另一个致命错误,“在不在对象上下文中使用 $this”这一行:foreach ($this->_css as $css => $active)。我不明白这是怎么回事?非常感谢您的见解。
    • 确认!我的错。 $this 在静态类中不存在。让我快速更改代码。
    • @Tim 已更正。 generate 函数不应是静态的。
    【解决方案2】:

    这是一种手动操作 js 和 css 文件资产顺序的方法。

    首先,在控制器中添加 css 和 js 路径时,使用自动 Phalcon\Assets\Collection 容器来存储您的临时资产:

    $this->assets->addJs('js/bootstrap-multiselect.js');
    $this->assets->addCss('css/bootstrap-multiselect.css');
    

    在所有控制器扩展的自定义 BaseController 中,添加一个 afterExecuteRoute() 公共方法:

    /**
     * stuff to do after a route has been executed
     * this is where we attach standard js and css assets
     * */
    public function afterExecuteRoute(){
        // wait to rebuild assets until after the dispatcher is finished
        if( ! $this->dispatcher->isFinished() ){
            return;
        }
        ...
    }
    

    一旦我们确定当前路由已完成执行,我们就可以从 Phalcon\Assets\Manager 中的自动 js 和 css 集合中提取临时资产,将它们附加到我们的常见资产文件列表、订单和对它们进行去重,然后将它们放入新的自定义集合中:

    // get list of js files added to the standard js collection
    $append_js = array();
    forEach( $this->assets->getJs() as $js){
        $append_js[] = $js->getPath();
    }
    // declare paths to common js assets
    $js_assets = array(
        'js/jquery-2.1.1.min.js',
        'js/jquery-ui.min.js',
        'js/bootstrap.min.js',
    );
    // merge common paths with ad-hoc paths
    $js_assets = array_merge( $js_assets, $append_js );
    $js_assets = array_unique( $js_assets ); // dedup
    // add js assets to a new collection
    $js_collection = $this->assets->collection('header_js');
    forEach( $js_assets as $js_path ){
        $js_collection->addJs( $js_path );
    }
    

    将 css 资源重新构建到新集合中的工作方式相同:

    // get list of css files added to the standard css collection
    $append_css = array();
    forEach( $this->assets->getCss() as $css ){
        $append_css[] = $css->getPath();
    }
    // declare paths to common css assets
    $css_assets = array(
        'css/jquery-ui.min.css',
        'css/jquery-ui.theme.min.css',
        'css/jquery-ui.structure.min.css',
        'css/bootstrap.min.css',
        'css/bootstrap-theme.min.css',
        'css/main.css',
    );
    // merge common paths with ad-hoc paths
    $css_assets = array_merge( $css_assets, $append_css );
    $css_assets = array_unique( $css_assets ); // dedup
    // add css assets to a new collection
    $css_collection = $this->assets->collection('header_css');
    forEach( $css_assets as $css_path ){
        $css_collection->addCss( $css_path );
    }
    

    最后,当您在模板中输出 js 和 css 资产时,输出新的自定义集合,而不是 Phalcon\Assets\Manager 自动创建的默认集合:

    {{ getDoctype() }}
    <html>
        <head>
            {{ tag.getTitle() }}
            {{ assets.outputCss( 'header_css' ) }}
            {{ assets.outputJs( 'header_js' ) }}
        </head>
    

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 2016-03-27
      • 2021-01-13
      • 2017-04-10
      • 2011-04-22
      • 2010-09-23
      相关资源
      最近更新 更多