Ok. I'm confused on one part. I did see the ognl site but wasn't seeing the same stuff I've been seeing in various tutorials. I'm taking it that the "wo: str " type sequences in the wods/html aren't in fact OGNL, and are something completely different.
On Sat, May 31, 2008 at 8:53 AM, Timo Hoepfner <[EMAIL PROTECTED]> wrote: >> I was starting to look into switching to the new WOLips and doing >> certain other old things the new "right way". I know that WOgnl is >> there, but google has not shown me an obvious overview page. > > > There's some documentation in the "Documentation" folder of the framework > source. Content pasted below. > WOOGNL is based on OGNL. The official site for it is http://www.ognl.org/ . > There you can find a language guide: > http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/index.html > > Timo > > > Hi, > I thought those on this list might be interested in a little > framework that I put together a few weekends ago that allows for the > use of OGNL syntax in wod bindings and D2W custom assignments. OGNL > is basicly key-value coding on steroids. Pulled straight from the > wod file of the downloadable example WOOgnlTest (note the '~' > character is just like the '^', ie it flags that the binding should > be resolved via OGNL. The '~' character is configurable so for > example you could set "OGNL:" to be the flag). > > // Calling static methods or accessing static ivars > String1: WOString { > value = "[EMAIL PROTECTED]@OgnlSpecialCharacters"; > } > > // Use of conditionals, note that every previous value of the . is > pushed into the ivar #this > String2: WOString { > value = "~name.length().(#this > 100? 2*#this : 20+#this)"; > } > > // String concat > String3: WOString { > value = "~\"Hello Max \" + name"; > } > > // Use of set operator in. can also use in against NSArray and > NSSet objects > String4: WOString { > value = "~name in {\"Main\", \"Something\"} ? \"Yes\" : \"No\""; > } > > // Variable declaration. Note that commas allow multiple actions > per expression. > String5: WOString { > value = "~#A=new com.webobjects.foundation.NSMutableArray(), > #A.addObject(name), #A.addObjectsFromArray(session.languages), #A"; > } > > The WOOgnl dev page is at http://www.netstruxr.com/developer/woognl.html. > > More info on OGNL is at http://www.ognl.org > > Comments, bugs, feedback or questions feel free to contact me. > > Regards, > Max > > > > > > === Overview === > It is often the case in a WOD file that you want to apply formatters to > various > bindings, but only certain specific components actually support the concept > of > a formatter. > > There are several approaches to solving this problem. One is to create > formatter > methods on your models (i.e, person.displayName() that returns firstName() + > " " + lastName()). > This suffers a design flaw in that you don't want what is essentially view > code in your > models. Another approach is to define these methods in a WOComponent, but > then you have the > problem that you can't reuse the value very easily (you need it in every > component). You could > create a new WOComponent that just renders in this format, but then you > can't pass it as the > value to another binding. > > Rails addresses this with the concept of a helper function. Helper > functions are easily reusable > formatting methods for use in your views. WOHelperFunctionHTMLParser > provides a similar type of > functionality for use in WOD bindings. > > > === Example Usage === > As an example, say you have a Person class and you want a common display > name (like in the example > above). With WOHelperFunctionHTMLParser, you would do the following: > > 1) Create a class like the following (in any package): > public class PersonHelper { > public String displayName(Person person) { > return person.firstName() + " " + person.lastName(); > } > } > > 2) In a WOD file: > PersonName : WOString { > value = currentPerson|displayName; > } > > (that is a pipe between currentPerson and displayName) > > 3) Set ognl.helperFunctions=true in your Properties file. > > 4) Profit. > > Likewise you can make StringHelper, BooleanHelper, etc. You want to use > "yes" or "no" when > you display booleans? > > in Java: > public class BooleanHelper { > public String yesNo(Boolean value) { > String yesNoValue; > if (yesNoValue == null || !yesNoValue.booleanValue()) > { > yesNoValue = "no"; > } > else { > yesNoValue = "yes"; > } > } > } > > in your WOD: > RandomValue : WOString { > value = currentPerson.isAdmin|yesNo; > } > > The above examples use WOString, so /technically/ you could use formatters > for these. Here's > an example where that wouldn't work out: > > HeaderFooter : HeaderFooterWrapper { > title = currentPerson|displayName; > } > > The examples here only define a single method, but you can define as many > helper methods inside > of the Helper classes as you'd like. > > > === How Does it Work? === > In the parser stage of loading your WOD file, helper function bindings are > replaced with the > much larger WOOGNL expression that is able to resolve your request, so > behind the scenes this > is using the same OGNL that you know and love. > > The helper class to use for a particular value is determined by the type of > object that comes > immediately before the pipe symbol. For instance, if getClass().getName() > returns > "com.mdimension.Person", by default WOHelperFunction will look for a > "PersonHelper" class > using the same bundle discovery that components use. > > > === Helper Function Parameters === > Because the method calls turn into WOOGNL behind the scenes, parameters > should mostly just work. As > an example, you could make a truncate helper function: > > in Java: > public class StringHelper { > public String truncate(String value, int atIndex) { > String truncatedValue = value; > if (value != null && value.length() > atIndex) { > truncatedValue = value.substring(0, atIndex) > + " ..."; > } > return truncatedValue; > } > } > > and in your WOD: > HeaderFooter : HeaderFooterWrapper { > title = pageMetadata.description|truncate(10); > } > > You are not limited to just a single parameter. > > > === Remapping Helper Instances === > It is sometimes helper to remap a particular type of object to a custom > helper class. In this > case, you can call: > > setHelperInstanceForClassInFrameworkNamed(Object helperInstance, Class > targetObjectClass, String frameworkName); > > Let's say you want Person.class to use MyPersonHelper as its helper instance > for the entire app, you would call: > > WOHelperFunctionRegistry.setHelperInstanceForClassInFrameworkNamed(new > MyPersonHelper(), Person.class, "app"); > > > === Per-Framework Helper Functions === > Unqualified, helper functions look in the "app" frameworkName to resolve. > However, this can cause conflicts if > you have a framework that wants to register its own helpers (you wouldn't > want to replace the top-level > StringHelper, for instance). Take Ajax framework as an example: > > WOHelperFunctionRegistry.setHelperInstanceForClassInFrameworkNamed(new > AjaxPersonHelper(), String.class, "Ajax"); > > To use a qualified helper function, you use the syntax: > > HeaderFooter : HeaderFooterWrapper { > title = currentPerson|Ajax.displayName; > } > > Note the "Ajax." qualifier in front of the helper function name. > > > === Subclassing Helper Instances === > Subclassing with helper instances is legal. So if you have a StringHelper > in your core framework, you can > make a MyProjectStringHelper extends StringHelper and register > MyProjectStringHelper as "app" helper. > > > === Gotchas === > If you use WOLips, you should go to Windows=>Preferences=>WOLips=>WOD Editor > and add pipe, open > paren, and close paren to the list of valid wod binding characters. > > > > _______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list ([email protected]) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
