How to combine e-mail push and Web pull with Next's WebObjects
Jon Udell
Web protocols and e-mail together make a curious two-headed beast. Using e-mail, I can push data to your computer. Using the Web, you can pull data from mine.
Lately, I've noticed that people push a lot of big documents into my mailbox -- documents that would be more useful to me if they were on the Web. Why mail them? It's not because the senders don't operate Web sites. Many do. But nothing alerts me
to the appearance on those sites of new documents intended for me. Hence the use -- or, I would say, the abuse -- of e-mail.
In this month's column I'll describe a simple way to improve e-mail and Web synergy. It involves an extension of BYTE's Virtual Press Room (
http://www.byte.com/vpr/vpr.htm
). VPR streamlines communication between vendors and BYTE editors by enabling vendors (or their public-relations agents) to submit press releases and product descriptions directly to a searchable, navigable Web archive.
The problem with VPR's first incarnation was that editors had to log in and actively scan the archive. Once the novelty wore off, they didn't do that archive check on a regular basis. Should VPR, therefore, deliver its documents to editors as e-mail? No way! That would further overload mailboxes that are already groaning with broadcasted documents. Instead, I decided that VPR should use mail properly, to deliver messages rather than lengthy documents.
VPR Update, Version 1
The daily VPR update delivered to editors contains a summary of the late
st batch of documents added to the archive, along with pointers (URLs) that lead to the documents themselves. Here's part of yesterday's update:
Company: TDK Systems, Inc.
Title: TDK Systems introduces 100Base TX LAN Card
URL:
http://dev5.byte.com/vpr/vpr1404.htm
The Perl script that produces these messages is straightforward. Some of the fields I wanted to include in the update were stored as META tags in the VPR header (see
http://www.byte.com/art/9512/sec9/art1.htm
). I'd already written a function to extract these fields in order to build views of the archive by co
mpany and product (see
http://www.byte.com/art/vprtabs.pl
). Other fields, such as Title and Summary, aren't stored in the VPR header. They're just sections of each VPR document. But since the script that writes these documents guarantees regular structure, these pseudo-fields are easily recoverable.
What makes VPR Update effective is that each update message includes a link to a complete document. Here's an example of how it can work. On February 29, Susan Nicolls submitted an announcement for General Magic's new Active Web Tools. On March 1, it appeared in BYTE editor Rex Baldazo's VPR update message. Intrigued, Baldazo clicked once to view the document. From there he clicked again on Nicolls' "mailto" URL (activated automatically by VPR) to acknowledge receipt of the document and request more det
ails.
It would be great if things always worked this easily but, unfortunately, there's a catch. Baldazo had to be running the Netscape 2.0 mail client, which converts Web addresses in message texts into live, clickable links. Editors who receive VPR updates on their BIX or cc:Mail accounts miss out on these links. Of course, they can cut the Web address to the clipboard and paste it into a browser. But that's like getting up off the sofa to change channels on the TV. Life's too short. We demand instant gratification and, in this case, we should have it. Lotus Notes users take for granted the ability to mail doclinks to other users. It's a powerful technique that Internet users should be able to take for granted, too.
VPR Update, Version 2
Inactive links weren't the only problem with version 1. Some editors wanted weekly rather than daily updates. Others wanted updates with more, fewer, or different fields than those provided by default. Thus was born a Web application that enab
les editors (and, more recently, sales and marketing staff) to specify:
1)
the e-mail address at which to receive updates
2)
the frequency of updates (daily or weekly)
3)
the set of fields to be transmitted (i.e., Company, Product, Title, Date, Summary, Contact).
This application required a Hypertext Markup Language (HTML) form connected to a database of preferences. For the planned 20 to 50 users, that database didn't have to be anything fancier than yet another structured ASCII text file. Reading that file in Perl was trivial; it can easily absorb an ASCII representation of the necessary data structure, an associative array of lists containing lists. But unlike Lisp, Perl can't natively write back a changed version of this structure in ASCII form.
Beyond Perl: Next's WebObjects
Of course, there are ways to make Perl structures persistent. In Unix, Perl can store flat associative arrays in DBM databases. For nested
structures, which this application requires, Perl 5 modules implement persistence. But there's more to Web development than Perl. Here was the perfect opportunity to test-drive Next's WebObjects, which I'd recently downloaded from
http://www.next.com
. I've always liked Objective-C and the Next object libraries, but I never had a convenient way to deploy applications built with them. On the Web, Next's toolkit and many other software toolkits enjoy immediate mainstream applicability. The freedom is exhilarating.
WebObjects is available for Next, Solaris, and Windows NT (Intel only) platforms; I'm running it on NT. It works with a variety of Web servers; I'm using it with Microsoft's Internet Information Server. And it works with any browser because all the object intelligence lives on the server side.
Like
nearly all the toolkits that map database records to Web forms, WebObjects encodes the mapping using HTML templates (see
A
in the figure
"Anatomy of a WebObjects Applications"
). Unlike many of the others, though, the WebObjects template language does not express logic such as "If Field1 > Field2 then output Field3." You encode higher-level behavior by declaring a set of Web components (see
B
in the figure
) and writing an Objective-C script (see
C
in the figure
) to manipulate those components.
Anatomy of a WebObjects Application
The flow of events in a WebObjects application begins when a user clicks on a URL like this:
www.byte.com/cgi-bin/WebObjects.exe?prefs
where
prefs
refers to a WebObjects directory tree containing templates, mapping files, and scripts. WebObjects.exe is a small, transient stub responsible only for sending a request
to a daemon (Unix) or a process (NT) that implements the guts of an application. This stub-and-daemon architecture minimizes Common Gateway Interface (CGI) overhead. Furthermore, it makes even the humblest WebObjects application (like mine) inherently scalable.
Users log in to get to the preferences screen (see
D and E
in the figure
). Since HTTP is stateless, how can the application avoid mixing up the preferences of one user with those of another? WebObjects handles this automatically by creating stateful sessions, stamping transactions within a session with HTTP cookies, or (for browsers that can't handle cookies) with hidden fields. To tap into this state management you need only declare objects, such as the preferences list, to have session-level -- rather than application-level -- scope (see
F
, the WebObjects tree,
in the figure
).
The components I used were the simplest kind: HTML intrinsics such as the password tex
tbox and the drop-down list box. But the class library that supports WebObjects also provides fancier components, such as a calendar. These components, unlike their Java counterparts, require no extra client intelligence. Ultimately, the libraries render everything as HTML usable by any forms-capable browser. That's a refreshing echo of the Web's original simplicity and universality. Components can, meanwhile, enjoy the full benefit of object orientation. In a family of components related by inheritance, for example, changes in appearance and behavior propagate automatically.
Setting Your Preferences
On the preferences form, a user can change the e-mail address, the update frequency, and the list of fields included in the update. The declaration of the form component names the routine that's wired to the Submit button. That routine has access to the session object containing the current user's list of preferences and to the application object containing the dictionary of all users' p
references. A dictionary is the Next (and Smalltalk) equivalent of a Perl associative array -- a set of name-value pairs. Two lines of Objective-C suffice to update the dictionary, then save it to disk (see
G
in the figure
).
Saving the dictionary as a text file works fine for the few dozen current users. It clearly won't work fine for tens of thousands of users. This scenario isn't far-fetched, either. I'm planning a registration system for the BYTE Site, and personalized delivery of VPR updates will be one of the benefits that registered users enjoy. WebObjects Enterprise, the high-end commercial version of what Next gives away for free on the Web, was built for jobs like this one. It includes Next's Enterprise Objects Framework, which creates persistent mappings between objects (such as my preferences dictionary) and Sybase or Oracle data stores.
It would take more than one project to justify the $25,000 price tag for WebObjects Enterprise. And the midrange
version, a $2500 product called WebObjects Pro, doesn't offer the same compelling abstraction of data management. So I'll probably end up with a different solution.
But even if I don't buy Next's toolkit, I absolutely buy into Next's development philosophy: True object-oriented business logic, mapped transparently to plain-vanilla HTML widgets on the front end and industrial-strength SQL storage on the back end. This server-centric model runs contrary to the client-oriented Java/ActiveX movement but, for right now and for the near future, this approach can deliver Web applications to a lot more users.
Finishing Touches
My WebObjects application only gets and sets preferences. Ideally it would create and send updates, too, but the free version of WebObjects can't call a mail program. You can link this capability into your application with WebObjects Pro, but for me it was easier to handle this chore in Perl. Scheduled to run daily and weekly, a script (
http://www.byte.com/art/download/prefs.pl
) parses the preferences file, extracts requested fields from VPR documents, creates update messages, and sends them.
The final result is a hybrid application: half Perl, half Objective-C. It's a hybrid in another sense, too: half e-mail, half Web. I think the world needs more of these. Consider list servers. It's feast or famine: either too much information or none. A hybrid push/pull approach would be so much nicer. I'd still receive timely updates, but I could drill down for details on my own terms.
Next time you want to e-mail me a hefty document, do us both a favor. Just mail me a pointer.
TOOLWATCH
CelAnimator............$249
FutureWave Software
San Diego, CA
Internet:
http://www.futurewave.com
From the maker of SmartSketch, the most intelligent paint/draw hybrid I've seen, comes a nifty tool that builds vector animations for the Web.
BOOKNOTE
SQL for Smarties: Advanced SQL Programming
by Joe Celko
Morgan Kaufman
Internet:
http://www.mkp.com
Price: $39.95
You can go a long way managing data with Perl, but eventually you have to break out a real database. When you do, here's an excellent, vendor-neutral refresher course on advanced SQL.
illustration_link (91 Kbytes)

How WebObjects manages VPR update preferences. Users can view and change their settings with a browser. Behind the scenes, HTML templates and Objective-C scripts drive the application.
photo_link (42 Kbytes)

Jon Udell (
judell@bix.com
) is BYTE's executive editor for new media.