Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding page-specific Javascript to each view in CakePHP

In an attempt to keep my scripts maintainable, I'm going to move each into their own file, organised by controller and action:

// scripts which only apply to /views/posts/add.ctp
/app/webroot/js/page/posts/add.js

// scripts which only apply to /view/users/index.ctp
/app/webroot/js/page/users/index.js

That's all cool, however I'd like for these to be automatically added by the Controller, since it obviously knows the name of both the controller and action.

I figure the best place for this is in AppController::beforeRender(). (yes?)

The only problem is that I don't know how to actually add this into the $scripts_for_layout variable. I thought that getting a reference to the javascript helper object would work, but I can't find it from the controller!

class AppController extends Controller {
    var $helpers = array("javascript", "html", "form");

    function beforeRender() {
        // ???
    }
}
like image 442
nickf Avatar asked Sep 15 '09 04:09

nickf


2 Answers

Very easy to do in your default.ctp layout file:

An example to automatically include .css files per controller and/or controller/action (because I had this lying around, easily adaptable to .js files):

<head>
...
<?php
    if (is_file(WWW_ROOT . 'css' . DS . $this->params['controller'] . '.css')) {
        echo $html->css($this->params['controller']);
    }
    if (is_file(WWW_ROOT . 'css' . DS . $this->params['controller'] . DS . $this->params['action'] . '.css')) {
        echo $html->css($this->params['controller'] . '/' . $this->params['action']);
    }
?>
...
</head>
like image 132
deceze Avatar answered Nov 12 '22 03:11

deceze


Like deceze is saying, we do it using the layout, although I find our solution a bit more elegant :)

In default.ctp:

if(isset($cssIncludes)){
    foreach($cssIncludes as $css){
        echo $html->css($css);
    }
}

if(isset($jsIncludes)){
    foreach($jsIncludes as $js){
        echo $javascript->link($js);
    }
}

Then, in our controller actions, we define these arrays:

$this->set('cssIncludes',array('special')); // this will link to /css/special.css
$this->set('jsIncludes',array('jquery'));   // this will link to /js/jquery.js

For files that need to be loaded in each view, we simply add the same type of link "statically" to the top of the layout, like:

echo $javascript->link('global');
echo $html->css('global');

This works really well for us. Good luck!

like image 26
brettkelly Avatar answered Nov 12 '22 05:11

brettkelly