Scott Penrose

ExtJS Perl Library

Scott Penrose is a perl hacker with an interest in home automation. He has been playing with electronics since he was old enough to burn his fingers with a soldering iron.

NEW: See Ext.Direct

I am writing (with someone else) an ExtJS Perl back end.

Actually Two Backends:

  1. A stand alone example CGI to go with the demonstrations
  2. A library to do what you mostly need with a few lines of code

Why both: Because we want to demonstrate from scratch how to write a CGI so you can write things we have not thought of, teach some perl, and promote perl into the Ext community; and because I want to do only 1 or two lines of code to provide basic back end secure functionality for ExtJS.

Status

  • CGI - May 2008 - Work in progress, working but not pretty
  • Library - May 2008 - Working perfectly, if all you want is lists. Need to write flexibly and examples of insert, update and delete.

The CGI

Basic Requirements

  • Short
  • Semi-Secure (e.g. Bind columns)
  • Small library dependencies (DBI & JSON)
  • Aid to training and examples

The Library

Basic Requirements

  • Simplicity (in use, not necessarily in implementation)
  • Secure
  • Reliable
  • Fast(ish)
  • Versions for: Stand alone; Frameworks like Catalyst; and mod_perl2
  • TODO

Handlers

This is what the library can handle. It maps nicely to what Ext wants.

Lists

Grid, Editing with forms and Combo boxes all need to get lists of data.

Insert, Delete, Update

A single entry in a data store (such as a database).

Tree

Walking through a tree (e.g. parent/child nodes on a database, or directory listings).

Examples

Here are some examples of how it would be used.

CGI Simple List

#!Perl
use ExtJS;
my $extjs = ExtJS->new('example.db');
$extjs->list->query(q{SELECT * FROM mylist WHERE title like ? ORDER BY title});
$extjs->list->process();

Apache Module

#!XML
PerlModule ExtJS::Apache
<Location /get/mylist>
  PerlModule ExtJS::Apache
  PerlSetVar ExtJS_Database /tmp/example.db
  PerlSetVar ExtJS_Query SELECT * FROM mylist ORDER BY title
</Location>

TODO - Example showing Query written using Table Name from path info or similar.

CGI With Lucene Backend

This example uses the list code but replaces the default DBI backend with a Lucene version.

#!Perl
use ExtJS;
my $extjs = ExtJS->new();
$extjs->data('Lucene', '/tmp/lucenedemo');
$extjs->list->query(['title', 'content']);
$extjs->list->process();

Notes:

  • The data method accepts:
    • String = use ExtJS::Data::*
    • Full string = use * (e.g. MyLibrary::ExtJS::Data)
    • Object = Already instantiated, use it
    • 'dbi:*' - Assume you are passing in a dbi string
    • Filename - assumes DBD::SQLite file
    • Directory - assumes Lucene directory
    • URL - Assumes URL to RSS type feed
      • Same as using ->data('DB', 'dbi:XYZ');
    • Second parameter is passed to new of that object
  • Query is really passed into Data specifically for Lists.

Backends

The backends being written or at least thought about.

Data Store

Read and write to the data. Just a way of abstracting to a single set of entries.

  • DBI - Simple database. Just a single query. Defaults to SQLite but can use any DBI
  • Lucene - A lucene directory - query provides list of fields to search on
  • Remote - A way of querying remote objects like RSS or other XML
    • There is a large list of these I have from CPAN to EdNA to any RSS feed
  • FileSystem - For demonstrating building a Tree

The data backend must support the following methods:

  • get(query) - return a list. Optional query parameter to search against.
  • insert(data) - insert a new record. Should return the ID
  • delete(where) - delete an entry, provide what to match on
  • update(data, where) - Update an existing entry

Encoder

Encode to JSON or XML or Data Dumper - anything you want really. This system will provide

  • JSON - Basic JSON encoder
  • XML - Basic XML encoder

This version will probably not have any options to encode.

Method: encode(hashref), return a string and content type

Output

Take the Content Type and String provided by the Encoder and output it. Default would be CGI (also support for mod_perl).

Input

Call back for input.

Method: get(key), return string

Default: CGI (also support for mod_perl)

Limitations

Plugin Structure

The model above is fantastic for writing new Input, Output, Encoding and Data storage models. But it requires multiple refactoring for adding a new Handler (like Tree). Especially "Data" which needs to know how to query its objects to return a tree (quite different to a list).

General Discussion

JSON standard

The Samples, Examples and Tutorials on the ExtJS site have no standard for reading or writing data. Some of them return simple structures like a "0" or "1" and others return a JSON object. The JSON objects have no standards either, often using the word "success" to mean a true/false flag and "failure" to contain a message. Some of the ExtJS classes use JSON directly but also do not have a standard.

Here is an attempt to start a standard JSON structure, based on many existing examples, for the use in these ExtJS tutorials and examples.

#!JavaScript
{
  // Did this work?
  success: TRUE | FALSE, 
  // TODO: How to pass a message ?
  failure: "Why it failed",
  // Results array of objects (object = Javascript Hash)
  results: [
    {
      // Although only an example object... id/title would be a standard for lists etc
      id: 123,
      title: "Hello",
    },
    {
      id: 222,
      title: "World",
    },
  ],
  // Fields, also used for order - TODO Consider how to give metadata?
  fields: [
    'id', 'title',
  ],
}

Notes:

  • The format above is Pseudo code - it may not fully compile (especially in Internet Explorer !)

JSON Encoding

Almost all the example code uses a mix of manually generated JSON and automatically via library encoding. These examples encourage some very poor programming technique. Often the Javascript is very well written and the backend is poorly written.

Call Standard

Calling, CGI Parameters, general location to be defined. The theory is you can cut/paste the examples and they will work without changing your system.

Re-write Examples

This is a bit of a holy grail - I would like to have well structure database, good PHP & Perl examples and Javascript to match. I have started documenting some of the changes that would be good, but not sure what time I have to complete them:

  • Database Examples
    • TODO
  • JSON Encoding
    • Remove all manually encoded strings and use the built in JSON encoders
  • Non-Formatted Data
    • Change the 0 & 1 type return examples into a better structure.
    • This may/may not be JSON. It might be better to for simplicity.
  • Cleanup XML
    • Make sure the XML is formatted in the same way as the JSON, interchangeable
  • Javascript unnecessary Functions
    • Many examples write a function and then call it below. If the purpose is to make a block, then just use a block. But they should not be creating those functions only to call them once - temporary is bad.
  • Javascript unnecessary Temporary Variables
    • This is tricker because sometimes it makes it more readable. But some examples mix two forms. They need a clean up.

  • Javascript
  • Perl
  • Project
  • OpenSource