News

11.1.2007 ›› CakeX 0.1 beta released. More...

29.9.2006 ›› CakeX 0.1 alpha released. More...

19.9.2006 ›› Today was planned release of CakeX 0.1 alpha. More...

CakeX

Another possible AJAX transport layer in CakePHP

›› CakeX DEMO
›› CakeX API
›› CakeX Project

Links & Resources

›› CakePHP
›› xajax

CakeX - xajax in CakePHP

If You're here, You probably know something about CakePHP and xajax. This project utilizes upcoming xajax 0.5 feature - response plugins, so it uses 0.5 Beta 1 version of xajax code.

For those who are familiar with xajax: forget about registering PHP functions, objects etc - CakeX utilizes xajax by other way, so JavaScript code in head section of Your pages will definitely not contain stumbs for remote functions ;-) Instead You will be able to call ANY CakePHP url, which will be translated by router as action of some controller, which will have initialized component 'Cakex' (and probably also helper 'Cakex') and implemented method afterFilter().

Please, read content of this page before You will try demo. Many things about CakeX will become clear, You know :-) By the way: CakeX demo is nothing more then simple CakePHP plugin.

Why use CakeX with xajax instead of AjaxHelper with prototype.js?

My personal arguments (if You will find some other, let me know, please):

  • prototype.js library has problems with a lot of 3rd party libraries, because it modifies Object.prototype or something similar and this practise looks to me like ugly strategy of one web browser which all webdesigners are fighting with
  • xajax JavaScript library filesize is under 18kB
  • xajax is more then good enough for DOM manipulations (with known ID of DOM element)
  • absence of effects in xajax is not a big problem, as there are other lightweight JS effect libraries which could be easily used/driven by xajax
  • list of method names of xajaxResponse is more then self-explanatory: confirmCommands, assign, append, prepend, replace, clear, alert, redirect, script, call, remove, create, insert, insertAfter, createInput, insertInput, insertInputAfter, addEvent, addHandler, removeHandler, includeScript, includeScriptOnce, includeCSS.
  • all of above methods have in JavaScript xajax object implemented their's functions, which You probably can use in Your JavaScript code
  • xajax allows me to stop care about JavaScript even if I'm building AJAX application
  • xajax community will make a lot of xajax plugins and they will be immediately usable in CakeX

What CakeX consist of?

Basically: one component with one co-operating helper and xajax library.

How CakeX works?

There is no magic, just PHP code ;-)

Regular request:

  • component 'Cakex' initializes in startup() method xajax response and necessary CakeX plugins and in all of plugins is called callback startup(&$component)
  • after render of controller's action are called CakeX plugins callbacks afterRender(&$helper)
  • in HEAD of layout are by helper 'Cakex' rendered necessary JavaScript includes and links (plugins callbacks headScript(&$helper) are called also)
  • then are called CakeX plugins callbacks afterFilter(&$component)

Xajax request from browser:

  • component 'Cakex' in startup() method initializes xajax response and necessary CakeX plugins
  • component 'Cakex' prepares sended data (so we can access them as we are accustomed in CakePHP environment)
  • component 'Cakex' will set following controller variables:
    • $controller->autoLayout = false;
    • $controller->params['xajax'] = 1;
    • $controller->params['xajaxr'] = SOMEFLOATVALUE;
    where SOMEFLOATVALUE is timestamp in miliseconds (sended from browser and created by JavaScript expression new Date().getTime()) - those values are used in Cakex component, helper and plugins - so we are able to determine in which process phase we currently are - regular request, xajax request, bare call inside of requestAction() caused by xajax request etc)
  • component 'Cakex' will call plugins callback startup(&$component)
  • then is executed controller's action
  • if it is rendered (by dispatcher or by render() call) then Cakex helper runs it's afterRender() callback (plugins callbacks afterRender(&$helper) are called also)
  • if controller has some string in $this->params['form']['cakex_update'] then rendered output is catched up and assigned to innerHTML property of 'cakex_update' DOM element (otherwise all rendered output is dropped)
  • then are called CakeX plugins callbacks afterFilter(&$component)
  • then is in $controller->afterFilter() called CakexComponent::afterFilter() method and if component Cakex don't belongs to controller inside of requestAction() call, xajax processes response object and exit execution of script

Every CakeX plugin's callback takes as only argument reference to Cakex component or helper, so You can check array $params for some important values (You can check them inside of controller functions and view files also, off course):

  • empty($params['bare']) means this is not called by requestAction()
  • empty($params['xajax']) means this is not call caused by xajax JavaScript engine from browser
  • !empty($params['xajaxr']) means those params comes from controller which was called by xajax as FIRST (dispatched directly from URL)
  • (!empty($params['xajax']) && empty($params['xajaxr'])) means we're processing xajax call but inside of requestAction call (if developer calls it properly)
Do not use CakeX plugin as storage for any data - especially if You want manipulate them in callbacks. You will probably run in big trouble if You will use requestAction(), as all callbacks (except for headScript()) are called in requestAction() also.

How to access xajax response?

You can access xajax response object (common for whole script lifetime - even if You're using requestAction() call) in Your controller by

$this->Cakex->response

and in Your view by

$cakex->response

Allways access Your xajax response and CakeX plugins by reference!

In short: if You just want Your action caused by xajax call from browser display some alert, You can process view file with code

$cakex->response->alert('Hi! I am CakePHP with xajax!')

or execute code in Your controller

$this->autoRender = false;
$this->Cakex->response->alert('Hi! I am CakePHP with xajax!')

Don't forget CakeX is using xajax v0.5, so if You're already familiar with xajax, FORGET about 'add' prefix in Your response method names.

What is CakeX plugin?

CakeX plugin is class (subclass of class xajaxResponsePlugin), which could be used for any additional functionality with CakeX. It can render some additional javascript in HEAD of Your layout, execute javascript at end of Your page, has access to xajax response, is hooked to some callbacks (startup(&$component), headScript(&$helper), afterRender(&$helper) and afterFilter(&$component)), and is accessible in controller by

$this->Cakex->cakexpluginname

and in view by

$cakex->cakexpluginname

YES! It is accessible inside of controller and inside of view also ;-) It means: if Your controller's action is supposed to be called from xajax JS engine only and it's implementation doesn't need rendering of view, You don't need view file just for some response actions. By the other words: if You want to implement some kind of functionality which will ends with twin component-helper, You can implement this functionality in CakeX plugin, as You have access to it in controller and even in view. Just keep in mind one thing: CakeX plugin's objects (along with global xajaxResponse object and some other objects needed by xajax) are created ONLY ONCE. It means: don't use them for storing any data which will change if You will call some other controller by requestAction() call. See page 'basic usage' of CakeX demo.

Off course - You can access plugin by standard xajax way by call $response->plugin('plugin_name').

Which plugins are used is defined it app/config/cakex.php file and/or in beforeFilter() of Your controller.

By other words: CakeX plugin is supposed to be used for actions with xajax response You don't want code again and again. And because of it's callbacks You're able incorporate almost any additional functionality to CakeX without need to change CakeX component/helper code. Remember: Your CakeX plugin can do anything You want. There is no tutorial for CakeX plugins in this time, if You want to know more about them, explore code of plugins of CakeX demo. They demonstrates almost all functionality of CakeX, but they was written in hurry (I want to release CakeX 0.1-alpha with demo ASAP), so be nice and keep it in mind, please ;-)

Only feature which IMHO has to be in CakeX plugin but is implemented directly in CakeX helper is: UPDATE. Reason is simple: update of innerHTML property of some DOM element is widely used in AJAX applications and I don't want to force all of You to use some plugin for such a basic functionality. To be exact: I know AjaxHelper has all additional functionality implemented in it's methods, but for programmer which is not so familliar with prototype it is only possible way. CakeX helper contains only 3 methods usable in views: link(), form() and tagErrorMsg() - for 'basic' ;-) functionality. Any other functionality belongs to CakeX plugin.

NOTE: CakeX helper produces html code, which will stay functional even if JavaScript is disabled in browser. Just study HTML code it produces: I am sure You're able to generate link

<a href="/some/cake/url/" onlick="xajax.call('/some/cake/url/'); 
return false;">Some link</a>
by hand, but CakeX helper is able to customize generated code in dependency of handle request mode (get/post) etc.

What about requestAction()?

How to use requestAction() depends on fact, if called controller needs to know if it is called from controller which will process it's action by xajax. If it needs to know it, just pass parameter 'xajax' with integer 1 to it, like

$some_data = $this->requestAction('/mycontroller/myaction/', 
array('xajax' => 1));

What about Controller::redirect()?

It is on You - You can (but don't have to) use xajax redirects instead (if Your request becomes from xajax JavaScript engine), like

if (empty($this->params['xajax'])) {
    $this->redirect('/');
    exit;
}
else {
    $this->Cakex->response->redirect('/');
    // immediately process response (without any plugin callbacks)
    $this->Cakex->afterFilter(true);    
}

Best place would be AppController, off course ;-)

What about debugging?

Debugging in AJAX applications... ;-) I made debugging in CakeX completely independent on CakePHP DEBUG constant. Instead You can set $config['debugLevel'] in app/config/cakex.php to value 0 - 3. It doesn't cause anything - until You will load and try demo plugin 'debug' - it shows one of possible ways how You can debug any data and CakePHP environment.

What about flash messages?

If You're processing xajax request, no layout is rendered, so classic way will not work at all. Don't worry, CakeX plugin can be used almost for anything You can imagine - just try demo plugin 'flash'.

Installation of CakeX necessary files

I will assume You have CakePHP installed somewhere.

  • Download latest CakeX release from CakeX Releases
  • Unpack it somewhere - You will obtain directories 'cakex', 'demo' and 'docs'.
  • Copy content of directory 'cakex/app' over Your 'app' directory
  • In Your controller load component and helper 'Cakex'
  • Implement method afterFilter in Your controller (or in AppController) like
    function afterFilter() {
        parent::afterFilter();
        $this->Cakex->afterFilter();
    }
    
  • In HEAD section of Your layour execute code
    e($cakex->headScript());
  • If You want to, customize file app/config/cakex.php

Installation of CakeX demo

I recommend to You install and run CakeX demo at Your server - webhosting I'm use for those pages is free - means with no guarantee of speed/availability etc. So if You think responses from this server are slow, don't blame CakeX/xajax for it. I will assume You have CakePHP with CakeX installed somewhere.

  • Copy content of directory 'demo/app' over Your 'app' directory
  • In Your browser open url http://your_server/cakex_demo/

If answer is yes, consider donation, please, or at least: let me somewhere know what You think about it. Thank You.