Integrating JS frameworks with Aruba

Marty Vance <[email protected]> Mon, 17 Aug 2009 12:43:10 -0600
Newsgroups gmane.comp.cms.xaraya.devel
Organization Xaraya
Message-ID <[email protected]>
This is a proposal for integrating Javascript frameworks with Xaraya. 
jQuery will be implemented as a model, as the default framework used by 
Xaraya.

Javascript API functions
==================================================
In order to formalize our handling of frameworks and their components, 
some additions to our Javascript API are required.

These functions exist in base/xarjavascriptapi and act as wrappers for 
counterparts in each framework.  As wrappers, they take arguments 
$modName and $modType in order to locate the framework's API functions. 
  These arguments default to 'base' and 'jquery', respectively.  The 
last argument is an array named $args, which is passed to the framework 
function to handle as necessary.

init: Locates the primary framework JS, places it in the script queue, 
and performs other initialization tasks

loadplugin: Locates plugin, places JS in the script queue, and performs 
plugin initialization (including loading other assets into queues)

appendevent: Adds code to the specified document-level event handler, 
either from a file or string.

In the $args for appendevent, an index named 'event' must be present, 
and either 'file' or 'code'.  If the requisite args are not present, the 
function fails silently.

None of these functions raise exceptions.

As such, Xaraya ships with the following functions:

modules/base/xarjavascriptapi/
- base_javascriptapi_init($modName='base', $type='jquery', $args=array())
- base_javascriptapi_loadplugin($modName='base', $type='jquery', 
$args=array())
- base_javascriptapi_appendevent($modName='base', $type='jquery', 
$args=array())

JQuery serves as an example of a framework's functions:

modules/base/xarjqueryapi/
- base_jqueryapi_init($args)
- base_jqueryapi_loadplugin($args)
- base_jqueryapi_appendevent($args)

Alternatively, the framework-specific functions could be called directly 
via xarModAPIFunc like any other API function if the developer was sure 
which framework(s) are present, but this is not recommended.

Additionally, two functions exist in the JS API which have no framework 
counterparts.

modules/base/xarjavascriptapi/
- base_javascriptapi_registerframework($modName='base', $type='jquery', 
$args=array())
- base_javascriptapi_registerplugin($modName='base', $type='jquery', 
$args=array())

The $args for each of these must contain indexes 'framework', 'name', 
and 'version'.  Any other indexes are automatically converted to a 
module var in the host module (see below).  If a registerplugin function 
is found within the module $modName, $args will be passed to it instead 
for handling.

These functions allow Xaraya to learn about which frameworks are 
present, and their plugins.


Modules
==================================================
A framework itself must belong to and exist within a Xaraya module (the 
"host module").  Whether the primary framework file should be subject to 
theme override is debatable, however plugins and supporting code, 
images, and stylesheets should certainly be subject to override.

Host modules are encouraged to create module vars related to the 
operation of the framework as necessary.  The naming convention for 
these modules vars is [framework].[varname].

Modules which depend on a framework provided by another non-core module 
are required to list that module as a dependency.  A module which 
requires specific plugins are encourages to ship them, however the 
plugins must be moved to that framework's host module.

Module vars added in base related to jQuery, in base->modifyconfig, tab 
'other':

- jquery.varname: (str) variable name in javascript to use for the 
jQuery object.  Default: 'jQuery'
- jquery.autoload: (bool) whether to automatically load jQuery on every 
request.  Default: true
- jquery.compact: (bool) whether to skip looking for optimized files. 
Default: true
- jquery.plugins (array) list of registered plugins

Module vars may also be created for plugin defaults.  For example, 
jquery.plugin.cluetip.

Modules hosting other frameworks are expected to create similar module 
vars as necessary.

It is up to the module developer to provide a UI for setting these 
module vars.

The base module holds a module var to identify what frameworks are in 
place and registered, named 'RegisteredFrameworks', which is an array. 
It also holds a module var named 'DefaultFramework', which contains the 
name of the preferred framework.

File Locations
==================================================
Some parts of a framework are subject to override via Blocklayout.  It 
is more desirable to organize files according to functionality rather 
than file type, therefore all framework files are placed under [module 
name]/xartemplates/.

The root location for a framework is at [module 
name]/xartemplates/[framework], e.g, base/xartemplates/jquery.  This 
directory contains the framework JS files, BL templates for 
initialization, configuration, document-level events, and any other 
files necessary for the framework to function.

Plugins (as a generic term) are at [module 
name]/xartemplates/[framework]/plugins/, with each in its own subfolder, 
e.g., base/xartemplates/jquery/plugins/thickbox/.  These directories 
contain everything necessary for the plugin to function.

Framework Registration
==================================================
During module install, the host module must call 
base_xarjavascriptapi_registerframework in order to tell Xaraya that the 
framework is in place.

Plugin Registration
==================================================
Also during module install, the host module must register any included 
plugins by calling base_javascriptapi_registerplugin for each.

The host module for each framework must supply a method to manually 
register plugins, in the event that a user manually puts plugins in place.

Templates
==================================================
Each framework must provide modifyconfig.xd and init.xd in its root 
directory if required.  To facilitate document-level event handlers, 
each event (see below) requires [event name].xd, or a generic event.xd.

Likewise, each plugin must provide modifyconfig.xd and init.xd for its 
own use.

Events
==================================================
Currently, Xaraya's JS API provides two positions where JS may be 
rendered: "head" and "body".

Head has typically been used to include external scripts, while body has 
been used to run JS code after the majority of the document has been loaded.

To make this API more modern, additional positions are put in place 
which correspond with commonly used document-level events.

- abort
- click
- dblclick
- keydown
- keypress
- keyup
- load
- mousedown
- mousemove
- mouseout
- mouseover
- mouseup
- ready
- resize
- unload

Most of these match DOM events, with one exception.  The load event is 
fired when the document itself has finished loading; ready is fired when 
the document and all external assets (CSS, images, scripts) are fully 
loaded.  This is a freeform list, and not hardcoded into the system; a 
new position may be created simply by passing it to appendevent.

Of these, only load and ready are expected to be used with any 
regularity.  The others exist for completeness.

In practice (for XHTML documents), the order of rendering in the head 
element is 'head', then all other positions except body.  Body is 
rendered within the body element, as desired by the theme author.

Core Changes in Blocklayout
==================================================
In order to handle the new file location which frameworks occupy, new 
functions must be added to Blocklayout to enable processing.

- xarTplFramework($modName, $frameworkName, $tplData = array(), 
$templateName = NULL)
- xarTplPlugin($modName, $frameworkName, $pluginName, $tplData = 
array(), $templateName = NULL)

The argument names should be obvious, however $frameworkName and 
$pluginName refer to the filesystem directory names, not the common name 
of the framework/plugin.

See also: http://www.xaraya.com/index.php/xarbb/topic/3479