Replace Magento JavaScript Includes (addJs)

I will keep it simple .... on my product pages I need to delete the prototype.js file and replace it with the latest prototype. So far, using local.xml, I have successfully replaced it using this:

<action method="removeItem"><type>js</type><name>prototype/prototype.js</name></action> <action method="addJs"><script>prototype/prototype-new.js</script></action> 

The problem is that now the prototype is loading below all other inclusions that stop it from working.

Is there a way to set the order of JavaScript using local.xml without having to delete and add each individual file again?

+7
source share
7 answers

You can use the params element, with the HTML attribute “data group” in it, Magento will put the elements with the “set” parameters after any elements without the “parameters”. You can use local.xml in your theme to ensure the order of these elements (I recommend Magento specify its standard files first):

 <action method="addJs"> <script>prototype/javascript0.js</script> <params><![CDATA[data-group="js002"]]></params> <!-- creates first group js002 --> </action> <action method="addJs"> <script>prototype/javascript1.js</script> <params><![CDATA[data-group="js002"]]></params> <!-- appends to created group js002, after javascript0 --> </action> <action method="addJs"> <script>prototype/javascript2.js</script> <params><![CDATA[data-group="js001"]]></params> <!-- creates first group js001 --> </action> <action method="addJs"> <script>prototype/javascript3.js</script> <params><![CDATA[data-group="js001"]]></params> <!-- appends to created group js001, after javascript2 --> </action> <action method="addJs"> <script>prototype/javascript4.js</script> <params><![CDATA[data-group="js002"]]></params> <!-- appends to created group js002, after javascript1 --> </action> <action method="addJs"> <script>prototype/javascript5.js</script> <!-- no params supplied, will be rendered before any groups --> </action> 

The order in which items with the params parameter are displayed only in the order in which the actions are performed. Elements are displayed grouped by the value "params", therefore, when the group "js001" is determined by the first action (javascript2.js), subsequent actions with the same group name will be added to this group, etc.

In the above example, the rendering order would look like this:

  • prototype / javascript5.js (without parameters, in the first place)
  • prototype / javascript0.js (first created parameter group "js002")
  • prototype / javascript1.js (first created parameter group "js002")
  • prototype / javascript4.js (first created parameter group "js002")
  • prototype / javascript2.js (second created parameter group "js001")
  • prototype / javascript3.js (second created parameter group "js001")

Elements added using addItem addJs, addCss, etc., are processed the same way, however they differ (and will be respectively grouped) by type (see order below), with each group in supergroups being internally ordered as explained above:

  • Js
  • skin_js
  • js_css
  • skin_css
+43
source

Mage_Page_Block_Html_Head $ _data; contains an array of these elements, so I think you can filter it for your own good. The default methods do not allow you to determine the order of added items.

+1
source

I understand that this post is quite old, but I stumbled upon it while researching this problem, so I realized why not.

Not sure if this is the most elegant solution, but its work is good enough for us.

Basically I created a new block in local.xml as follows: <block type="core/template" name="prehead" template="page/html/prehead/main.phtml" />

Then just changed my main layouts (1column.phtml and friends) to hide this: <head> <?php echo $this->getBlockHtml('prehead') ?> <?php echo $this->getChildHtml('head') ?> </head>

In main.phtml add my JS, which I want to load first

<script type='text/javascript' src='<?php echo $this->getSkinUrl('js/require.js', array('_secure'=>true)); ?>'></script> <script type='text/javascript' src='<?php echo $this->getSkinUrl('js/main.js', array('_secure'=>true)); ?>'></script>

This is convenient for us, because it still allows us to change main.js depending on which page we are working on, doing something like this in local.xml :

<checkout_onestep_index translate="label"> <label>One Step Checkout</label> <block type="core/template" name="prehead" template="page/html/prehead/checkout.phtml" /> </checkout_onestep_index>

Hope this helps someone who accidentally stumbles upon this.

Ken

+1
source

Since local.xml is finally loaded by the magento system, it means that the xml mentioned there is finally merged. This may be the reason your new prototype is loading below other scripts.

Alternatively, you can override the Mage_Page_Block_Html_Head :: getCssJsHtml () method and play with it.


Thanks

0
source

Ok, here is my solution. First copy of the application \ code \ core \ Mage \ Page \ Block \ Html \ head.php in app \ code \ local \ Mage \ Page \ Block \ Html \ head.php

Then add this function to the file:

 public function replaceItem($type, $name, $replace) { $newArray = array(); foreach($this->_data['items'] as $key => $value) { if($key == $type.'/'.$name) { $newArray[$type . '/'. $replace] = array( 'type' => $type, 'name' => $replace, 'params' => $value['params'], 'if' => $value['if'], 'cond' => $value['cond']); } else { $newArray[$key] = $value; } } $this->_data['items'] = $newArray; return $this; } 

Now in your .XML layout file there is a line like this:

 <action method="replaceItem"><type>js</type><name>prototype/prototype.js</name><replace>onestepcheckout/prototype/prototype.js</replace></action> 

The options are exactly the same as for removeItem, but now the replacement file will be listed in the same place as the source file. It also inherits the same param, if and cond parameters. Please use this code since I just wrote and worked through basic tests!

0
source

I think the Barny Shergold solution is the most correct, but the comment on avoiding changing the main files is correct. To have the best of both worlds, you can implement the Barny solution in a module that extends the Mage_Page_Block_Html_Head class as follows:

Yourcompany / Layouthelper / etc. /config.xml

 <?xml version="1.0"?> <config> <modules> <Yourcompany_Layouthelper> <version>0.0.1</version> </Yourcompany_Layouthelper> </modules> <global> <blocks> <page> <rewrite> <html_head>Yourcompany_Layouthelper_Block_Html_Head</html_head> </rewrite> </page> </blocks> </global> </config> 

Yourcompany / Layouthelper / block / HTML / Head.php

 class Yourcompany_Layouthelper_Block_Html_Head extends Mage_Page_Block_Html_Head { public function replaceItem($type, $name, $replace) { $newArray = array(); foreach($this->_data['items'] as $key => $value) { if($key == $type.'/'.$name) { $newArray[$type . '/'. $replace] = array( 'type' => $type, 'name' => $replace, 'params' => $value['params'], 'if' => $value['if'], 'cond' => $value['cond']); } else { $newArray[$key] = $value; } } $this->_data['items'] = $newArray; return $this; } } 
0
source

jquery conflict with prototype in magento:

The easiest solution is to add jquery to the end of your main file.

 jQuery.noConflict(); 

Or create your custom js file and add this line, and also include this file after the main js.

0
source

All Articles