• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: WOgnl resource
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: WOgnl resource


  • Subject: Re: WOgnl resource
  • From: "Joe Little" <email@hidden>
  • Date: Sat, 31 May 2008 08:59:22 -0700

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@hidden> 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 = "~@ognl.webobjects.WOOgnl@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@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >WOgnl resource (From: "Joe Little" <email@hidden>)
 >Re: WOgnl resource (From: Timo Hoepfner <email@hidden>)

  • Prev by Date: Re: WOgnl resource
  • Next by Date: Re: WOgnl resource
  • Previous by thread: Re: WOgnl resource
  • Next by thread: Re: WOgnl resource
  • Index(es):
    • Date
    • Thread