All your $base are belong to Ajax

We have custom routes, completly dynamic. We can even move the whole app to a subdirectory and still it works! So nice! But how to deal with that in static Javascript files? What about the Ajax and maybe some JS asset configs like image folders and such? In this small post i will tell you a good practice of mine which allows me to forget about that problem.

In CakePHP you have two handy properties in the controller, views and helpers. They are called $this->base and $this->here. They are basicly all you will ever need, but most importantly $this->base.
The $base property tells you the current directory of the application (roughly put). If you application runs in http://example/app/ the $base property has the value /app.
The $here property tells you the current directory + the current action path. If you request http://example/app/admin/users/home the $here property has the value /app/admin/users/home.
We can use this info to our advantage when writing Ajax request in our external Javascript files. What i always do is using the JavascriptHelper to generate a code block with exactly these two values.
$javascript->codeBlock("var base = '{$this->base}, here = '{$this->here}';'");
I usually throw that line in my layout before i add anythings else, so that this info is available in all my scripts.
Now whenever i want to call something with Ajax i can either use Ajax.Request(base + '/controller/action.json'); or simply Ajax.Request(here + '.json'). If i ever decide to move the application i no longer need to worry about the base path.
Same goes for our webroot folder of course: $imgFolder = base + '/img/';
Another practice i found useful is when you want to submit a CakePHP form with Ajax. Instead of figuring out what path you need to POST to, just query the action attribute of the form. Much easier than writing the url yourself, even easier than using base.
// ajax post on all forms, just for demo
$$('form').invoke('observe', 'submit', function(evt){

var form = evt.element();
new Ajax.Request(form.readAttribute('action') + '.json', {
parameters: form.serialize(),
onComplete: function(xhr) {
// added .json for fun
// maybe do something neat with validationErrors
}
});

});

This should help you keeping your Javascript codebase lean.
http://j.mp/bwwXmg)">