Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reorder Magento JavaScript Includes (addJs)

I'll keep this simple.... on my product pages I need to remove the prototype.js file and replace it with the latest version of 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 issue is that now prototype is loaded below everything other includes which stops it working.

Is there a way of setting the order of a JavaScript include using local.xml without having to remove and add every single file again?

like image 516
Adam Moss Avatar asked Sep 06 '11 08:09

Adam Moss


3 Answers

You can use the params element, with "data-group" HTML attribute in it, Magento will put items with "params" set after any items with no "params" set. You can use local.xml in your theme to ensure the order of these elements (I recommend to let Magento add 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 elements with "params" set are rendered in only determined by the order in which actions are executed. Items are rendered grouped by the value of "params", so once group "js001" is defined by the first action (javascript2.js), successive actions with the same group name will append to that group, etc.

In the example above, the order of rendering will be:

  • prototype/javascript5.js (no params, comes first)
  • prototype/javascript0.js (first created params group "js002")
  • prototype/javascript1.js (first created params group "js002")
  • prototype/javascript4.js (first created params group "js002")
  • prototype/javascript2.js (second created params group "js001")
  • prototype/javascript3.js (second created params group "js001")

Items added using addItem addJs, addCss, etc, are threated in the same way, however they differ (and will be super-grouped accordingly) by type (see order below), with each group in super-groups internally ordered as explained above:

  • js
  • skin_js
  • js_css
  • skin_css
like image 116
Dmitri Sologoubenko Avatar answered Nov 12 '22 03:11

Dmitri Sologoubenko


Mage_Page_Block_Html_Head $_data; holds the array of those items so I guess you can filter it for your own good. Default methods does not allow defining order of added items.

like image 23
Anton S Avatar answered Nov 12 '22 04:11

Anton S


I realize this post is pretty old but i stumbled on it while researching this problem, so i figured why not.

Not sure if this is the most elegant solution, but its working sufficiently well for us.

I basically created a new block in my local.xml like this: <block type="core/template" name="prehead" template="page/html/prehead/main.phtml" />

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

In main.phtml I add my JS that 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 as well because it still allows us to change the main.js depending on what page we are on by 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 it helps someone who happens to stumble on this.

-Ken

like image 1
Ken Koch Avatar answered Nov 12 '22 02:11

Ken Koch