Zen Application Concepts
If you are new to Caché objects and the ObjectScript programming language, the discussion in this chapter makes most sense after you have mastered the supporting material available in other books. The best starting points are the books Using Caché Objects and Using Caché ObjectScript.
Client and Server
Zen is a client/server web technology. The terms client and server are commonly used; this section explains how Zen uses these terms.
Zen and CSP
The book Using Caché Server Pages (CSP) describes the relationship between the client and server in CSP applications. It outlines the flow of events between issuing the HTTP request and displaying the page in the browser. Zen applications and Zen pages are CSP pages, so all of this information also applies to Zen.
Zen applications use CSP technologies to:
Filter and respond to HTTP requests.
Manage sessions and session lifecycle.
Manage user identity, authentication, and access control.
Provide the hyperevent mechanism used to call server methods from the client.
Call from the server to execute code securely on the client.
If you make use of the CSP session preserve mode, be aware that the server-side Zen page (%page) and application (%application) objects are not preserved between server requests.
Zen Pages at Runtime
A Zen page automatically responds to Hypertext Transfer Protocol (HTTP) requests from a browser and serves up a complete HyperText Markup Language (HTML) document to satisfy such a request. Zen pages can also satisfy other types of requests, such as for eXtensible Markup Language (XML) or Scalable Vector Graphics (SVG) content. The behavior for XML or SVG is documented in later chapters. It is similar to the HTML behavior documented in this chapter.
The following sequence displays a Zen page in a browser window:
The web browser sends an HTTP request that names a specific Zen page. The Caché server receives the request and automatically routes it to the Zen page class.
The page class invokes its %OnBeforeCreatePage() callback method. This method provides the opportunity for the application to perform any setup work that may be required before %CreatePage() begins execution.
The page class creates an instance of itself on the Caché server and invokes its class method %CreatePage(). This method creates the set of component objects and adds these objects as children of the page object.
When a Zen page class contains a description of the page in XML format within an XData Contents block, Zen automatically generates a %CreatePage() method whenever the class is compiled. The compiler uses the information in XData Contents to generate the method. This is by far the most common case. Alternatively, a programmer may omit the XData Contents block and implement %CreatePage() manually. This gives the opportunity to create dynamic page content.
However, most Zen application developers choose to set up an initial Document Object Model (DOM) for the page using XData Contents, then add finishing touches to this model in %OnAfterCreatePage().
The page class invokes its %OnAfterCreatePage() callback method. In this method, the application can modify the content generated by %CreatePage() in any way that is needed. After %OnAfterCreatePage() completes execution, there is a page object in memory that contains some number of child component objects.
The page object constructs an HTML document from its DOM by invoking the page class’s %DrawHTML() method. Every Zen page and component object has a %DrawHTML() method that knows how to render the object as HTML. In the case of a Zen page, the %DrawHTML() method supplies:
The page title.
Any HTML meta-tags needed by the page.
Any content needed to support hyperevents (the mechanism used to make in-page calls back to the server).
Default CSS style definitions defined by the component classes.
CSS style definitions defined by the application class.
CSS style definitions defined by the page class. (This order is important as it allows the application settings to override defaults and page settings to override application settings).
The HTML content of every component on the page (obtained by invoking the %DrawHTML() method for every component on the page).
As with %CreatePage(), for the most part a Zen programmer can ignore %DrawHTML(). Caché generates and invokes it automatically. The important fact about %DrawHTML() is when it occurs. %DrawHTML() is the last step before the page leaves the server.
The Zen programmer must ensure that all server-side adjustments to the page are complete before the end of the %OnAfterCreatePage() method.
The Caché server delivers the HTML document to the client.
If there is an onloadHandler() client-side method defined in the page class, it runs on the client side at this time.
The browser displays the HTML document
As described above, the Zen application development framework offers several opportunities to manipulate the Zen page prior to its initial display. The most frequently used are as follows
The XData Contents block in the Zen page class uses the syntax described in:
All chapters in the book Using Zen Components
The %OnAfterCreatePage() callback method runs on the server and so can be written in a server-side language such as Caché Basic, ObjectScript, or MVBASIC. Zen invokes %OnAfterCreatePage() after the page object is initially created; you can use statements in %OnAfterCreatePage() to add components on the page or otherwise manipulate them, all using your server-side language of choice. For technical details and a list of server-side methods you can call to work with components programmatically, see the section “Defining Page Contents Dynamically on the Server” in the “Zen Pages” chapter of Developing Zen Applications.
A Zen application consists of the following parts:
A class derived from %ZEN.application that provides application-wide behavior such as a common style sheet. The style sheet is specified as an XML block embedded within the class.
Every page contains components. Components provide “look and feel” and permit the user to interact with the page. All components are derived from %ZEN.Component.component. They include buttons, tables, list boxes, text fields, panels — essentially any item that can be displayed on a page.
This architecture works as follows:
A Zen application consists of page classes.
For convenience, a Zen application may also have an application class defined.
If there is an application class, each page identifies it.
Every Zen page consists of a page object and a set of component objects.
The set of components for a page is defined using a block of XML embedded into the page class.
The page class can also define a set of methods that provide additional behavior, such as responding to user actions. These methods can run within the browser, or on the server, depending on how the code is written.
When the client sends a page request, the page object and all of its constituent component objects are instantiated on the Caché server. This is the object tree.
This object tree can be further modified by user code on the Caché server.
Properties and methods of the object tree are thus available to the client.
As the user interacts with a page, events are fired that invoke the various methods of the client object tree. Some of these methods execute within the browser, while others can be defined to run back on the server (for database access, etc.).
Zen automatically manages any calls that a page makes back to the server, including session context, security, and synchronizing changes between the client and the server.
Users create Zen applications by assembling classes (both pre-built and user-defined) into larger functional units: components are assembled into pages, and pages are assembled into applications. The application class, if provided, supplies application-wide conventions that apply to all pages.
For programming details, see the “Zen Applications” chapter in Developing Zen Applications.
A Zen page class consists of:
A contents definition—An XML block embedded within the page class. It defines the set of components that make up the page, along with their settings. It is possible to define the contents of a page programmatically, but in most cases an XML block is more convenient.
Style overrides—An XML block embedded within the page class. It defines page-specific overrides of CSS styles for the components on this page.
Event-handling methods—A page class typically contains a number of methods that handle events associated with a page, such as when the user interacts with a component. Some of these methods may run on the server and some on the client. Later chapters provide details.
For programming details, see the “Zen Pages” chapter in Developing Zen Applications.
Zen component classes define the behavior and layout of the page. Every Zen component has the following characteristics:
Defines a set of properties and methods that determine its runtime state and behavior.
Defines how its initial HTML is drawn (if any). It is also possible to define components that only render themselves using client-side, dynamic HTML.
Defines a standard CSS style sheet that specifies how it should appear on the page. Applications can selectively override these styles without having to modify the pre-built components.
Defines settings that adjust the appearance or behavior of a component. A Zen component class formally exposes certain settings so that it is easy to dynamically modify these setting values while designing a Zen page.
New components are automatically ready for use within a page’s XML content definition.
Component classes vary in complexity from simple wrappers for native HTML controls to full-featured calendar and grid controls. Components include the following specialized types:
Controls display data and allow for user input (such as text or button controls).
Groups contain sets of other components (such as groups, tab groups, menus, and forms).
Panes display rich information (such as a tables retrieved from queries).
Other components simply display data on the page.
For further details, see the next chapter, “Zen Component Concepts.”