5

I am trying to insert JS files into the view but they are being inserted in the wrong order.

In my default.ctp I have this

$this->Html->script(array(
    'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js',
    'global'
), array('inline'=>false));

echo $this->fetch('script');

In my view I have this:

$this->Html->script('jquery.fancybox.pack', array('inline' => false));

But when I view the source it comes out like this:

<script type="text/javascript" src="/js/jquery.fancybox.pack.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="/js/global.js">

Which is obviously the wrong order so the jQuery plugin is not working.

What am I doing wrong?

JJJ
  • 31,545
  • 20
  • 84
  • 99
472084
  • 17,079
  • 10
  • 56
  • 78

3 Answers3

6

Generally, I echo out the required scripts in the layout (instead of adding them to the buffer) and then script block (buffered scripts) after. This ensures that scripts required for each view are echoed first. Your default.ctp would look something like this instead:

// get echoed immediately
echo $this->Html->script(array(
    'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js',
    'global'
));
// everything else from the view, echoed after
echo $this->fetch('script');

Or, you can specify a special block for your preceding scripts.

echo $this->Html->script(array(
    'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js',
    'global'
), array('block' => 'firstScripts');
echo $this->fetch('css');
echo $this->fetch('firstScripts');
echo $this->fetch('script');
jeremyharris
  • 7,735
  • 19
  • 31
  • This is what I had at first but I really liked putting everything into `$this->fetch('script');` because it made sure all CSS came first, then all JS. Not some CSS then some JS then some CSS etc.. – 472084 Mar 28 '12 at 14:32
  • Aren't css and scripts in different blocks? And can't you assign them to blocks anyway? http://book.cakephp.org/2.0/en/views.html#using-blocks-for-script-and-css-files – jeremyharris Mar 28 '12 at 14:54
  • What I meant is if you echo inline CSS in your view it will be below the JS in the layout, and I am trying to keep all the CSS first --- Blocks do work really well but the problem I am having is JS files added in the view are added before the JS files in the layout, so you cant have jQuery in the layout and specific plugins in each view as the plugins will be above the jQuery call. – 472084 Mar 28 '12 at 15:21
  • What if you split it up into separate blocks (edited answer)? This will keep all non-inline CSS first, then echo your `firstScripts` block (which you can append to in the views event) and then generic scripts after that. – jeremyharris Mar 28 '12 at 15:26
  • Nice, didn't think of that. Thanks. – 472084 Mar 28 '12 at 16:03
2

Not sure how much time you invested in building your current system, but you can try using a hierarchical resource loader helper, instead of standard cakePHP one.

Standard resource loader unfortunately has no way to deal with dependencies between different files and just loads them in the order you provide them (view is parsed before layout).

gintas
  • 2,070
  • 1
  • 16
  • 26
0

Use this at head section.

Html->script('jquery-1.11.1.js') ?>
fetch('script') ?>