Changes for page Development-WO Component-Code Template and WODs
Last modified by Pascal Robert on 2012/07/19 21:09
From version 6.1
edited by Quinton Dolan
on 2007/07/12 20:08
on 2007/07/12 20:08
Change comment:
There is no comment for this version
To version 8.1
edited by smmccraw
on 2007/07/08 09:46
on 2007/07/08 09:46
Change comment:
There is no comment for this version
Summary
-
Page properties (2 modified, 0 added, 0 removed)
Details
- Page properties
-
- Author
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki. qdolan1 +XWiki.smmccraw - Content
-
... ... @@ -20,17 +20,17 @@ 20 20 21 21 To receive values from the request (for instance, form data), implement the takeValuesFromRequest method. If your WODynamicElement responds to user actions, you must implement the invokeAction method. And if your WODynamicElement generates output, you must implement the appendToResponse method. At runtime, your WODynamicElement will be wired up to a WOComponent that you can access via the WOContext that is passed into each of the three methods above, which can be used to resolve bindings in a particular appearance on a page. For example, to retrieve the value of a binding, it might look like: 22 22 23 -{{ code}}23 +{{panel}} 24 24 25 -private WOAssociation myNameAssociation; 26 -... 27 -public void appendToResponse(WOResponse _response, WOContext _context) { 28 - WOComponent component = _context.component(); 29 - String name = (String) myNameAssociation.valueInComponent(component); 30 - super.appendToResponse(_response, _context); 31 -} 25 + private WOAssociation myNameAssociation; 26 + ... 27 + public void appendToResponse(WOResponse _response, WOContext _context) { 28 + WOComponent component = _context.component(); 29 + String name = (String) myNameAssociation.valueInComponent(component); 30 + super.appendToResponse(_response, _context); 31 + } 32 32 33 -{{/ code}}33 +{{/panel}} 34 34 35 35 This same pattern is used for [[Stateless WOComponents>>Programming__WebObjects-Web Applications-Development-Stateless Components]]. WODynamicElement can provide a .api file to describe its bindings. For more information on .api files, see the .API File section below. 36 36 ... ... @@ -38,15 +38,15 @@ 38 38 39 39 WOComponents add several major capabilities above and beyond WODynamicElements. The primary additional capability is support for templating. When you create WOComponent, you can also create a ".wo" folder, which contains three files: a .html or .xml template, a .wod binding declaration, and a .woo file. Like WODynamicElements, WOComponents can also provide an optional .api file (as described below). The code for a WOComponent can be a simple as simply declaring that your class extends WOComponent along with its constructor. For example: 40 40 41 -{{ code}}41 +{{panel}} 42 42 43 -public class MyComponent extends WOComponent { 44 - public MyComponent(WOContext _context) { 45 - super(_context); 43 + public class MyComponent extends WOComponent { 44 + public MyComponent(WOContext _context) { 45 + super(_context); 46 + } 46 46 } 47 -} 48 48 49 -{{/ code}}49 +{{/panel}} 50 50 51 51 The same three core methods described above for WODynamicElements also exist for a WOComponent, however because WOComponents can be stateful, you can also declare instance variables (ivars) in your component that you can bind to. Each time your WOComponent is used on a page, a new instance is created, which is another large distinction as compared to a WODynamicElement. It is not necessary for your WOComponents to be thread-safe. 52 52 ... ... @@ -56,11 +56,11 @@ 56 56 57 57 By default, WOComponent templates can be either .html or .xml files. WebObjects templates separate all binding declarations into a separate file called a .WOD file, which is different than many other web frameworks. As a result, the templates are generally much easier to read and can often be more easily given to a designer to work on without the risk of code-related bindings being modified by accident. WOComponents are declared in the template using a "webobject tag", which looks like an HTML tag: 58 58 59 -{{ code value="xml"}}59 +{{panel}} 60 60 61 -<webobject name = "PersonName"></webobject> 61 + <webobject name = "PersonName"></webobject> 62 62 63 -{{/ code}}63 +{{/panel}} 64 64 65 65 The name declared in the WebObject tag will be used as a key to lookup the corresponding binding definition in your WOD file. 66 66 ... ... @@ -68,23 +68,23 @@ 68 68 69 69 WOD files (Web Object Declaration?) define the bindings for each of the component references in the template. For instance, if the reference above was connected to a "public String personName()" method on your component, the WOD declaration might look like: 70 70 71 -{{ code}}71 +{{panel}} 72 72 73 -PersonName : WOString { 74 - value = personName; 75 -} 73 + PersonName : WOString { 74 + value = personName; 75 + } 76 76 77 -{{/ code}}77 +{{/panel}} 78 78 79 79 There are several pieces to this declaration. The first token is the WebObject tag name which appears in the template. These values much match exactly for WebObjects to resolve the binding information. If you reference a name in your template and do not declare a corresponding WOD entry, WebObjects will throw an exception at runtime. 80 80 81 81 The second token, after the colon, is the name of the component or element to instantiate in your template. This name is resolved using NSBundle lookup rules, which by default will find any class that has the same name as the token, excluding package name. For instance, WOString might actually be "com.webobjects.appserver.//private.WOString", but the name of the class without its package name is "WOString". This is important to note, because it means that if you are using this syntax, you must uniquely name your classes across all packages (an Objective-C heritage, where the concept of a package did not exist). You can, however, choose to fully qualify your class names, in which case the "WOString" in the example above would become "com.webobjects.appserver.//private.WOString" and there would be no ambiguity in class resolution. It is possible to override the normal NSBundle lookup process by using a method on NSUtilities: 82 82 83 -{{ code}}83 +{{panel}} 84 84 85 -NSUtilities._setClassForName(com.bla.TestComponent.class, "TestComponent"); 85 + NSUtilities._setClassForName(com.bla.TestComponent.class, "TestComponent"); 86 86 87 -{{/ code}}87 +{{/panel}} 88 88 89 89 This call would bind the name "TestComponent" appearing in a WOD reference to the class com.bla.TestComponent, avoiding any further class "hunt". This is also useful to replace internal component implements with your own. For instance, you could replace the implementation of WOString with your own class ~-~- a capability that Project WOnder makes extensive use of to provide bug fixes and enhancements to the core components. 90 90 ... ... @@ -94,36 +94,36 @@ 94 94 95 95 A single WOD entry can contain several binding declarations, and a WOD file can contain many entries. For example, here is an excerpt from a real WOD file: 96 96 97 -{{ code}}97 +{{panel}} 98 98 99 -FilterAction : WOSubmitButton { 100 - action = filter; 101 - value = "filter"; 102 -} 99 + FilterAction : WOSubmitButton { 100 + action = filter; 101 + value = "filter"; 102 + } 103 + 104 + EditAction : WOHyperlink { 105 + action = editRequest; 106 + } 107 + 108 + NoRequestsConditional : WOConditional { 109 + condition = requestsDisplayGroup.allObjects.count; 110 + negate = true; 111 + } 103 103 104 -EditAction : WOHyperlink { 105 - action = editRequest; 106 -} 113 +{{/panel}} 107 107 108 -NoRequestsConditional : WOConditional { 109 - condition = requestsDisplayGroup.allObjects.count; 110 - negate = true; 111 -} 112 - 113 -{{/code}} 114 - 115 115 === WOO Files === 116 116 117 117 At a minimum, a WOO file declares the WO version and the Template's character encoding. As an example, a bare bones WOO file might like look: 118 118 119 -{{ code}}119 +{{panel}} 120 120 121 -{ 122 - "WebObjects Release" = "WebObjects 5.0"; 123 - encoding = NSMacOSRomanStringEncoding; 124 -} 121 + { 122 + "WebObjects Release" = "WebObjects 5.0"; 123 + encoding = NSMacOSRomanStringEncoding; 124 + } 125 125 126 -{{/ code}}126 +{{/panel}} 127 127 128 128 Additionally, a WOO file can contain definitions of instantiated objects that your WO component can refer to. If you build your components with WOBuilder, you will find the definition of the attributes of your WODisplayGroups in your component's WOO file. 129 129 ... ... @@ -133,31 +133,31 @@ 133 133 134 134 As an example: 135 135 136 -{{ code value="xml"}}136 +{{panel}} 137 137 138 -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 139 -<wodefinitions> 140 - <wo wocomponentcontent="true" class="AjaxSortableList.java"> 141 - <binding name = "id"/> 142 - <binding name = "list"/> 143 - <binding name = "listItemIDKeyPath"/> 144 - <binding name = "startIndex"/> 145 - <binding name = "action"/> 146 - 147 - <validation message = "'id' is a required binding"> 148 - <unbound name = "id"/> 149 - </validation> 138 + <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 139 + <wodefinitions> 140 + <wo wocomponentcontent="true" class="AjaxSortableList.java"> 141 + <binding name = "id"/> 142 + <binding name = "list"/> 143 + <binding name = "listItemIDKeyPath"/> 144 + <binding name = "startIndex"/> 145 + <binding name = "action"/> 150 150 151 - <validation message="'listItemIDKeyPath' must be bound when 'list' is bound"> 152 - <and> 153 - <bound name = "list"/> 154 - <unbound name = "listItemIDKeyPath"/> 155 - </and> 156 - </validation> 157 - </wo> 158 -</wodefinitions> 147 + <validation message = "'id' is a required binding"> 148 + <unbound name = "id"/> 149 + </validation> 150 + 151 + <validation message="'listItemIDKeyPath' must be bound when 'list' is bound"> 152 + <and> 153 + <bound name = "list"/> 154 + <unbound name = "listItemIDKeyPath"/> 155 + </and> 156 + </validation> 157 + </wo> 158 + </wodefinitions> 159 159 160 -{{/ code}}160 +{{/panel}} 161 161 162 162 In this example, the API defines the bindings at the top, along with a series of validations. The validation message is displayed in the IDE when the declarations inside the validation evaluate to "true". For instance, for the first validation, the validation message appears if the "id" value is not bound. In the second case, the message appears if the "list" value is bound but "listItemIDKeyPath" is NOT bound. 163 163