Table of Contents Previous Section

pageWithName: and Page Caching

When the application object receives a pageWithName: message, it creates a new component. For example, in the HelloWorld example a user enters a name in the first page (the Main component), clicks Submit, and is presented with a personal greeting on the second page (the Hello component). Clicking the Submit button in the first page invokes the sayHello method in the Main component. As part of its implementation sayHello sends a pageWithName: message to the application object:

id visitorName;

- sayHello {
    id nextPage;
    
    // Create the next page.
    nextPage = [[self application] pageWithName:@"Hello"];  
    
    // Set state in the Hello page
    [nextPage setVisitorName:visitorName];
    
    // Return the 'Hello' page.
    return nextPage;
}

Each time the sayHello method is invoked, a new Hello component is created. For example, if the user backtracks to the main page and clicks the Submit button again, another Hello page is created. It's unlikely this duplication of components will be a problem for the HelloWorld application, since users quickly tire of its charms. But, depending on design, some applications may benefit by modifying the operation of pageWithName: so that an existing component can be reused.

If you want to extend WebObjects' page caching mechanism to include pages returned by pageWithName:, you must implement your own solution. Fortunately, it's easy. One approach is to have the session maintain a dictionary that maps page names to page objects. Here's the code you would add to an application's Session.wos file:

id pageDictionary;

- init {
    [super init];
    pageDictionary = [NSMutableDictionary dictionary];
    return self;

}

- pageWithName:aName {
    id aPage = [pageDictionary objectForKey:aName];
      
    if (!aPage) {
        aPage = [[self application] pageWithName:aName];
        [pageDictionary setObject:aPage forKey:aName];
    }
    return aPage; 
}

Note that we implement pageWithName: in the session object since we want to cache these pages on a per-session basis. (Overriding the method in the application object would cache pages on a per-application basis.) Since the pageWithName: method that we want to use now resides in the session object, one line in the sayHello method has to change (change in bold):

- sayHello {
    id nextPage;
    nextPage = [[self session] pageWithName:@"Hello"];  
    [nextPage setVisitorName:visitorName];
    return nextPage;
}

Table of Contents Next Section