Introduction

I needed a web development platform to do the impossible. As a single developer I needed to rapidly assemble a large web application in a very short time. Furthermore I knew that I would be developing the programming while others would be commissioned to do the art design, and that they would need to be able to use the HTML & graphics packages with which they were already experienced. I needed to incorporate a flexible object architecture: I knew that the same components would need to reappear on different pages, at times with varying forms. What's more, like all web projects, I knew that this one would need to continue to evolve as our site matured and userbase increased. I'd had enough experience writing CGI to know that program navigation in a stateless environment becomes a convoluted mess without some higher structure to assist the programmer. In summary I needed:

* a rapid prototyping and deployment tool
* with simple to create and use reusable objects
* objects need to be able to change according to their context
* the entire project will be need to be able to be edited in Frontpage, Dreamweaver or the like and preserve its object structure
* the project needs to be based on portable, opensource tools (I'm cheap and don't know where this will end up)
* it needs to be fast enough to support lots of users on economical hardware

MySQL proved to be an appropriate backend component for dynamic data storage. PERL was where I wanted to base development.

After quite a few theoretical forays I settled on the following language description.

 

The JMH Web OBjects Language (wob)

I should begin by saying that my objects are not true objects in the OOP sense. What they really are are reusable, context-overridable html/perl subroutines which can survive being edited in a wysiwyg html editor.

The entire project file is written in an HTML authoring environment, Frontpage or the like. When rendering, page properties are taken from the properties of the HTML document.

A WOB HTML document contains a series of object definitions separated by ###objectname. The first object is treated as the base object which all other objects will modify or redefine completely if necessary. However, the first object is treated as the default object. The last object in the file must "end" and is used to produce the closing HTML tags; it can also include material you want inserted at the bottom of every page no matter what.

If an "init" object is defined, it is executed when the wob system starts. This is especially useful for establishing database connections and initializing global variables.

Object names must start with a letter and can contain a-z, A-Z, 0-9 and _. The object file is scanned for links (either go=ObjectName or name="go" value="ObjectName") and these files are classified as public access. If any other object is attempted to be called through CGI an "access denied" error will be generated. The first (default) object is also classified as public access..

Objects contain HTML, wob-perl, variable references, references to other objects, and object redefinitions with the following syntax:

* ->ObjectName -- generates a href link to ObjectName
* <a href="?"> -- the name of the script is substituted in before the ? -- it's assumed you'll add some cgi parameters following the ?. For example <a href="?go=ObjectName&size=6"> will make a link to ObjectName and set $size to 6. Objects referenced this way get classified as public access.
* &ObjectName -- In HTML this is an object reference. Like a subroutine call, this object is executed at this point in the HTML file.
* $variable -- The value of the session variable is inserted here. These values are preserved per user according to session rules. Sessions are cookie based and expire after 120 minutes of unuse. Session data is stored on the server.
* $_localVariable -- This is a perl global whose value is not preserved with the session data.
* $SQLfield -- the "field" field from the last SQL expression is inserted here
* `` #perl script goes here `` -- Any valid perl material can be inserted here. <p>, </p>, <br> are removed and &gt; &lt; &amp; &nbsp; are replaced with their corresponding values. The assumption here is that the perl is being written in the HTML editor environment. $variable and $SQLfield substitutions are made. &function is not touched.
* <script language="wob">#perl script goes here</script> -- like above, but HTML conversions (<p>... and &lt;...) are not made.
* !!ObjectName; -- within a script this is the proper notation for a object reference.
* [sql statement here;] -- wob-perl calls the default DBI datasource (the first ->connect reference in the project file) with the enclosed SQL. Note that the semicolon and closing bracket cannot be separated by white space. The result hash is returned or false on failure. The result hash is usually referenced with $SQLfield syntax.
* delete $variable -- It is beneficial to delete $variables when they are no longer needed -- this shortens the session data. This is especially important for large items (text uploads for example)
* $_insertid -- contains the last Mysql AUTO_INCREMENT value
* private $var; -or- private $var=... -- dissallows $var from CGI input -- only your code can set this value. This is important for markers for being logged in, etc.
* $_sqlresult -- contains the results from the last sql execute, usually the number of rows affected.
* $debug -- if 0 or undef no debugging; 1 shows session data and redfines; 2 shows all item calls -- you can put &debug=2 on the URL line to turn on debugging. Disabled (commented out) in compiled version.
* #insert filename -- inserts the content of filename into the current file, stripping off html header (... <body>) and </body... -- Note the filename must not contain spaces, even if quoted. The name must include an absolute path.
* #include filename -- same as #insert
* Autoquoting in [ ;] sql constructs -- if you have the structure '$variable' (single quotes with just a variable) in a square bracketed SQL statement, the contents are automatically quoted for SQL so you don't need to use the ->quote($string) operator.

Object redefinitions require a bit more explanation. When an object is called it can redefine any other object. This behavior has nearly unlimited potential in structuring your program. For example, a login object verify a password and either report a login error, or redefine certain objects to give access to protected objects. Another typical use is to have the default object contain a series of standard objects (eg topBar, leftBar, rightBar, centerPaine...) which have default definitions, but which are redefined by externally-accessible objects.

With the current implementation redefinitions are not carried in the session. This means that each rendering starts from the default state.

Object redefinitions take effect at their point of definition. The syntax is ##objectName at the beginning of a line. Note this is two ## instead of three ### as for the object definition. Redifinitions carry to the next object definition or redefinition. Most redefinitions will redefine lowercase-named objects.

The package also include a few useful functions:

* &quote4url($string) -- returns a string suitably quoted for use in a href.
* &badlanguage($string) -- returns a non-null string if $string contains rude language. The return value is the first offensive word found.
* &clearsession -- resets the session data. This is particularly useful as part of a LogOut object, or if you want to manually expire the session.
* &wf($filename,$content) -- writes a file named $filename full of content $content
* &rf($filename) -- returns the content of file $filename
* &autoformat(text) -- changes plain text to html with some degree of smarts

 

How WOB Works & Deployment

The program works by parsing the wob html file into a perl script. In the development phase this script is simply eval'ed, but for deployment the script can be wrapped and executed as a stand-alone perl cgi script. Similarly it can be easily modified to work with speedy-cgi, mod-perl or fast-cgi for higher performance systems.

 

Instalation

Download the current source file from http://wob.sourceforge.net/wob.txt. Rename it to wob.pl, move it to an appropriate location, and mark it executable (if you want). Create a CGI executable shell script like this one:

#!/bin/sh
/usr/bin/perl wob.pl MyWobFile.wob

Of course your perl path, wob.pl path and MyWobFile.wob should be replaced by actual paths.

Edit the wob.pl file to set the following globals to appropriate values:

$CompiledOutput='wobout.pl'; ## file name for compiled output
$sqllog='/usr/users/www/pma/sqllog'; ## file for logging SQL info
$_sid_base='/usr/users/www/pma/sid/';

CompiledOutput should be a filename and path to put the result perl script, as is mentioned in the Deployment section above. sqllog is used for debugging -- leave it blank if you don't want to log SQL requests and responses; set it to a file & path if you want to inspect them for debugging purposes. You sould make it blank for deployment. _sid_base is a directory to put session data files and must be writable by your web server process.

You should now be ready to try your cgi script.

 

Limitations

At this point CGI parsing is limited to text only data. Actually any data is ok except \001 - \002.

Since wysiwyg html editors often wrap text automatically, new lines are often undesirably inserted into `` code segments. Comments are especially problematic, but any strings where the formatting is significant can be affected. Use the <script> construct instead as a workaround.

 

Example

What follows is a brief example to show what a basic WOB file might look like.


###Default

&TopLeft &TopCenter &TopRight
&Left &Center &Right

This text appears on all pages which don't override Default. :-)

###TopLeft

WOB Title

###TopLeft

###TopRight

Brought to you by WOB

###Left

->Choice1

->Choice2

->Choice3

###Center

This text will end up in the center frame portion by default.

``$count++;`` The count is now $count.

###Right

Context

Sensitive

Material

Here?

###Choice1

##Center

Choice 1 will redefine the title to be Monty-Python-esque

##TopCenter

And Now For Something Completely Different

###Choice2

##Center

etc...


License

Copyright (C) 2000, John M. Hanna. The WOB components may be distributed under the terms of the General Public License (GPL). THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.

 

ToDo (Comming Soon)

A secondary script to hide & unhide `` scripts into <script> format
Auto-quoting of sql variables -- important for security.
Option to preserve redef overrides in session.
Form validation, success, cancel processing
Example code snippets file.
Script to find use of uninitialized $_xxx variables (mod_perl compatibility).

 

About the Author

John Hanna is the e-media coordinator at Caleb Project, a non-profit Christian organization. <jhanna@cproject.com>

updated 00-06-19