Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2007-508
$eventId
ID of event: wwdc2007
$eventContentId
ID of session without event part: 508
$eventShortId
Shortened ID of event: wwdc07
$year
Year of session: 2007
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC07 • Session 508

Building Powerful Web 2.0 Applications with WebObjects

Information Technologies • 1:04:59

WebObjects is a terrific platform for having your modern web applications take advantage of the latest web-based services such as social networking, blogging, and wikis. Watch Apple engineers demonstrate the ease of development and deployment provided by the WebObjects tools, and see how WebObjects and Mac OS X Server make a fantastic combination for hosting your next-generation web applications.

Speakers: Pierre Frisch, Daryl Lee, Mike Schrag

Unlisted on Apple Developer site

Transcript

This transcript has potential transcription errors. We are working on an improved version.

I'm the WebObjects Engineering Manager I think some people know me. Today, we are going to talk about two things. First, we're going to see what's new in WebObjects 5.4. And then I'm going to give the mic to Mike, and he's going to talk to us about WebObjects 2 and Project Wonder.

So what's new in WebObjects 5.4? So first of all, I'm going to give you a bit of overview of what the state of WebObjects is today. WebObjects started in 1996. So it's probably the oldest framework on the market with WebObjects 1.0. We went to Java Native in 2001 with WebObject 5.0. And today, we are to WebObjects 5.4.

And what is the spot of WebObjects in the marketplace? First of all, we use WebObjects within Apple heavily, a lot. It powers Apple, it powers all sorts of systems throughout Apple. We've got many, many, many engineer developing with WebObjects inside. We love it, we use it, it's fair to say. And the other thing is that we've changed the WebObjects model, development model, and we now integrate within the products patches that come from the inside Apple users.

And so you are going to see a lot of movement on the framework just coming from everyday use of people developing with WebObjects within Apple, okay? WebObjects outside. You can see, if you do a search on Google and you look at the URLs with WebObjects in it, there is 4 million pages, over 4 million pages in Google.

Those are public pages that you have created with WebObjects on the web. That doesn't count any of the private page, just public pages. And that number is growing I think, by what I can remember, because I don't have the long history, to about half a million a year. So WebObjects is growing well. And thank you to you all.

As you know, we announced last year that we're focusing on the run time. In WebObjects 5.4, a lot of change under the hood. We have kept all the public API as they were, and we tried very, very hard to keep the compatibility. However, with change, a lot of internals.

So for all of you that have subclass internal APIs, and I am one of the culprits, please, please look at your code because we don't make an omelette without breaking eggs. The internal has changed. So look at your code, look at any override of the private APIs because I cannot guarantee that it didn't break, okay? What's in WebObjects 5.4? So I'm going to cover four topics this morning, this afternoon. First of all, support for AJAX. Then the new look for the i2 web. We have done quite a number of modernization preparation for the frameworks, and what's going on with the build and deployment environment.

Support for AJAX. We have got a new AJAX request handler. And the reason for that is that when you do pages, AJAX typically do page fragments. So you don't want to put the page fragments in the page cache, so we actually put in the framework support for page fragments so that you can actually handle the request properly. So this is normally handled completely transparently. You don't have to worry about, we just do it. And Mike is going to talk a little bit more on how he's using it in the Project Wonder. XHTML-compliant code generation.

( Applause )

Thank you. All tags are now lower case, quoted and closed properly, which also means that your code needs to be. We correctly handle class and ID, which means that you can now create reusable component that handles class and ID properly. We carry them around, we do the right thing with them, we don't put them with the IMT. Also, the weird behaviors that choose to happen.

The messages you can use it in reusable component. We also have a new way of creating ID because typically all of you know that WebObjects element ID has a series of numbers and dots. Well, the element ID on the XML page cannot start with a number and cannot contain dots. So we have to do something. So you can now invoke a metatag to return you a proper element ID. And (inaudible) is configurable. If you don't like to have a WO in front, you can change it. If you don't like this code, you can change it.

This is a big thing. We changed the single file component parser. Okay, typically, all components are contained in a bundle with an HTML in the word and maybe sometimes other files. We are still supporting that format. We are not duplicating it. This is supported, and we intend to carry on supporting that format for a long time.

However, we have created a new single confined format where you can include your binding within the HTML page. So essentially, what you can write is a single tag where you are to put your binding directly in the HTML tag. We have got a syntax with the square bracket. If you don't like it, you can revert it to the dollar sign. It's a question of style.

The other big thing with the parser is that you can actually extend it. We introduced into binding the notion of protocol, which means that you can actually write protocol column in the binding. What that means is you can actually create your own protocol handler within WebObjects to create to go after different syntax. Typically, ognl have heard about Groovy, Janino, which kind of be a bit more obscure. But you can extend it to whatever you want. And you can do all sort of things. You don't have to rewrite the parser anymore.

Consistent support for secure URLs. That's something that should have been done a long time ago. You can actually now interrogate the request to know whether it was a secure request or a non secure request. The context is going to have the same thing, a secure mode. And typically just works. So if you have got a secure request, every URL you are going to turn are going to be secure and just works.

The i2 web. The i2 web new look. Okay, you used to have that kind of page that we all know about. We changed it. This is an xmlHttpRequest query so that as I will actually load page fragments, it's fully AJAX planned. And we just modernize everything. Same thing for the list where you actually have got a new look for the list where you can have the side and the indication of the focus. We're going to see that with file in a minute.

And we have got a floating palette on the long lists. Daryl...

( Applause )

So as Pierre said, you know, our direct web templates were looking pretty long on the tooth circa in 1996. So we thought we'd do a pass at them and sort of AJAXify them and give them a fresher experience. So if we could flip to the demo machine, let's see, here we go. So what I'll show you first is the new WebObjects's look. And we kind of added a black and white polished look to it and prominently put WebObjects's badges there and things like that.

Let's do a quick search. And let me just look at the 40 items here. As you can see, you know, it's kind of resizing and doing fun things. It's really easy to-- let me just show you a few more pages here just for a quick tour. Here's our edit page. And, you know, it works just like bold direct web templates. Let me show you our new basic look. And that one has a little bit more fun AJAXy toolbar in it.

And as you can see, there's the focus indication that Pierre was talking about. So the mouse events. And let me go fetch a bunch of rows here. And as you can see, we kind of use CSS a little bit and layer things. Another thing you might be interested in is that these are all AJAX requests that are going on in here when I click the arrow buttons here to page in more rows. So there's just a quick tour. Just wanted to show you what the looks were. We've kept the neutral look pretty much the same. So if you like customizing templates that way, that's still available for you. So anyway, so those are our new looks. Back to Pierre.

( Applause )

So after the candy in the store there, some of the things that we've done to the run time. The first thing we did is modernize the NSArray and the mutable array in a set so that you can now support a Generics. So we brought everything back.

We actually support 1.5, and not only we support it, but we require it now. So you can actually write interation properly. So instead of doing the old fashioned interation with an index, you can actually do it a new way with just an interatim. It's actually very nice, and you don't have to type cast anything. We modernize the plist serialization so now you can read and write XML plist. And we fully support the Apple DTD, including the time value Integer, Float finally.

Web services, same thing. We brought everything to the modern day and time, so we access one full compliant. And I believe they work now. We improved the schema performance. Essentially what we did, we introduced into schema the management of indexes, so you can actually create your table index directly in the schema, which basically enabled you to keep everything in one place. You don't have to have those SQL script lying around to recreate the indexes each time.

And I'm going to show it to you in a minute. Mike actually provided all the support in WOLips, so you can actually create them in WOLips. We improved the schema generation at run time, so we actually fixed all the synchronization features so that it actually works, create an index and do the right thing.

We also enabled the support of enum, so if you create custom types in your model, custom attributes, you can actually return a Java enum, which is also some feature that I know a lot of you have requested. And so you can actually return the Java enum as a custom type.

And all of that is supported in WOLips. So if you look at your WOLips, probably if you download the recent version, I don't remember exactly when Mike put it in, but if you download the recent version, you'll see that now you have got an option to create an index and actually it just works. Thank you, Mike.

( Applause )

Java EOGenerator. The old EOGenerator doesn't work in Leopard, so we had to provide it as a replacement. So we took the time to actually write a new one that actually is more modern and choose a WebObjects template parser so you can actually write your template class using your traditional syntax of the WebObjects syntax. Which also means that it's slightly and also means that it's all slightly more convenient because you can use all the new attribute methods so you can actually access all the new stuff, new Java stuff instead of being content to the old Objective-C stuff.

Build deployment, build deployment, build system. Let's be very, very clear. The old Xcode system, if you have got existing projects in Xcode, you can still build them. The jam build system is still there. It's actually not there in the seeds. That's a bug. It's going to be delivered with Leopard.

However, you cannot create any new project using that technology. You can create an Ant project in Xcode in you'd like, but we don't provide any support for it. We just provide Xcode support for Ant. So there is no template to create a WebObjects in Ant. Recommended build system is still WOLips and Eclipse.

However, for those of who don't want to use Eclipse, we are sponsoring tools, and we're actually sponsoring an open source repackaging of the entity modeler so that you can use the entity modeler outside of Eclipse. This will be distributed as an open source part of the WOLips project.

The second big push that we want to do in there is a self-contained bundle. This is actually a feature of 5.2. Poorly documented, poorly supported, and really, really useful. What we want to do is move out of the traditional framework towards what we call the self contained framework jars. All that's been delivered since 5.2 in your /Llibrary WebObjects/lib folder. And you've been able to use it forever. However, very few people have used them. So that's a format we'd like to carry on moving forward.

Same thing. You can actually build self contained applications. You have been able to do that since 5.2. If you push all your jars into .woa/Contents/Extensions, all the jars in the directory are going to be loaded before anything else. What that means is that if you push in your application to 5.3 or the 5.4 jars, you are going to run with the jars you have tested with, not the jar that I store on the machine. That will provide a much more reliable deployment environment than trying to mix and match and also enable you to upgrade the application independently of the upgrade of the OS.

Deployment. Last year, we talked about a new deployment environment with all sorts of things. That was premature. When we actually put everything together, we discovered that it wouldn't work. Even provide the same services. So for this release, for Leopard, we are keeping the traditional deployment environment with JavaMonitor and wotaskd. The example source, so if you want to change or if you were to do a modification, you can.

What we have done is that we have folded the mod WebObjects to Apache 2.2. It supports 32 and 64 bits without any problem. And so you keep your traditional deployment environment. Moving forward, we're going to move to a more modern architecture, probably something in the same line than Monitor and wotaskd. And we are going to move more toward JMX integration for the monitoring.

We are trying to help the community as much as possible, pushing the run time, helping all the tools, the open source tools, working very closely with the Wonder team and WOLips team to try to get things in sync and delivered to you at the same time you need them.

And the last thing I want to say is please, please install the 5.4 beta, test it, check it, send me bugs. If you have got all bugs, try to see if they are still there in 5.4 and put a note in the bug report. I can guarantee that the bug report, again, the 5.4 beta is going to have priority against any other version.

So really, if you want something to be fixed, add a note in your bug report, have tested it, it's still there in 5.4, I really need that to be fixed. And we have got a very short period of opportunity to fix those, if you want them fixed. So please, find bugs, go on.

And now, I invite Mike to present.

( Applause )

So last year, I had the cell phone camera. And Pascal gave me an actual camera to do the photo with this year. So everybody smile. We'll see how this works out. I've got to get the flash, the 200 feet long. All right, so AJAX framework. It would help to have the switcher for the slides.

Can you switch back to slides, please? Thank you. AJAX framework. I guess I should say I'm Mike Schrag from mDimension Technology. What is AJAX? AJAX stands for Asynchronous JavaScript And XML. If you've seen anything like Google maps or Flickr or any of the modern web applications, you've noticed that they do a lot of behaviors that are much more like desktop applications.

Namely, you have things like you click on a link and it refreshes just a section of the page versus doing a full page refresh. What this means is several things. One is you can do smaller refreshes, which means, you know, less bandwidth usage. It means that your applications perform much more like a desktop app than a traditional web application. And one of the other reasons that you might want to do this is that, you know, with any new technology like AJAX, you have new expectations from your customers.

Namely, they're also using Google maps and Flickr and 37 singles apps. And they expect your WebObjects applications to be just as cool. So what does this mean for WebObjects? Well, components, right? I mean, components are what make WebObjects really cool. You have the stateful components, you have components that can-- you could have multiple ones on a page. You have automatic binding synchronization, an itty bitty reference to direct actions with AJAX.

I'm going to focus on the component aspect. If you're doing direct actions with AJAX, you'll find that it's pretty much just like any other of the frameworks. You're doing, you know, your own state management. You're passing state back and forth. What, to me, is particularly interesting and exciting is taking advantage of stateful components and AJAX. So I'm going to do a little demo here.

So this first demo is just a quickie. And that is to show some of the examples that are in Project Wonder's AJAX framework. The first one that I'll do is the usual hello world example. And of course these don't get touched by Apple designers. So, you know, that's what you get.

So in this first section, we have an example that's showing how this would work in a traditional WebObjects application. Behind this is essentially it's a WO hyperlink with an action that's bound to a method. Every time I click this WO hyperlink, you can see, you know, the progress part is a full page reload. If it was wide enough, you'd be able to see all the element IDs changing.

You know, this is your traditional WO app. You can see the time stamp here at the top changing. At the bottom here is what we call an AJAX update link, which I'll tell you about in a little bit. And so instead, first of all, you can see how much faster I can click this. I can click it about two times faster. And all it's doing is sending just that one little section back and forth.

What's particularly cool is on this bottom one, it's exactly like the top one in that it's a component action. It's a stateful component action. That string there is a stateful binding on a WO string to a variable in my component. It works exactly like the rest of WO, except now we're having, you know, partial updates of a page with AJAX.

So one of the other ones that's kind of neat is the drag and drop list example. This is something that people have started to do more with drag and drop. So this doesn't look necessarily all that exciting, but what's cool is this does magical things, just like you expect WO to do.

Namely, every one of the things I'm dragging are actually bound to EOs, or can be bound to a full on job objects, whatever it is. So, you know, the example I always give is you could literally be dragging a T-shirt EO and drop it into your shopping cart.

When the action actually fires, it's just like, you know, your action method with a WO hyperlink in that the right object is bound up at the right time. So, you know, when you're, you know, its T-shirt bought method is called, you just have a reference to the T-shirt object, which is what, in my mind, makes WO magical and amazing to be able to develop with.

And lastly, for the quick demos, is AJAXInPlace. This is one of the ones that actually doesn't get a lot of play on the mailing list, but to me is one of the most powerful in the framework. And that is it lets you essentially define a view template and an edit template with a full on WO component.

So this view template here, when I click on it, it goes into edit mode. I can have custom view and edit controls. And as an example of a more complex scenario, here's a slightly more complicated WO component, that when I click on this, it then switches to a completely different edit component.

You can actually do some amazing things with this. It's a very simple way to be able to, you know, provide, you know, a very clean look when you're not in an edit mode and switch to whatever complexity level you need. Again, using components just like you're used to. So that's the quick examples. Incidentally, everything that you see up here is actually part of the AJAX example that is inside of Project Wonder. So you can grab it and kind of go through and see everything. Slides, please.

Or not. All right, so, okay, what do you have to do? With any framework, any developer is going to ask, you know, what am I going to have to change in my code to make use of this? And the hello world example, this is something roughly like what you saw.

You have a time stamp above this div. You have a div that has an ID. You have a WO string bound to a hello world, you know, it could be a method. I have a WO hyperlink with an action, with an update link, and a time stamp up above.

So what do we change for hello AJAX world? That's pretty much it. The parts in yellow are actually what changed. And so essentially, what was a divs now is an AJAX update container. Incidentally, you can see I'm using the inline binding syntax here. This is actually Project Wonders, but you can configure the 5.4.1 to work in the same way. My WO hyperlink turned into an AJAX update link.

And there's one extra sort of magical thing, and that is UpdateContainerID. Unlike a regular WO hyperlink, you know, a WO hyperlink is just going to refresh the entire page. For AJAX, though, you need to be able to specify, you know, what part of the page do I want to refresh as a result of this? And so here I'm specifying the HTML ID of the div that I want to refresh or the LI or whatever it is. And so in this case, the update container ID has ID content. The link says refresh container with the ID content. And that's it.

And, you know, this is a slightly contrived example. But I'm going to walk you through something you can actually see. Doing these conversions really is pretty much this simple. There's very few fundamental components that you need to be aware of that you can then turn around and do some very rich things with.

So this is the one technical slide that I have. I started out with much more and we chopped them out. The traditional request-response loop, takeValuesFromRequest, invokeAction, and appendToResponse. Those are fundamentally the same, with the one catch that in an AJAX update, say you have a link at the bottom of your page, you have an area that you want to refresh at the top of your page, when you click the link, by the time the action, WO, gets down to evaluate the action of the link being pressed, it's already passed by the part at the top. It's now sort of lost its opportunity to append a response to the area that you want to refresh. So what the AJAX framework does is actually sort of sneaks in there, it runs your invoke action phase the normal way.

It then turns off some things in the framework so that it doesn't trip you up and double fire your actions. It then does a second invoke action pass, this time actually triggering the area that you told it to refresh to dump its outout out. So the most part, you don't need to care about this. It's pretty much totally seamless. It just happens in the background. But it's, you know, sort of a notable element.

So what are the three primary components you need to care about? The ones right here. AJAXUpdateContainer, AJAXUpdateLink, AJAXSubmitButton. We have a huge number more that do cool things like Google maps, you know, what have you. But the three that if you were just starting out and you want to see how do I use AJAX framework, these are the ones you need to care about.

So AJAXUpdateContainer. This is sort of the fundamental component. AJAXUpdateContainer lets you essentially specify a section of your page that is AJAX updatable. So in the previous example, the hello world example, I turned a div into an AJAXUpdateContainer. What that allows me to do is later I have an AJAXUpdateLink, an AJAXSubmitButton that can go back and refresh that area. I'm listing the important bindings here, but there are tons of bindings. You can actually configure these things in lots and lots of ways.

AJAXUpdateLink, pretty much exactly like the WO hyperlink, but AJAXified. The important bindings, action and updateContainerID. This basically has the same semantics as the WO hyperlink. You can use it, for the most part, just in the same way, except when you add this additional UpdateContainerID, you then tell it I want to refresh this section of the page. In fact, if you leave off the updateContainerID, it lets you essentially make update links that all they do is fire background actions, which is actually kind of a useful feature too.

I've got to press it very hard. AJAXSubmitButton. It's the cool friend of WOSubmitButton. The important bindings, updateContainterID, action and value. Just like a WOSubmitButton, action and value work identically, except it now has this-- just like AJAX update link, updateContainerID, this essentially lets me say, you know, when I submit this form, what area of the screen do I want to refresh? What update container do I want to refresh? And this actually does a background form submission.

And like I said, there's tons of components that are available. We have AJAX file up loading, dragging and dropping, auto complete, like the Google auto completion, highlighting inplace editing. There are tons in there. AJAX example actually covers most of these, so if you want to see sort of example uses of common cases, definitely look in that.

But the way we typically work is someone asks on the mailing list, you know, how do I X? And if it's not already in an example, we make a new one and put it in there. So most of the common cases, there are already some examples of for you.

So let's actually go through and do a conversion from a non AJAX app to an AJAX app. Actually, this is the div here for what I'm about to show. So this app is a very, very simple blog app. It really only has a post in this model, so you have a set of posts on a page. And I'll show you how you might go from a boring WO app to a really, really overblown effects garish AJAX app.

Can we go to demo machine, please? So here we have the very, very boring Larry World WebObjects non AJAX blog. So just to give you a feel for, you know, the types of things that this blog does, I can add a new post, I can click this button here and I can do a full page submit and see what this is going to look like when I actually submit It happens to be using a textile parser here. So I can post this, you know, as a new post at the top. I can choose to edit this, which brings it back down to the bottom of the screen there back into that form. I can click the middle mouse button. I can do an update.

And I can then delete it. Notice it's pretty boring, right? If you were just starting out and writing the simplest possible blog you can make in WebObjects, this is what you would make. So let's start to take a look at, you know, how could we make this cooler? If I can stop clicking the middle mouse button.

So I'll open my Eclipse here. So this is the actual, you know, inline binding syntax version of this. You can see it's very simple. So if I switch back here, so the first thing I want to do is, of course, and I have these notes here, so I'm not going to copy and past into it, but I am following some notes, so I'm not completely cheating. So the first thing that I'm going to want to do is Larry has got to go. So we want WObocop.

And of course, we need to change this to, if I can spell it right, so go ahead and save that, refresh, automatically much cooler. All right, so some of the first things that we're going to want to do. For most of these operations, we're going to want to take, you know, the center area, and essentially be able to AJAX refresh this.

You know, when you add a new post, when you delete a post, you want to consider reloading this section of the page. So the first thing I'm going to do is I'm going to convert this div, which is the outer div, into an AJAXUpdateContainer. So I'm going to go ahead and refactor this.

So this is some of the refactoring tools in the new component editor inside of WOLips. So it actually changed both tags at the same time. So when I save this, you'll see nothing changed, right? All I did was say I just want this area to be AJAX updatable. I didn't actually structurally change the page at all.

And all it does is sort of provide some hooks into the framework to be able to do other things later. So what are some of the other things I'm going to want to be able to do? Inplace editing of posts would be a pretty cool one. Right now, I click edit and it goes down to this form, which is kind of boring.

So let's go ahead and we'll convert this list item over to an AJAX inplace editor, which I showed you a little example of before. So I'll do a little code completion there. I want to save this element name as li. Then the way AJAX in place works is we give it a view container and an edit container, or sorry, a view component and edit component. In this case, the view component pretty much is already here. It's what we already defined. So I want to go ahead and wrap this in an AJAX in place view template and go ahead and make that inline bindings. I then want to add a new AJAXInPlaceEditTemplate.

And in this case, actually I'm going to reuse this part of this form at the bottom. So I can say this happens to be called EditBlogPost. And in this case, there's a binding called repetitionBlogPost that I can actually bind this thing into. So in this case, or, you know, in this case, if I didn't know what the bindings were available, I could do a completion and this will actually show me what bindings are available in my component.

I can do a completion there. This is actually doing a completion against the Java code inside the wad template here, or sorry, the inline template. So I have now essentially defined my view and edit component. Some of the things that I need to do for AJAXInPlace, I need to tell it, you know, what actions need to be called when you actually click the save button? By default, it will automatically generate a save and cancel button or a save button on the cancel link for you. So in this case, I'm going to say save action, I'm going to make this do an update blog post.

The other thing is by default, the way this works is when you click anywhere in the div, it goes into edit mode. For a lot of things like just having a piece of text, you click, it turns into a text area, that's fine. But in our case, we actually, if you remember over here, we had these edit and delete links. So I don't want to make it so when the whole thing is clicked to edit. So I'm going to basically tell this thing that I want manual view control, if I can type true.

So one of the things that you can notice is that in line bindings is pretty handy for things like WO string. But we already have like five or six bindings on here. It's starting to get a little bit obnoxious. So we can refactor that down into the wad file.

So one of the other things is the edit link right now is a WO hyperlink. So this is a full page reload and puts that stuff down at the bottom. Instead, we want to change this over to be an AJAX function link. So because we have an AJAXInPlace, it already provides some hooks to do things like switching to edit mode, switching to view mode, saving, things like that, that you can actually call from JavaScript. But, you know, we don't really want to write JavaScript for most of the things, so we provide some hooks. So you can do, instead, an AJAXFfunctionLink.

In this case, we're going to call the built-in function edit. Note that this is not a binding to a component action. This is a binding to a JavaScript function that sort of edit is a magical one that it knows how to wire up properly. So now when we click the edit link, it will switch us into the edit mode of the AJAXInPlace.

Delete, we want to be an AJAXUpdateLink. We don't want to essentially say when you click this, call the delete blog post action just like this hyperlink does. But instead, we want to go and just refresh the whole blog contents area because, you know, the post is now gone, just reload the whole thing. So I'll click the wrong thing.

So in this case, we want to refactor this to be AJAX update link. And so we call the same delete blog post action. But in this case, I want to do an updateContainerID. And if you remember, the div up here, blogContent, I actually want to refresh the whole area. So this is essentially now our, of course, yeah, I changed the structure of the component, so if I were to reload that page, because I injected a whole bunch of components in the middle that that link didn't match up to.

I can now click edit and go to InPlace editing on this. I can make a change, and it does InPlace saving. And deleting does, if you notice, it's much, much faster. We don't do a full page reload. All it's doing is now just doing a refresh of that one section. So there's that.

Now, it would be kind of cool to be able to add on some of those fancy scriptaculous effects that you see all over the place. There are a bunch of hooks into the framework to be able to do some of the common operations like, for instance, in this case, we want to do sort of blind up blind down effect when you go into in and out of edit mode for one of those things.

So if I go to the AJAX InPlace here, I essentially want to say when you go into edit mode, the effect that I want is effect out blind. These actually hook into scriptaculous effects. So that's course, but if you know scriptaculous, this actually corresponds to the effect that blinds scriptaculous pair, event pair, or sorry, effect pair. When you save, I want it to go ahead and do the same thing.

When you cancel, again, I just want to do the same thing, except I want that to be cancelInsertion. Just from having put the thing together before, by default, the speeds are kind of obnoxiously slow. So let's go ahead and override the duration to be 0.2. And again, for saving and canceling, so this is 0.2 seconds to do one of these transitions.

So now, when I reload this page, let's go ahead and add new post and get a little bit more so you can see the effect more. So now when I go into edit mode, this now does some scriptaculous effects for me. So notice so far, I have not done any JavaScripts. I may be cheating a little bit. That's actually technically some JavaScript binding.

Although this actually is slightly magical because it knows if you give Effect.blind is the pair of events up until into blind up blind down. If you did just blind up, it would only do a partial effect. It would affect them on one way and not on the other. So it actually is doing a little bit of processing here.

So there's that. And again, this demo is going to be just effects crazy. You'll never want to build an app like this, but, you know, if you want to show off to all your friends how many effects you can put on one page, this will be the demo for them.

So one of the other things is right now, I hit delete, and, you know, if I'm trying to show off doing fancy effects, that's just not going to cut it. That's lame. So we want to go to our AJAXUpdateLink. And we want to tell it, first of all, again, it's starting to get kind of a lot of bindings here. Let's refactor that down into the wad.

And I want to say that the effect, the before effect is blind up, and the duration, again, 0.2. And in this case, it's going to delete after the thing is gone. So I don't need the end transition. So all I need is the effect before the action. So now, when I reload this page, I add a new one in here, delete binds up, and it's just gone.

Because what happened was it did a-- before the operation, it did a blind up. It then called my background, asynchronously called my delete action, which is literally just a normal component action in my component, and then did a refresh of the blog post. But because of the way this thing is all set up, it just blinds up and goes away.

One of the other things is you notice right now, you can't really see that it's doing anything. This effect may not be very visible because we're on a local machine versus over the Internet. But it would be cool if I could basically give a busy indicator to people any time an AJAX event occurs. So I'll use the BusyIndicator.

So what I actually have here is any time a particular div performs an operation, or, you know, has an update performed on it, I can essentially say go into sort of a busy state. And so in this case, it applies a busy style and takes it back off when it's done. So I don't know if you'll be able to see this, but yeah, there's a little bit of a flash. If you look up here next to anything that actually updates, you'll see a little flash there.

So over the Internet, obviously you can have operations that might take a second and a half or something. That would be much more noticeable. And you wouldn't want your user to sit there wondering, you know, what is this doing. So you can basically just drop that in and get a busy indicator automatically.

So now one of the things that's also not particularly cool is that I typed down here, and I had to press this button, you know, I'm way too lazy to press a button. That's just not going to fly. So let's convert our blog post form over, sorry, our preview into an automatic updating container.

So in this case, I no longer need this preview button. That's out of there. I can now-- this is one part that's slightly contrived. You wouldn't normally write this like this, but because I have-- I wanted to just keep it simple for the-- and not have to do multiple components.

I have this edit blog post. I'm going to pass in the ID of the text area that I want it to use so I can watch that. So in this case, it is new, I didn't make an API file, so now I have to type, so I want this to be, I forget what I called the thing, never mind, I was just wrong, I do have an API file for that.

I want it to be called newBlogPostContents. So that's actually the ID of this thing. Because I need to be able to hook up to that on the HTML side and watch it. So now I want to convert this blog post preview, just like we've done before. This thing needs to be AJAXUpdateContainer.

And I want this to observe a field. In this case, I want it to observe the newBlogPostContents field. I want it to observe it at a certain frequency of one second. In real life, you'll never do this because one second is really fast over the web. But notice, I'm not touching this at all, this is all the same bindings that we're used to, but I just wrapped it in an update container.

So now when I type, so there you go. Automatically refreshing. I can post, except I-- oh, cool, my model doesn't make title required. So that's that. New post form. It would actually be kind of cool that, you know, why do I have to see this all the time? It would be really nice if this was sort of collapsed when I don't need it and I can expand it when I want it back. So I'm going to go and convert this thing over to an AJAXInPlace like we did up in the edit form. So what I want to do is I'm going to turn this thing into, let's see, this will be an AJAXInPlace.

In this case, before we had already essentially defined the view template. In this case, we've defined the edit template. So I'm going to go ahead and just wrap this whole thing into an AJAXInPlaceEditTemplate. Oh, actually I forgot to check inline bindings, which is not a big deal, so it just picked Component as a name, which I don't really like, so I'll refactor this to be NewPostFormInPlace. You can actually see a change in both places there.

So I've now essentially given it the edit template. So now I need to define the view template for this. So what do I want it to say when it's just in view mode? So in this case, I'll go ahead and just make it an AJAXFunctionLink. Action equals edit, in this case. I want it to go into edit mode when I click this link.

And I'll tell this guy to, oh, manual view control, this guy here, manualViewControl, because I am essentially defining my link. In this case, actually it's the only thing in there, so you wouldn't necessarily have to do that, but, you know, my script says I'm going to do that, so it's what I'll do. So one of the other things is AJAXInPlace automatically wraps your edit component in a form, so you don't actually need that part anymore. It also automatically gives you, by default, your submit and your cancel, although you can also override those if you want.

Then I have to tell it, you know, what is the action that gets called when you save? And what does happen when you cancel? So in this case, the save action is at BlogPost. And because in this case, normally when you click the save button, it refreshes the InPlace, the AJAXInPlace.

In this case, because I'm adding a new blog post, I want it to refresh that whole blog section because I'm putting something new up here. So I can actually tell this thing saveUpdateContainerID. So this says on save update this particular container, and we're going to do blog content, which is that one at the very top.

I removed the form, yep, so let's see if I've actually got everything right. So this is now an AJAXInPlace. When I save, that thing goes-- it collapses back down and the new post appears up here. But, again, I'm trying to show off, you know, how many effects we can put on a page. And there are definitely more effects we can put on this page.

So one of the things is if you notice when I posted this, all it did was basically just pop up at the top. It doesn't really give me a very good indication that it did anything. In fact, if you were looking down at the bottom, you might miss that that occurred up there. So here's we're going to use something called AJAX highlight.

And this lets you, if you've used any of the AJAX apps on the web, there's that really common idiom of yellow flashing, something that's changed. That's really easy to do in AJAX framework, except it really hooks in at an object level because what you really want to do is you want to sort of just register with the system that I want to highlight this object when you get to it.

So in this case, this is the only Java parts that we're going to write here. These two methods are essentially-- this is called by the super class, when I click the update, when I save an update, this is called a super class when I click save to add a new one. So on the update case, I'm going to call AJAXHighlight, and I want to highlight for update this blog post. So essentially what this does is it registers with the highlighting system this BlogPost. In this case, BlogPost is an EO.

So I'm registering that this EO should be highlighted on the next refresh. Down here, I want to instead do a highlightNew of this BlogPost. You can actually just use highlight if you want, but it's kind of common that sometimes you want to do a different effect, whether it's new or updated.

So that's it for Java, and we're going to come back here. And so now we essentially, in our template, we need to tell it, well, where on this page do we want to do a highlight? Because it's actually possible you could have the same object in multiple places.

So in this case, we want to highlight our ViewBlogPost. So if I command 6 this, I can wrap this in an AJAX highlight. And you'll notice it looked at the required bindings for this component, and so it filled in. I need to set a value. So in this case, my value here is-- I'm going through the repetition of BlogPost. So the value is repetition BlogPost. So essentially what this says is, and I don't like that, so what this says is basically when you get to-- when the repetition blog post matches an object that I've registered as needing a highlight, I want it to highlight.

So if I reload this page, go into new post, actually, let's delete something so we can actually see it, so you see the yellow flash when that happened. Well, that's not as flashy as an effect as I might want to show here. So there's actually, again, the same kind of hooks you can do. So in this case, I want to say-- I want to make it so when you add a new one that it actually kind of blinds down, that it sort of appears down from the top. So in this case, neweffect, BlindDown.

I want it to start hidden. I'm going to refresh that area, but I don't want it to appear and then blind down. I want it to disappear at first and then sort of slide down from invisible. And I'm not doing a non findings, so I don't need that. And, again, duration of .2.

So same deal, reel up the page, so now I can delete and they sort of roll up, make a new one, slide down. It's kind of cool. Lastly, I want to make it so this new blog post is definitely something that could have an effect put on it because everything on this page must have an effect put on it.

So it would actually be kind of cool if this little thing was where the new post is attached to the bottom of our page and just kind of slid up like a little console. So what I'm going to do is go back to the BlogPostForm, which definitely needs that done to it because that's not going to fly, and rename that. That will do.

So I've actually defined a CSS class here called, of course, floaty. This makes it sort of stick to the bottom. All that is is a position fixed. Then I'm going to say, in this case, this is actually might be a little backwards from what you might think. I want to say when you cancel a blind up, and when you edit blind down, but if you remember, it's stuck to the bottom. So it's going to animate from the bottom.

So what sort of seems like it would be the backwards effect turns out to be, actually, what we want, in this case, and the usual durations. I can't remember which one I want. That one. So now that thing is stuck to the bottom of our page. We click it and it slides up. But actually, you can kind of see on the bottom here, that little thing pop in the busy symbol.

It grows from the bottom there, kind of cool, refreshing, got our textile in there, save it, it pops down, and the one animate, you know, it slides in from the top. So do that again. So you watch this, the bottom will slide down and it will slide down from the top. And that's that.

We've now taken-- we've gone from, you know, a very boring WO app to really, and I think it turned out to be something like 25 lines have c%hanged, a really, really overblown effects demo of a blog. And so, you know, this is, again, kind of a contrived example, but it's just sort of to show you how easy it is to wrap these things into, you know, wrap your WO components with these things.

We have tons of hooks in here for doing all kinds of effects, all kinds of things like, again, like Google maps, highlightings, sliders, any number of things. And these actually were built as part of production applications. So we've tested these things on Safari, on Internet Explorer, on Firefox, on Opera. We've run it on a Wii, which is kind of cool.

And, you know, all of these things just kind of work. And one of the things that is particularly notable is that entire demo was not a single line JavaScript was written. And that wasn't like cheating. There's literally no JavaScript in that HTML template anywhere. And this certainly varies as to, you know, how complicated the types of interactions you want will be. You know, as you do more complicated things, you may need to drop down a new JavaScript.

And we actually have all kinds of really cool hooks to essentially be able to intermingle JavaScript and component action. So, you know, you can actually make an AJAX update link that turns into a JavaScript function for you so that you can call update areas of your page the refresh components from JavaScript integrated really nicely together. So if you can flip back to slides, please.

( Applause )

I ended up changing that.

That's actually off by like two lines. But, you know, so if you go ahead and watch the DVD next year and you go he lied, that's what's going on. So how do you get started? It's pretty easy. You download and install the frameworks, you add them to your project, and you integrate the framework with your applications.

Download and installing. It's part of Project Wonder. So my company, mDimension, actually hosts the Project Wonder build server, nightly build server. Go to webobjects.mdimension.com/wonder, download the latest version. We work pretty hard to keep the latest versions of that framework actually in a very stable state. Install the ones that goes into your library frameworks, just like you would any framework. Adding it to your project.

There are three frameworks that are actually very important here. ERJars, which is sort of the base set of jar files that Project Wonder uses. ERExtensions, which in the past has been a highly controversial framework, that does tons and tons of cool things in Project Wonder. Historically, people have been nervous about including this framework in their project because it basically injects code into your app. Most people don't like this.

It injects code into your app that's really, really cool. But last year, Anjo (phonetic) did a whole bunch of work on this to make it so that just blinking to the framework does not bring in anything that you don't intend. So essentially, linking to the framework now is just linking to any other framework. It's purely utilities. It's not going to patch in stuff that you're not anticipating. And lastly, Ajax.framework, of course, you will need.

Integrating. There are three basic ways to integrate. One way is we've actually refactored out the parts of the ERX application of the ERX section, the sort of the base classes of Wonder. And the ERXAjaxApplication and ERXAjaxSession. The notable parts of these is that this is just AJAX stuff. So again, to try to make this easy for people to integrate in their apps, this doesn't bring in any other Wonder stuff, you don't have to worry about, you know, other things hooking into your app.

This is just the AJAX portion. So essentially, if you just change your app superclass to AJAX app and change your session superclass to AJAX, the ERX AJAX session, you are now able to use AJAX framework. Better yet, just use Wonder. It's awesome, it's one of the largest open source frameworks out there, tons and tons of cool things that will solve problems that you have and fix deadlocks that you have and don't know it yet.

And lastly, just like a merger with here, this is actually not a lot of code in there. A couple hundred lines, maybe. If you really don't have the, you know, flexibility in your projects to change base class hierarchy, just copy and past it into yours. A notable point here is WO 5.4 includes essentially what is ERXAjaxApplication to ERXAjaxSession. So if you're using WO 5.4, those parts will be built in for you.

One of the-- there's not a version of Wonder released just yet that is WO 5.4 compatible, but Anjo has been working feverishly through the night. So I suspect by maybe tomorrow, there will be, maybe the end of the week. So we are working on that, though. There will be a version that will come out very, very soon, that will essentially let you experiment with all these things with 5.4 and run your apps on 5.4. So expect that to come soon.

And, of course, profit because all of your customers will just go crazy when you have sliding blog posts. Now, download Wonder, try it. Like I showed before, the AJAX example application is in Project Wonder. It shows off pretty much every component that we have. If there's something in there that's missing, get on the Wonder discussion mailing list post, let us know, we'll add it in.

There is several people actually using this application, many actually in production environments, who can definitely help answer questions and contribute. We're an open source, we're all volunteer. We would love to have people come in and fix bugs, contribute new components. I've had a couple people actually come up to me at WWDC and say, you know, hey, I've been using the framework, I have a cool new component, how do I submit it back? Get on the mailing list and, you know, submit a patch in.

We love patches. We love not having to do work ourselves. That's great. I'll bring Pierre back up. So for more information in general on WO 5.4 stuff, talk to these guys. For information on AJAX framework or Project Wonder or WOLips, you know, talk to us. Thank you. AJAX framework.

( Applause )

Okay, so if you need anything more, I'm here. You all have my e-mail address. It's easy. Matt I don't think is here in this room today. If you need anything with the evangelism, try Matt. Wrong thing. Coming up, I would really insist on the first one because that was not in your program. We have reintroduced the Birds of a Feather. Bring your cool app, show them to your fellow developers tonight. We have got a special room for you so that you can actually share your apps. So please come.

Obviously, you need to come to the rest too. In summary, WebObjects has a maturity that's got a staying power. We have been there 10 years. We are going to be there. The WO 5.4 has got more improvement, more changes than quite a few of the release before. So have a look at it. It's a very significant release. And you can build Web 2.0 with WebObjects today using Wonder. And really, it's really about the framework.