This is an example from the standard WebObjects distribution. It has been coverted to WOPerl.


Dodge Lite

The Dodge Lite application presents potential "customers" with a virtual Dodge Showroom. In this virtual showroom users can display merchandise based on criteria such as price and model. Users can view the cars returned from their queries and click on a particular car to learn more about it.

Once a customer selects a particular car, a "shopping cart" object is created. This object becomes a repository for preferences the user specifies.

The "Lite" portion of the Dodge Lite application's name refers to the fact that the entire application is written in WebScript, with no compiled code. Instead of a relational database, Dodge Lite uses a so-called dictionary data source. This topic is discussed in more detail below.

Dodge Lite is a good example of a Web shopping application that stores state as a user progresses through a series of forms and pages.


Notable Dodge Lite Components

Application

The Application.wos script declares a global variable dodgeData, and a session variable customerChoice. The dodgeData variable is initialized in the awake method with the contents of the file DodgeData.

The customerChoice variable is the user's shopping cart. customerChoice is a session variable, meaning that each session has its own version of it. customerChoice is instantiated as an NSMutableDictionary object in the script Car.wos, at the point the user selects a particular car.

The Application script primarily consists of methods that return information from the dodgeData "dictionary data source," such as car colors, types, models, and so on.

Main

The Main.wos script initializes the browsers and pop-up button the user sees on the first page of the application. When the user clicks on the 'Display Cars' button, it invokes the method displayCars. The displayCars method sets variables for the next page based on the user's selection in the browsers. This determines which cars get displayed in the next page. The displayCars method also invokes the next page's fetchSelectedCars method, which ensures that when the next page appears, the cars it displays are based on the user's criteria.

SelectedCars
The next page is SelectedCars. Its fetchSelectedCars method is invoked from Main.wos before SelectedCars is displayed. fetchSelectedCars checks the user's selection against the data stored in the dodgeData global variable. If it finds cars that match the user's criteria, it displays them. Otherwise, it displays a message that no matches were found.

When the user clicks on a car to select it, this invokes the selectCar method, which navigates to the next page, Car. The selectCar method invokes the next page's setSelectedCar: method before it returns the page.

Car
It is in this script that the customerChoice "shopping cart" object is created if it does not already exist. Remember, customerChoice is a session variable declared in the Application script. In Car.wos' setSelectedCar: method that was called from the preceding page, any previous contents of customerChoice are discarded, and customerChoice is reinitialized with the new car selection.

This script figures out the packages that are available for the user's selection. Once a user clicks on a package, the script changes the icon to show that the package is selected. If one package negates the possibility of other packages, those other packages' icons are grayed out.

From the Car page the user can navigate to either the Dealers page or the Leasing page.

Dealers

The Dealers page is noteworthy because it has no script associated with it-- just an HTML template and a declarations file. The declarations file associates methods defined in the Application script with WOActiveImage dynamic elements. When a user clicks on one of these images, the corresponding method in Application.wos is invoked.

Leasing
Like the Dealers page, the Leasing page also has only a declarations file and an HTML template. The Leasing page is not fully implemented in Dodge Lite. You can find the extended version of the Dodge Virtual Showroom at the Next Software Inc.'s web site (http://www.next.com).
Footer
The Dodge Lite application includes a Footer component that consists only of an HTML file. This footer contains text and links to other pages.

Interesting Issues From Dodge Lite

Loading Application Resources

The Application script in Dodge Lite uses the WOApplication method pathForResource:ofType: to load the file DodgeData into the application. This method takes a path and the file's extension as arguments:

    id filePath = [WOApp pathForResource:@"Database/DodgeData" ofType:@"dict"];

You can use this method to load different kinds of resources into your application-- for example, images, sound files, data files, and so on.

Using a Dictionary Data Source

Instead of using a relational database, this application uses a simpler alternative-- a dictionary data source. A dictionary data source is an NSDictionary object in which data is represented as key-value pairs. The dictionary data source dodgeData is initialized from the filePath object that was created above using pathForResource:ofType:.

 
    dodgeData = [[NSDictionary alloc] initWithContentsOfFile:filePath];

As a global variable, dodgeData lasts for the duration of the application. All user queries are checked against the data it contains.

ASCII Property List Format

The reason that the dodgeData NSDictionary object can be initialized from the file DodgeData is because the file contains data in an property list format. A property list is a compound data type that consists of NSStrings, NSArrays, NSDictionaries, and NSDatas (though NSDatas have limited utility in this context). Property lists can be represented in an ASCII format, and property list objects such as NSDictionaries and NSArrays can consequently be initialized from ASCII files that use this format. For example, the following statement shows the format used to represent dictionary data:

    {
	"Neon" = {
	    "name" = "Neon";
	    "picture" = "../Images/Models/NeonClrMap.gif";
	};
    }

While NSDictionary property list statements use curly braces to surround groups of key-value pairs, the ASCII property list format for NSArrays uses parentheses, as follows:

    (
	"Dogs",
	"Cats",
	"Horses"
    )		

You could create a file containing array data in this format and use it to initialize an NSArray.

A property list object can contain other property list objects. For example, the data in the DodgeData file includes dictionaries within dictionaries as well as strings and arrays:

    "Neon DH22" = {
	"ID" = "Neon DH22";
	"model" = "Neon";
	"type" = "2-Door";
	"name" = "2-Dr Coupe";
	"picture" = "../Images/Types/HighlineCoupe270.gif";
	"basePrice" = 11240;
	"packages" = ( "Neon D", "Neon 23 D", "Neon F");
	"marketingDescription" = "Here\'s the Highline flavor in two-doors.  That and other features (also available on the Highline 4-door) like body color fascias, bodyside molding and grille bar.";

Because the top level object in the DodgeData file is a dictionary, the file can be used to initialize an NSDictionary object. NSDictionary objects initialized from the file will contain dictionaries, strings, and arrays, all enclosed within a top-level dictionary.