2

I'm using a layout override to modify the cart module for Virtuemart, but the ajax request deletes part of my code when it updates. Because of this, I would like to change not only the template, but also the javascript routine the module calls.

I could get the behavior I want quickly by altering the module itself, but I was wondering if I could clone the code (which is inside a js file, it is not a part of default.php) and place it inside the override, so that I don't have to fix it every time I update Virtuemart.

Is it possible? Any ideas?

2 Answers 2

2

Yes, and no...

Let's start with the "no" - The Joomla core devs have created a way to inject scripts, but no (API) way to remove them.

And, "Yes" , but it's complicated....

You'll need to create a Joomla system plugin to affect the removal.

If you do it any sooner than onBeforeCompileHead - you might end up with another script injecting it again.

This example just removes a script - because I'm injecting a new one elsewhere. You could modify this to remove and replace at the same time - but that's up to you to decide.

This is how I did it for a BS3 template I wrote. I really needed to ditch the BS 2.3 javascript and replace it with BS3 javascript. The plugin was written to accommodate removing multiple javascripts, although this example only shows one.

class PlgSystemRWBS3 extends JPlugin {

function onBeforeCompileHead() {
    $doc = JFactory::getDocument();
    $cfg = JFactory::getConfig();
    $min = $cfg->get('debug', 0, 'INTEGER') ? '' : '.min';
    $remove = array(
        '/media/jui/js/bootstrap'.$min.'.js'
    );
    $this->_removeScript($doc, $remove);
}

private function _removeScript($o, $remove) {
    $removed = false;
    foreach($remove as $r) {
        $found = preg_grep('/'.preg_quote($r,'/').'$/', array_keys($o->_scripts));
            if(count($found) > 0) {
                unset($o->_scripts[array_shift($found)]);
            }
    }
}
}
4
  • 1
    Food for thought: 3v4l.org/sgnYF Commented Jan 19, 2022 at 0:34
  • @mickmackusa - looks nice, but fails if you're trying to remove a specific script using its path. For example, if an extension is loading its own version of jquery and you prefer the built-in version - so you specify it with full path. Using your method, all files matching jquery.js would get removed.
    – Michael
    Commented Mar 15, 2022 at 4:06
  • Right, so using full paths makes it more reliable. 3v4l.org/QEJ09 Oh, I see, you are not necessarily using full paths -- you are using longer paths that end with. 3v4l.org/0QXaZ Commented Mar 15, 2022 at 4:21
  • 1
    @mickmackusa As far as Joomla is concerned, it's a full path from the web root, as JPATH::root(true) will be prepended to each item when the head is generated.
    – Michael
    Commented Mar 16, 2022 at 5:03
2

Sometimes the author of your component will provide a way to do such an override, so check the documentation first. If that is not possible, brute force works:

I recently solved this problem for myself by inserting a rule at the top of my .htaccess file on the server. Most Apache servers will handle this correctly. The rule would look like this:

Redirect 301 /components/path/to/your/script/thescript.js https://yourdomain.com/templates/your_template/html/js/thescript.js

The caveat is you need to remember that this exists. It will override any future updates to this script which the developer provides.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.