lightweight, manouverable and quickly deployed


11 Dec 2007 - v1.0.2

added filterStopWords to Utils.pm and call from _searchRecords() in Model.pm if $self->{stopwordFilterEnabled} (default). Added filterstopwords attribute to element in config.dtd

switched to using output_fh instead of output_file as the latter wasnt rewriting output when there was nothing coming out of the transform, but for publishing this might be a valid case

tweaked tools/CreateStubData.pl to add a null payload before adding new blank records

Added new tools/ValidateDate.pl script to validate an applications data files after possible manual editing or changes to the config.xml for the app

added new optional element 'select' to actions, tightned up the handling of out-of-band requests for modes that are disabled, added a sample search-only.cgi script, added and renamed a couple of messages and titles

added tools/PublishAll.pl which can be useful for cron-based or command-line publishing of apps

pushed all codebase elements to the subversion repository at sourceforge for the project

24 Sep 2007 - v1.0.1

added new optional element 'select' to actions, is '1' by default if not in the config file, may need to be set to '0' where you actually dont want people to browse the records, say where you have a config file which only allows one of the readonly methods like search, or view

tightened up the handling of out-of-band requests for modes that are disabled in the config file, also made the UI titles and messages for these more consitant

added a sample search-only.cgi script which is set to specify a config file that disables all modes except search, and points to a hard-coded app.

added and renamed a couple of messages and titles to the resource files and associated DTDs

19 Sep 2007 - v1.0 Release !!!

Added record search capability. New optional config.xml file element 'search' under actions with a mandatory attribute for transform, new optional boolean attribute in record definition area of config.xml called 'searchable', new x-search CGI paramater for a search string, and added new View::buildSearchContent() sub and Model::_searchRecords() to handle searching and rendering of search results

NOTE: should be cautious about performing/enabling search across large or many data files, performance wont be great as its parsing and crawling the file doing xpath searches on potentially numerous record/elements. It works but running a crawler across the rendered site would perform much better.

added new sub Model::_fkeyValues() to return values only from the foreign keys list

v0.31 switched to using buttons for form submission to support localisation of labels, turns out there's a bug in IE6 which means it submits values for *all* buttons that have the same name as the on that was clicked. introduced a simple change to alter the onclick behaviour to workaround this.

added a call to tinyMCE.getContent() in validate() when checking that mandatory fields have a value, previously wasnt able to extract the iFrame content where tinyMCE stores updates to TEXTAREAs it has been associated with. also removed alert that was left in JS unintentionally which was spitting out the entire DOM in IE

added ability to flag certain fields as sortable in record list mode (select), added new attribute to fields records in config.xml and show arrow images beside the currently sorted column.

sortable (1 | 0) #IMPLIED

and two new cgi paramaters to Controller.pm and edit.xslt x-sortorder # used when listing records, vals 'ascending' or 'descending' x-sortby # field to sort by when listing records

fixed a minor issue in handling of checkbox values where a checked value written as a record is newly created was set to 'on', is now '1' or '0'

titles and messages are now optional elements in config.xml, they are loaded from the file-system from default locations anyway if not defined in the config.xml file

split edit.xslt up into seperate files depending on function, new files are select.xslt, add.xslt and edit-fkey.xslt aded dateToText template to Utils.xslt

tidied up a few CSS inconsitancies in the sample XApp.css

added new test files 8_xml.t and 9_view.t and 10_search.t for testing of new functionality

13 May 2007 - v0.31

fixed a couple of minor issues with auto-generated index field generation, changed from @xapp:id attribute to xapp:id field within each record. the autogenerated IDs are numerical, the generator starts with a count of existing records + 1 then increments that until a unique/unused key value is found

'method' element is now optional in config.xml, form methods are set dynamically by default depending on appropriate REST-like action, eg GET for fetches, POST for updates

firmed up internationalisation support, all buttons and UI messages are now included in the resource files and echoed into output through XPAth statements which check for an element with a lang attribute matching the current browser language in use (currently only en, de and mi)

copy/paste now pastes 'after' the selected target record, or if no paste location is selected it pastes after the record that was copied, previously required user to select a paste location

can now doubleClick a record name in 'Select' view to enter edit mode for that record, calls a new sub editRecord() in xapp-tools.js

titles and messages now loaded by new sub _loadUIresource, a number of new elements added to each file, please update your config.dtd with the version from this distro so you can check you have all elements in your custom resource files

'xapp' namespace declaration/attribute now added to new data files root nodes

moved XSL transform calls from processActions out to two new subs buildEditContent() and buildViewContent() in XApperator::View

now using carp and croak for logging during die or warn conditions

added property $self->{debugMode} which is checked in contentFooter() and echos out some common CGI params that are not visible in the URL during POST requests

added useCompressedJS param and compressed copies of JS files, uncompressed copies are shipped and used by default

20 February 2007 - v0.30

Grouped all view and content rendering subs out to new module XApp::View.pm. Grouped all control/CGI related subs into new module XApp::Controller and all model/date related subs into new module XApp::Model

Renamed _publish to publish and _publishAll to pubishAll (as no reason why they couldnt be called from the controller)

Added support for auto-generation of an index value if there is no field marked in the config.xml file as an index field. The autoincrement style id attribute xapp:id is added to every new record. Need to add the following xmlns reference to any existing data files (and any view.xslt stylesheets that want to reference the id attribute)...


new config actions optional element 'selectfkey'

new optional attribute for 'edit' element in 'actions' in the config xml file of format "popup (1 | 0) #IMPLIED" which directs the UI generation to support a new popup window on edit rather than rendering the whole page again

tightened up the config.xml DTD to force all boolean type attributes to be "(1 | 0)" rather than "CDATA"

tidied up _warn and _dienice final 'warn' output formats, output is now via carp so can trace errors back to calling location. Added new _debug method

02 August 2006 - v0.20

new contentHeader and contentFooter methods and new contentSelectmenu method to replace old menuHTML. renamed internal property menuHTML to contentBody. this simplifies the controller.cgi as it no longer has to consider Content-type headers (now that we have XML output options)

any textarea field in config.xml that has an type attribute value of 'wysiwyg' will direct the UI to include client-side JS neccessary to invoke an editor instance to handle it. A new template in utils.xslt showWYSIWYGEditor() added to render the JS support.

added new plugin element in config.xml for specifying JS support libraries for various functions. Currently only used for WYSIWYG editor support, and specifically TinyMCE, allows admin of XApp instance to override buttons rendered in the WYSIWYG editor

date types are now stored in data files as condensed ISO8601 format, e.g. 2006-12-31, and a new base attribute 'dateEntryFormat' indicates how the UI should render date values for editing. if 'compound' (the default) will present 3-select lists (ie year, month, day) or if 'ISO8601' will render a single field with Baron Schwartz's excellent date chooser Javascript library for data entry assistance

if date or time config.xml entries specify default='0'|'' then are now set to blank instead of the current date/time when creating a new record. a default value of DATENOW will default a date to exactly that, as will TIMENOW on a time record

added 'xml' x-mode which spits out raq back-end xml content for a selected fkey with the data wrapped in an application root node and a data parent node

sanitising $x-mode in getCGIParams so can only be word chars and defaulting mode to 'select' if null or not recognised. also added new get/set sub mode()

changed errorsToUser to detailsToUser and now passing two strings to _dieNice, 1st is generic message which is always displayed, 2nd is detail which may be more sensitive, e.g. containing path or data details and only displayed on detailsToUser=1, both strings are written out to the log via 'warn', updated all calls to _dieNice to reflect this. added new method _warn() for non-fatal errors.

added new generate-id attribute to field record in schema to support auto-increment like behaviour on ID type fields. if set to '1' a call to the XSLT generate-id function will generate a default value for fields that dont currently have a value (e.g new ones)

added new private method _schemaHasFieldType() to check if a given type is present in the schema for this app, used to check if dependencies are required for certain types

split the RunTests.pl script into seperate funtional test.t files in the t/ folder and made sure they all return state to pre-run so they can be run independatly of one-another

17 June 2006 - v0.19

added new non-editing 'View' x-mode which performs on the fly presentation of an apps data. previously only supported a static render which is still available

view and publish xslt files now default to view.xslt and publish.xslt so dont have to be specified in config file, are also assumed to be in the apps root directory

eval-ing all LibXML calls to parse_file so we can trap and present a relevant err message in the UI in case the parse fails

masking collection select list and irrelevant menu items when no keys are present, no collection data files have been created yet

dates can now be submitted with null values, was previously spitting message back to user about formatting error

added onclick event to tip images in case click-happy folks do so before waiting for a mouseover

fixed edit.xslt where a cancel on create of 1st fkey displayed the editable records list (which of course was empty)

folder paths for publishing locations can now be assumed to be relative and if they dont start with a '/' will be assumed to be a subdir of the app instance's working directory, if so they'll obviously need to be writeable

config.dtd updated to reflect new optional element in the section of config.xml for an app

added sample view.xslt files to sample apps and config files

added demo app and tweaked messages and titles files to use generic terms 'record' and 'collection' to refer to data and keys

29 Jan 2006 - v0.18

added new recursive template searchReplace() to utils.xslt

Added new /tools/ script CreateStubData.pl which creates stub XML representing a sample record or sample container file as specified in the config file for a given XApperator application.

formatting changes to HTML that wraps records in list mode to show in a table with alternate row classes XAppRowEven/Odd so presentation can be driven by CSS

reordered editing FORM buttons, 'Add' is now first

when copying/pasting a new record it is now postfixed with "(n)" instead of prefixed with "copy (n) of"

escaping quotes in index field values as were breaking xpath queries generating 'invalid predicate' errors

also escaping quotes in tickIt javascript call as was stopping label select

8 Aug 2005 - v0.17

added new attribute 'maxlength' to schema fields which is used to validate text field lengths on submission. 'size' is now used for display only

mods to _createRecord() and _parseCGIParams() to take raw vals of submitted CGI params, was doing an || '' which defaulted to '' if the values were '0'

added check that max num of records not exceeded on save, insert or paste. should be blocked by the XSLT but will help if URL hacking is attempted

added check for edit enabled and masking edit button if not (useful if a config file only allows viewing of records)

added ability to embed markup in messages and echo them out with disable-output-escaping (multiple changes in edit.xslt)

updated RunTests.pl to check for these conditions and mods

8 Jul 2005 - v0.16

added new field type of 'time' which is expected to be in 24h format, e.g. '1530'

added new xsl:template name="showTime" to utils.xslt to handle display of time fields as drop-downs for hour and min parts, defaulting to current time passed in by the .pm. Added two supporting templates showSelectHour and showSelectMin the latter making a call to the recursive template optionRange.

added method _fileTypesOK() to do some field content validation, mostly looking for well-formed date and time fields, but also checking max lengths of strings as per config.xml settings

added new method _getDateTime the results of which are passed into the XSLT transform and used as defaults for date/time fields if none provided

added an xslt file in a new folder /tools/ for flattening xml files to be suitable for importing into the XApp framework. Included some sample xml input and output and added some docs to introduce them

added a documentation page illustrating typical directory structures and permissions required to get XApp up and running.

added checks to RunTests.pl for date/time values and methods

generated DTD's for the titles and messages xml resource files and associated them with the files. removed the *-all resource files from distribution as not used. also added time as valid attribute value in config.dtd

29 Jun 2005 - v0.15

added ability to delete fkeys/data files. moded processActions to call new method _deleteFKey() which removes the key from the keyfile and unlinks the file in the filesystem. Added new titles and messages to resource files for these actions and posible errors.

added new method _addNullPayload() to create a dummy data section to be passed into the XSLT, used in modes which dont really require UI data (e.g. publishing)

added addValidateFKeyJS() Javascript sub to utils.xslt to client-side filter unwanted foreign key values, ie make the file-system filename safe (was previously only being filtered server-side in the .pm)

added new method _fkeyValOK() which is called from a couple of places to sanity-check the fkey value as its umtimately used as a file-system reference. (stop dir-traversals)

mod to _updateRecord() to check for checkbox/boolean types and write them to XML as '0' or '1' rather than 'on' or ''

updates to XSLTs to only add onClick events to form submit buttons when clientsidevalidation is actually set to Javascript

added dieNice call if publish folder is not writeable, also checking if file exists and is actually writeable

added ValdiateConfig.pl in the ./t directory so deployers who do not have a validating XML editor can debug possible errors in their config.xml file. Uses XML::LibXML's built-in support for DTD validation

added GPL header to .cgi, .pm and .xslt files and included a copy of ver2 of the GPL in text form in the distribution

Changed sample controller.cgi to call buildMenu *after* the processActions has been called so it can reflect any changes in the foreign-keys data shown in the dropdown select menu

modded many of the subs and some XPaths in the XSLT to refer to or handle the foreign key data DOM via the document node rather than the root node

added new warnLevel property to new() constructor defaulting to '1' which triggers apache style warnings, but can be overridden in the controller.cgi if to be run from command line (for example)

added MANIFEST and FAQ testfiles to root of distribution

15 Jun 2005 - v0.14

added ability to perform multiple publishing transforms, new 'transform' elements are looked for as children of 'publish'. each transform uses attributes for specifying XSLT filename, output folder and extension. transform element also has attribute that directs _publish() to use either the fkey 'value' or its 'label' as a filename, if set to label will sanitise the filename before writing out to the filesystem (e.g. removing spaces).

added publish-all feature, new attrib 'all-enabled' in element of config.xml and publishAllEnabled internal attribute used in XApperator.pm and passed into XSLTs

now passing two paramaters in the _publish stage that contain the fkey and fkeyLabel in case the publisher wants to incorporate them into the XSLT output (e.g. in a heading or page title)

Added sub _keyLabel() which returns the text for the label node of a key in KEYS.xml which has a value node with the text specified in the 1st argument to this method.

added loads of default values to parseConfig() in case config.xml isnt valid, wouldnt be if developer used a validating editor, but hey!

added dieNice call if resources files not found

fixed XPath in addValidateFormJS template of Utils.xslt as was previously not resolving in 'add' mode

tidied up load of XPaths to be more efficient and/or specific (e.g. //config -> /application/config)

fixed bug where not all fields were displayed for editing if the config file was changed *after* records had already been populated

added new 'add' and 'publishalldisabled' records to messages.xml and titles.xml

moved lang attribute in language specific messages and titles xml files to the parent element rather than in each child, should be inhererited anyhow. e.g. xml:lang="de"

added more detailed Apache style 'warn' messages, format now like: Wed Jun 15 14:50:41 2005] [XApperator] Error: Cant publish /home/folder/somwhere

added a new Javascript sub checkSelected() to xapp-tools.js which is used to check one of the records displayed is actually selected when user has clicked 'Delete', 'Edit', 'Cut', 'Copy' or 'Paste'. Saves a round trip to the server. onClick actions to call it are generated within Edit.xslt

RunTests.pl updated to reflect above changes

25 Apr 2005 - v0.13

Added copy/cut and paste modes between records in a single XML file (not between files, yet). Required two new CGI params: x-pmode (for 'p'aste) which is either copy or cut, and x-tkey for 't'emporary key, ie the one being copied or cut.

Added new copypaste element to the action group in config.xml as well as two new title/message pairs to the resources files for cut, copy and paste

added public subs to .pm for title, menuHTML, error and content so controller can call methods rather than make refs to hard-coded properties

added null check for $mode in edit.xslt so blank UI displayed in edit div when new foreign key selected

fixed libxslt warning where menu prompt XQuery was failing coz messages now optionally out in seperate xml file

Added extra sample app to the distribution which demos a simple blogging mechanism using custom XPAth functions for handling of date fields

19 Apr 2005 - v0.12

Added password type field support to schema and edit.xslt/utils.xslt. Data shown asterix'd if required to be displayed/editable

Update config.dtd to cover various recent tweaks to the schema and config.xml layout in general

Modified _updateXML() to use the pre-loaded data payload (was previously doing it again, ie twice the work)

Added test script RunTests.pl which uses Test.pm to run through all internal subs and common CGI interactions checking error handling works as expected. Test data is in new top-level folder 't' in the distribution

bashed out lots more documentation, including fully PODifying XApperator.pm

11 Apr 2005 - v0.11

added '@src' attribute to 'titles' and 'messages' elements in config.xml and using that to parse an external resource file for that purpose. currently split titles and messages into one file per language and placed in new /resources/ dir. The parsing overhead will probably end up being too expensive but is easy to manage config.xml files during development. could do a merge as an app goes into testing or production

added new var rootDir to new method override-able thru controller.cgi, used in XApperator.pm to resolve all filesystem resources instead of having seperate params for each resources

Moved Javascript utils out to file xapp-utils.js and placed in the /resources/ dir. added new var resourcesPath to new method override-able thru controller.cgi, used in edit.xslt to build relative path to location of Javascript library

10 Apr 2005 - v0.10

prefixed all core XApperator CGI variables with the string 'x-' which should help avoid potential collision with XML data file fields of the same name as core XApp ones (e.g. mode, key, id etc).

added sanitisePath() sub to strip out ../ sequences from any given string

now passing $method (ie GET or POST) into menu rendering process

added new sub _dataPayloadReqd() to return true only under conditions where a data payload is actually required. was previously always loading one, which is most, but not all of the time.

added ability to add new record files (foreign keys) from top menu area. uses new _fkeyexists sub to make sure not overwriting existing file. added titles and messages 'nofkeylabel' and 'nofkeyvalue' in case of these conditions

dumped 'xpath' element in config.xml schema in favour of assembly of 'recordname' and new element 'rootname', rootname also used to create new template record files

07 April 2005 - v0.09

Added "insert" mode to be able to add a new record before any other selected record. if none selected then is inserted at document beginning. new rootinsert and insertkey hidden params added to form in edit.xslt to support this

Added _createRecord() sub which is now called by both addRecord and insertRecord

More client side JavaScript validation, now checking user has provided a value for each of the compulsory (or index) fields. Added clientsidevalidation element to config.xml and conditional check of it in edit.xslt.

added check for cols attribute in record schema for textarea fields and reflect this in the edit interface through utils.xslt

Added _keyExists sub to .pm as now checking for key under multiple conditions

Tweaked menu.xslt to order fkey dropdown labels, was previously document order of KEYS.xml

05 April 2005 - v0.08 (1st Alpha)

First Alpha Release !!!

Jamie knocked up a logo for me after a quick transfer of a few keywords, bloody great stuff. Cheers mate!

added client-side Javascript function to make it easier to choose records in the 'select' mode, user can click the textual label next to the radio button witout having to zero in on the button itself

04 April 2005 - v0.07

added new data type of 'date' for config.xml which is an ISO format 'YYYYMMDD' and represented in the UI using seperate dropdowns for each part with a suffix indicating part seperated by a ':'. For example if your date field name is 'mydate' then fields would be 'mydate:year', 'mydate:month' and 'mydate:day' and XApp will reassemble these when submitted into an internal concatenated value.

added new xsl:templates to assemble date field parts and moved them and showField() out to new utils.xslt file which edit.xslt now imports

added new method to XApperator.pm to register custom XSLT functions to be used by the standard templates. One function unescapes markup into brackets for use in the publishing/rendering phase.

added I18n/L10n support, controller checks list of languages 'Accepted' by the browser and feeds the primary one into the XSLT which then chooses appropriate messages and titles etc from the config.xml file to suit that language

now checking the 'required' attrib of each field and prompting if no value supplied. added asterisk next to compulsory fields in edit and add interfaces.

01 April 2005 - v0.06

added tooltip mouseover against labels in the edit interface if the record field has a 'tip' attribute value in the schema

changed the 'fields' container element in config.xml to 'schema' and altered the names of a few of the attributes to more closely align with W3C XML Schema names

Added DTD for config.xml file to ensure consistancy between apss

Added check for any of the edit like modes where no record key selected, show a warning instead in that case.

removed 'save' and 'savenew' actions from config.xml as inferred by status of edit element

added a confirm delete option

28 Mar 2005 - v0.05

moved data files to alternative dir in case stamps over config and keys data (tho admin should set permissions to block this). added new dataDir attribute to XApp object

added CSS styles to many of the UI elements

moved all UI messages and warnings out to the messages and titles section of config.xml. XApp.pm now sets a var display which edit.xslt knows to look for to determine which message to display

added relativeURL attribute to object taking val from CGI::url->relative and using to populate FORM method attributes in the XSLT (otherwise querystring params are displayed if method is POST and action is blank

23 March 2005 - v0.04

doing a single XML data parse now in processActions instead of in each private sub like _add, _delete etc

after an update (add, delete, save etc) the UI presents the list of records instead of forcing user to reselect their parent file

22 Mar 2005 - v0.03

added check for 'editable' attribute in field definition, if set to '0' will echo content of field in edit interface but not allow it to be editable through input fields etc.

added detect of new attribute 'rows' in textarea record fields in config.xml

added new config paramater for FORM method, POST or GET, which is embedded in forms in edit.xslt

checking we've got records in edit.xslt, if not, no point in showing the Edit or Delete modes

now checking if user is submitting a new record with the same index field as an existing one, if so, throw an error

20 Mar 2005 - v0.02

added Publishing mechanism (one-off XSL transform to file-system)

controller script now able to specify destination for errors, ie to user or log or both

errors all routed thru new internal sub _dieNice()

added check that user supplied a value for the index field, wont save if not

added recordsmin and recordsmax checking if specified in config.xml

added loads more documentation

11 Mar 2005 - v0.01

Original SourceForge release, planning stage

11 Feb 2005 - v0.001

Original spawn date

Authored using: XApperator