PATH |
WebObjects eases the development of dynamic Web-based applications that build HTML pages at run-time. However, there are times you need to generate static Web sites from dynamic WebObjects applications. For example, a publishing company may want to distribute its Web site that features magazines on CDs to its readers. In this case, the company will be looking for a solution that not only allows Internet users to surf the site dynamically, but also put the site onto a CD so that other users can surf it statically.
This example called "Dynamic Publishing" illustrates how to generate a static site from a WebObjects application.
When writing a WebObjects application that supports static page generation, you must pay attention to those dynamic elements that link to another page (for example, WOHyperlink, WOActiveImage). These elements should refer to the URL of a HTML file in the static site.
In its simplest form, you can use the href attributes in WOHyperlink and WOActiveImage to define the location of the HTML file. However, this means that these elements will only behave correctly when surfed statically. To use the same element, the same component, and, hence, the same WebObjects application to work in both dynamically and statically, you must build a dynamic element that changes its identity according to whether the application is static or dynamic. One way to achieve this is to use WOSwitchComponent.
SwitchLink: WOSwitchComponent { _componentName = linkComponent; labelValue = theLabelValue; currentDoc = theCurrentDocument; }
id theLabelValue, theCurrentDocument; - linkComponent { if ([[self application] isStaticSite]) return @"StaticLink"; else return @"DynamicLink"; }
Both StaticLink and DynamicLink are WOHyperlinks. StaticLink has a href attribute that specifies a static URL and DynamicLink has an action that returns a WebObjects response.
AStaticLink: WOHyperlink { string = labelValue; href = documentStaticPage; disabled = isDisable; };
When generating a static site, it is important to determine
in order to specify the correct URL for your images and links. The following are some suggestions of how to handle these two issues:
/InetPub/wwwroot/StaticSite/doc0+/...HTML /InetPub/wwwroot/StaticSite/doc10+/...HTML /InetPub/wwwroot/StaticSite/3.HTML /InetPub/wwwroot/StaticSite/5.HTML /InetPub/wwwroot/StaticSite/index.HTML
StaticSite is a subdirectory under the document root containing the static site that is generated. Inside the StaticSite directory resides index.html , which is the home page for the site. Any other HTML files at that level are section home pages. A document is placed in a subdirectory according to its primary key. For example, documents with primary keys from 11 to 20 will be in the subdirectory doc10+ . This approach is simple, effective, and requires minimum maintenance.
Typically, two processes are involved in generating a static site:
The parameters that are passed to the WebObjects dynamic application are appended as form values at the end of the HTTP request. In the Dynamic Publishing example, the documentId is appended as a form value of the HTTP request so that the Dynamic Page Generator receiving the request knows which document to generate.
To fire a HTTP request from a process, you must open a socket programmatically. The simplest way to implement this is to use the Java socket class.
Class javaSocketClass = NSClassFromString(@"MyJavaSocket"); Id javaSocketObj = [javaSocketClass new]; [content setString: [javaSocketObj getContent: URLString]];
where URLString is probably something such as:
http://python/scripts/WebObjects.exe/DynamicPageGenerator.woa?type=Document&documentId=123
getContent in MyJavaSocket uses the Java URL class to fire the HTTP request:
public String getContent(String URLPath) { String contentString = null; try { URL aURL = new URL(URLPath); URLConnection aURLConnection; try { byte buffer[] = new byte[20000]; StringBuffer responseBuff = new StringBuffer(); int totalBytesRead = 0; int bytesRead = -1; int i; aURLConnection = aURL.openConnection(); InputStream aInputStream=aURLConnection.getInputStream(); bytesRead = aInputStream.read(buffer); while (bytesRead > 0) { totalBytesRead += bytesRead; for (i=0; i<bytesRead; i++) { responseBuff.append((char)buffer[i]); } bytesRead = aInputStream.read(buffer); } contentString = responseBuff.toString(); } } return contentString; }
Once the site is generated, you must think about how to handle the subsequent changes. How often do you want the changes to propagate to the static site? How do you determine which documents to regenerate when changes are made? The answers depend on the application. Consider a magazine web site, whose contents are updated once a month when a new issue is published. A simple approach, generating a new static site each month, suffices. However, for a Web site that provides 24-hour news to Internet users, the application logic that chooses the documents to regenerate becomes more complex.
Since the site generated is effectively a static site, the limitations of a manually developed static site applies to a dynamically generated static site as well. For example, there will be no support for direct interaction with the users and, hence, no support for Form elements.