WOComponent objects dynamically render web pages (or sections of pages) at run time. They provide custom navigation and other logic for the page, provide a framework for organizing constituent objects (static and dynamic HTML elements and subcomponents), and enable the attribute bindings of dynamic elements.
Through New Component commands in Project Builder and WebObjects Builder
alloc/init
initWithCoder: (for unarchiving)
performParentAction: | Invokes a parent component's action method. |
awake | Allows custom component initializations during the start of a request-response cycle. |
takeValuesFromRequest:inContext: invokeActionForRequest:inContext: appendToResponse:inContext: |
These three methods allow custom component logic during the value-extraction, action-invocation, and HTML-generation phases of the request-response loop. |
setCachingEnabled: | Controls whether the component definition of the receiver is cached. |
Objects of the WOComponent class represent web pages (or sections of pages) that are dynamically rendered at runtime. A WOComponent object specifies the overall behavior of a WebObjects page, including navigation logic and database access. It also provides a framework for organizing the HTML elements of a page as objects and for binding the attributes of the page's dynamic elements to properties of the component.
Note: The term component has a range of meanings, not surprising since what it refers to exists on several levels. Sometimes "component" can refer to a WOComponent object, sometimes to the component directory, and sometimes to the rendered web page. For the purposes of this specification, "component" means WOComponent object, unless otherwise indicated.
A component is represented in the file system by a directory with a .wo extension. It contains files supplying three kinds of information:
Each WOComponent subclass has the same name as its component directory. By convention, the name of the component representing the first page of an application is Main. The names of the HTML, declaration, and implementation files in the component directory should match (minus their extensions) the name of the component directory (for example, Main.html). If there is a component script (a .wos file), the code it contains is made the implementation behavior of a special subclass of WOComponent created at runtime.
Note: For more on the organization and contents of component directories, see the first chapter of the WebObjects Developer's Guide.
The WOComponent class has many methods that have the same names as methods of the WOApplication class. However, the scope of the WOComponent methods is limited to a component rather than being application-wide. For example, you can control component-definition caching on a per-component basis using setCachingEnabled:, which has a WOApplication counterpart. When this kind of caching is enabled for a component, the application parses the contents of the component directory the first time the component is requested, creates the component definition, stores this object in memory, and restores it for subsequent requests.
The WOComponent class also has the localization method stringForKey:InTableNamed:withDefaultValue:. The difference is that the WOComponent method confines its search for the .strings file to the component directory. As with WOApplication's method, it searches the localized (.lproj) subdirectory in the order of language preference. For more on caching and localization, see the class description of the WOApplication class.
WOComponent objects also respond to awake, sleep, and the three request-handling messages: takeValuesFromRequest:inContext:, invokeActionForRequest:inContext:, and appendToResponse:inContext:. You can override these methods in your compiled subclasses, and thereby integrate your custom behavior into the request-response loop. (You can also override these methods in component scripts using WebScript.)
By implementing the
NSCoding protocol
(encodeWithCoder: and initWithCoder: methods), WOComponent objects can serialize their state in an object archive.
This capability makes WOComponent objects persistent across sessions when they and their "owning" session (which initiates the archiving) are stored in the page or in cookies. These methods are automatically implemented for scripted components.
A WOComponent object can represent a dynamic fragment of a Web page as well as an entire page. Such subcomponents, or reusable components, are nested within a parent component representing the page or another subcomponent. The capability for assembling components in a hierarchical structure to constitute a page is a key advantage of WebObjects. With frameworks of reusable components, developers can quickly build complex pages and can reuse components as building blocks in multiple development projects.
Each component keeps track of its subcomponents. When a component receives a request-handling message, such as takeValuesFromRequest:inContext:, it forwards that message to its subcomponents. But how does a child component communicate with its parent? It is frequently important that child and parent components have some way to synchronize their states. For instance, if a subcomponent presents a palette of options (such as colors), it must have some way to communicate a selection to the parent component so that the parent can update its display with the new option.
The WOComponent class provides a child-parent callback mechanism for this purpose.
In the parent's declaration file, you bind an arbitrary attribute of the
child to an action method of the parent. Then, as the last step in the child's
action method, you invoke performParentAction: with the argument being
the arbitrary attribute, returning the object received back as the response
page. See the method description for performParentAction: for details.
A component renders itself in HTML through a graph of objects representing its static and dynamic elements and its subcomponents. This graph of objects is called a dynamic template. Each object in the template contributes, in its turn, to the generation of HTML during the appendToResponse:inContext: phase of the request-response loop. (During the other two phases, the appropriate dynamic elements in the template extract page values and invoke actions.)
At runtime, when a component is requested, the application constructs a dynamic template from two sources in the component directory: the static HTML template (the .html file) and the declaration (.wod) file. The HTML file represents the static part of the component template and the declarations file captures the dynamic part. The declaration file indicates the class of each dynamic element and can specify initial attribute values and bindings between element attributes and properties of the component. The application parses these two files and integrates them where there are "<WEBOBJECT></WEBOBJECT>" markers in the HTML file, inserting the dynamic-element objects within the template's HTML syntactic tree.
The binding between the attributes of dynamic elements and the properties of a component is two-way. When it's their turn to extract values, invoke an action, or append their content, dynamic elements can "push" and "pull" values to and from the bound instance variables or methods of the component. This associative behavior always occurs with reference to the current component (page or subcomponent), which is maintained on a stack.
A component instance itself does not contain its dynamic template as instance
data. WOComponents are by definition reusable and instances are often re-created
within the same session or across sessions. It therefore makes sense to keep
the template in a central location where it is accessible by all instances
of a component. When the application parses the contents of a component
directory, it creates a component definition, a compact description
of a component that includes path and URL information as well as the component's
template. The application instantiates WOComponent objects from their component
definitions and (if isCachingEnabled returns YES) stores component
definitions in memory for future requests.
Programmatically creates the component's template using anHTMLString as the HTML template contents and aDeclarationString as the declarations file contents. Returns (as a WOElement object) the graph of static and dynamic elements build by parsing the HTML and declaration strings. You can then use the returned WOElement as the component's template.
See Also: - templateWithName:
Component objects associated with a response receive this message during the last phase of the request-response loop. In the append-to-response phase, the application objects (particularly the response page instance itself) generate the HTML content of the page. WOComponent's default implementation of this method forwards the message to the root WOElement object of the component template. Compiled or scripted subclasses of WOComponent can override this method to replace or supplement the default behavior with custom logic.
See Also: - invokeActionForRequest:inContext:, - takeValuesFromRequest:inContext:
Returns the WOApplication object for the current application.
See Also: WOApplication class, - context, - session
Invoked at the beginning of a WOComponent's involvement in a cycle of the request-response loop, giving the WOComponent an opportunity to initialize its instance variables or perform setup operations. The default implementation does nothing.
See Also: - init, - sleep
Returns the component URL relative to the server's document root, for example: "/WebObjects/MyApp.woa/Resources/Main.wo"
See Also: - name, - path
Returns the WOContext object for the current transaction.
See Also: WOContext class, - application, - session
Records information about the component if it is the response component in the current request-response loop transaction. The default implementation records the component's name. You might override this method if you want to record more information about the component. For example, you might want to record the values of some instance variables as well as the component name.
This message is sent only to the top-level response component, that is, the one representing the entire page. Components nested inside of that top-level component do not receive this message.
If a CLFF log file is kept for this application, the string returned by this method is recorded in that log file. Thus, you must ensure that the string you return can be analyzed by a CLFF-analysis tool.
See Also: WOStatisticsStore class
If the component is stored in a framework, this method returns the name of that framework. For example, if the component is in the framework NeXT_ROOT/NextLibrary/Frameworks/WOExtensions.framework, then this method returns the string "WOExtensions".
If the component is not stored in a framework, this method returns nil.
See Also: WOResourceManager class
Initializes a WOComponent object. If a WebObjects Builder archive file exists in the component directory, it initializes component variables from this archive. An exception is thrown if the method cannot determine the name of the component or if it cannot initialize the object for any other reason. Override init in compiled subclasses to perform custom initializations; as always, invoke super's init method as the first thing.
See Also: - awake
WOComponent objects associated with a request page receive this message during the middle phase of request handling. In this middle phase, the invokeActionForRequest:inContext: message is propagated through the WOElement objects of the page; the dynamic element on which the user has acted (by, for example, clicking a button) responds by triggering the method in the request component that is bound to the action. WOComponent's default implementation of this method forwards the message to the root WOElement object of the component template. Compiled or scripted subclasses of WOComponent can override this method to replace or supplement the default behavior with custom logic.
See Also: - appendToResponse:inContext:, - takeValuesFromRequest:inContext:
Returns whether component-definition caching is enabled for this component. NO is the default.
See Also: - setCachingEnabled:
Prints a message to the standard error device (stderr). The message can include formatted variable data using printf-style conversion specifiers, for example:
id i = 500; id f = 2.045; [self logWithFormat:@"Amount = %@, Rate = %@, Total = %@", i, f, i*f];
Note that in WebScript, all variables are objects, so the only conversion specifier allowed is %@ as shown above. In compiled Objective-C code, all printf conversion specifiers are allowed. The equivalent method in Java is logString.
Prints a message to the standard error device (stderr). This method is used by logWithFormat:.
Returns the name of the component minus the ".wo" extension; for example "Main" is a typical component name.
See Also: - baseURL, - path
Returns the file-system path of the component, which is an absolute path and includes the ".wo" extension; for example "C:\Next\NextLibrary\WOApps\MyApp.woa\Resources\Main.wo" is a typical component path.
See Also: - baseURL, - name
Returns the absolute path to the component resource having the name of aName and an extension of aType. The method searches all localized ".lproj" directories of the component before searching directly under the ".wo" component directory for a non-localized resource of the given name and extension.
This method is provided for backwards compatibility only. For WebObjects 3.5 and above, you should use the WOResourceManager API to retrieve resources. WOResourceManager is not able to retrieve resources stored inside component directories.
See Also: - stringForKey:InTableNamed:withDefaultValue:
Allows a subcomponent to invoke an action method of its parent component bound to the child component (attribute). Parent and child components are "synchronized" when this method returns: the variables that are bound by a declaration of the child component in the parent component's declaration file have the same value.
An example best illustrates this mechanism. Let's say you have a Palette subcomponent, and this WOComponent is nested in a parent component with a "displaySelection" action method. When the user selects an item in the palette (perhaps a color), you want to invoke "displaySelection" to show the result of the new selection (perhaps a car in the new color). The declaration in the parent's ".wod" file would look like this:
PALETTE: Palette { selection = number; callBack = "displaySelection"; };
The "callBack" item is an arbitrary attribute of the child component bound in this declaration to the parent component's "displaySelection" method. The performParentAction: method is used to activate this binding. Let's assume the child component has an action method called "click"; the implementation would look like this:
- click { /* this is the child's action */ selection = /* some value */; /* now invoke the parent's action */ return [self performParentAction:callBack]; }
Returns the current WOSession object.
See Also: WOSession class, - application, - context
Enables or disables the caching of component definitions for the receiving component. WOComponent definitions contain templates and other common information related to components, and are used to generate instances of those components. When this attribute is set to YES, the application parses the HTML template and the declaration (".wod") file of a component once and then stores the resulting component definition for future requests. By default, this kind of caching is disabled so that you can edit a scripted component without having to relaunch the application every time to check the results. (Note that this does not apply to Java subclasses of WOComponent; in this case, you still have to kill and relaunch the application.)
With WOApplication's method of the same name, you can turn component-definition caching off globally. You can then control caching of individual component definitions using WOComponent's version of this method. Selective caching is an especially valuable technique for very large applications where only the most frequently requested components should be cached.
See Also: - isCachingEnabled
Invoked at the conclusion of a request-handling cycle to give component the opportunity for deallocating objects created and initialized in its awake method. The default implementation does nothing.
Returns from within the component directory a localized string from string table "aTable.strings" using aKey to look it up. If no string value for the key is found in the table, defaultValue (optional) is returned. The method first searches the "aTable.strings" file, if it exists, in each localized (".lproj") subdirectories of the component; searching proceeds in the order of the language list maintained by the WOSession object (for details, see the setLanguages: method of the WOSession class). If no string value matching the key is found, the search then continues for a non-localized or default version of the string in the "aTable.strings" file (if it exists) directly under the component directory. If after this no string matching the key is found and no default value is specified, the method returns nil.
See "Localization" in the WOApplication class description for further details.
WOComponent objects associated with a request receive this message during the first phase of the request-response loop. The default WOComponent behavior is to resend the message to the root object of the component's template. In this phase, each dynamic element in the template extracts any entered data or changed state (such as a check in a check box) associated with an attribute and assigns the value to the component variable bound to the attribute. Compiled or scripted subclasses of Component can override this method to replace or supplement the default behavior with custom logic.
See Also: - appendToResponse:inContext:, - invokeActionForRequest:inContext:
Returns the root object of the graph of static and dynamic HTML elements and subcomponents that is used to graphically render the component identified by aName. This template is constructed from the ".html" and ".wod" file found in the component directory. You identify the template by specifying the component directory, which consists of the component name plus the "wo" extension: for example, "HelloWorld.wo." If the template is not cached, the application will parse the HTML and declaration files of the specified component to create the template. If the flag returned by WOApplication's printsHTMLParserDiagnostics is YES, the application sends HTML diagnostic messages to the standard output device.
See Also: - setPrintsHTMLParserDiagnostics: (WOApplication)
Returns the URL of the resource in the component directory that has a name of aName and an extension of anExtension. The method searches all localized component subdirectories (".lproj") in the preferred language order before searching directly under the component directory (".wo") for the resource. The preferred language order is returned by WOSession's languages method.
This method is provided for backwards compatibility only. For WebObjects 3.5 and above, you should use the WOResourceManager API to retrieve resources. WOResourceManager is not able to retrieve resources stored inside component directories.
See Also: - stringForKey:InTableNamed:withDefaultValue: