5

I have a custom extension that includes jQuery through layout XML like so:

<reference name="head">
    <action method="addJs"><script>jquery/jquery-1.8.1.min.js</script></action>
</reference>

Other extensions that use jQuery need to be loaded after my module so jQuery remains on top.

By default Magento loads everything alphabetically. Is there any way to specify a sort order for extensions?

One way is to override page.xml in my theme and manually include jQuery into the head or I can set every custom module to depend on the module I want on top for example:

<depends>
    <Package_JQueryLib />
</depends>

Any other recommendations?

Edit

I was thinking I could also override Mage_Page_Block_Html_Head and modify the addItem() method to include sorting or prepending files to the head.

7ochem
  • 2,183
  • 1
  • 34
  • 42
ringerce
  • 533
  • 2
  • 12
  • 25

3 Answers3

15

The <depends /> node is a valid approach - it is intended to provide control over colliding module xpath values, but it also can be used to affect the order in which child nodes appear.

The other option, rewriting the page/html_head class, is something that has been needed for awhile and, I imagine, actually done by others.

Another option to try would be to use an <update> directive in your custom module layout XML, as the directives in an <update /> are processed before the other directives. This means that jQuery will load before all other files.

<?xml version="1.0" encoding="UTF-8"?>
<layout>
    <default>
        <update handle="add_jquery_first" />
    </default>

    <add_jquery_first>
        <action method="addJs" block="head">
            <file>jquery/jquery-1.8.1.min.js</file>
        </action>
        <!-- or
        <reference name="head">
            <action method="addJs">
                <file>jquery/jquery-1.8.1.min.js</file>
            </action>
        </reference>
        -->
    </add_jquery_first>
</layout>
benmarks
  • 23,384
  • 1
  • 62
  • 84
  • Thanks for your advice. Much appreciated. I've edited my answer with the solution I came up with. It's probably not the most elegant but it works and I don't have to worry about jquery again. I tried the method with the update directive but jquery was still getting included after other custom extensions. Thanks again and please let me know what you think of my solution. – ringerce Sep 27 '12 at 02:46
  • Hmm. I'll need to look into why `update` didn't work. As for your answer, you could post it as an answer to your own question and then accept it for others to evaluate :-) – benmarks Sep 27 '12 at 03:28
  • I posted it :). I think the update method only applies to that particular modules layout xml but I could be wrong. The other modules layout xml was still getting appended to the page head first. – ringerce Sep 27 '12 at 05:34
  • Nice answer Ben! - http://github.com/drewhunter/ItemPosition - uses a rewrite of page/html_head as Ben described in his answer so it's not particularly pretty but it works – Drew Hunter Sep 27 '12 at 08:19
  • Drew, nice work. I wish I would have found your solution before doing my own :) – ringerce Sep 27 '12 at 13:58
  • @benmarks Curious to know how is it going with 'update' thing. Haven't got time to try it myself. – ivantedja Sep 27 '12 at 15:45
3

This is what I came up with: http://pastebin.com/tMUnWBWR

Now via layout xml or the addJs method I can use the sort_order parameter to define where I'd like my js included.

Example layout xml would look like:

<action method="addJs">
<script>js/script.js</script>
<params/>
<sort_order>0</sort_order>
</action>
ringerce
  • 533
  • 2
  • 12
  • 25
  • In Magento 1.9, this only works if I include all the optional elements in the action, and in the correct order, (type, name, params, if, cond, sort_order). See my question here: http://stackoverflow.com/questions/26659886/add-element-to-page-xml-in-magento – Justin Oct 30 '14 at 17:55
  • Also, this doesn't allow the JS to be moved to the top of all files, only the others in that same type. For example, if you have JS file with type 'skin_js' and another with 'js' they are only sorted within their same type. – Justin Oct 30 '14 at 18:16
1

Magento loads config files from app/etc/modules in alphabetically order in file app/code/core/Mage/Core/Model/Config.php in protected method _getDeclaredModuleFiles()

It tells that firstly Mage_All.xml will be loaded, then all the Magento config files (starts with Mage_) and finally custom modules in alphabetically order.

So here is a small but "dirty" trick - name your namespace as AaaPackagename. Name starts with numbers will also do the trick: 1Packagename or 000Packagename

Sergei Guk
  • 1,775
  • 1
  • 13
  • 12