Search

Does anybody know a way to check if a file has already been added to the head of a backend page? I’ve a field extension where I’m adding a javascript file to the head like this:

 $this->_engine->Page->addScriptToHead(URL . '/extensions/mediathek/assets/mediathek.js', 101);

If I use multiple instances of this field the script gets added multiple times which results in a lot of errors.

Any help appreciated.

I came up with the following solution:

        $script = false;
        foreach($this->_engine->Page->_head as $element) {
            if($element->getAttribute('src') == URL . '/extensions/mediathek/assets/jquery-ui.js') {
                $script = true;
            }
        }
        if(!$script) {
            $this->_engine->Page->addScriptToHead(URL . '/extensions/mediathek/assets/jquery-ui.js', 100);
        }

Yep that’s what I would have suggested!

Perhaps you could wrap this into a function and include in the core? I imagine this would be useful for others too.

In fact, this brings up the issue of JS libraries again. Some time ago I proposed a single extension that bundles all of the major libraries people may wish to use (Prototype, Scriptaculous, jQuery UI etc.) and other extensions can call this extension and trigger them being added to the head.

What about changing class.htmlpage.php from:

    function addScriptToHead($path, $position=NULL){            
        $script = new XMLElement('script');
        $script->setSelfClosingTag(false);
        $script->setAttributeArray(array('type' => 'text/javascript', 'src' => $path));
        return $this->addElementToHead($script, $position);
    }

    function addStylesheetToHead($path, $type='screen', $position=NULL){
        $link = new XMLElement('link');
        $link->setAttributeArray(array('rel' => 'stylesheet', 'type' => 'text/css', 'media' => $type, 'href' => $path));
        return $this->addElementToHead($link, $position);
    }

to:

    function addScriptToHead($path, $position=NULL, $duplicate=true){
        if($duplicate == false) $presence = $this->checkElementsInHead($path, 'src');
        if(!$presence) {
            $script = new XMLElement('script');
            $script->setSelfClosingTag(false);
            $script->setAttributeArray(array('type' => 'text/javascript', 'src' => $path));
            return $this->addElementToHead($script, $position);
        }
    }

    function addStylesheetToHead($path, $type='screen', $position=NULL, $duplicate=true){
        if($duplicate == false) $presence = $this->checkElementsInHead($path, 'href');
        if(!$presence) {
            $link = new XMLElement('link');
            $link->setAttributeArray(array('rel' => 'stylesheet', 'type' => 'text/css', 'media' => $type, 'href' => $path));
            return $this->addElementToHead($link, $position);
        }
    }

    function checkElementsInHead($path, $attr){
        foreach($this->_head as $element) {
            if($element->getAttribute($attr) == $path) return true;
        }   
    }

Nothing would change for existing extensions but it would be possible to avoid duplicated scripts by adding a false statement like that:

$this->_engine->Page->addScriptToHead(URL . '/extensions/mediathek/assets/jquery-ui.js', 100, false);

That would work in principle, but if two extensions both use jQuery UI then they will bundle them separately. The paths will be different, so both jQuery UI scripts would be added to the head.

Ah, you’re right. Ideas?
Should we split up the URL and just compare file names?

What about this change? It now compares file names instead of full paths:

    function checkElementsInHead($path, $attr){
        foreach($this->_head as $element) {
            $current = explode('/', $element->getAttribute($attr));
            $new = explode('/', $path);
            if($current[count($current) - 1] == $new[count($new) - 1]) return true;
        }   
    }

There is a function basename() wich does exactly what you are trying (stripping directories and returning just the filename).

Well, that happens when an art historian tries to code ;)
So it should be like this?

    function checkElementsInHead($path, $attr){
        foreach($this->_head as $element) {
            if(basename($element->getAttribute($attr)) == basename($path)) return true;
        }   
    }

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details