Friday, May 30, 2008

Thi(e)s(e) (2.5) Week(s) in Wonder

ERCoreBusinessLogic has a nice new generic audit trail mechanism in the form of ERCAuditTrail. More documentation to come soon on this.

Chainable sort orders via ERXSortOrder (and/or ERXKey's sort order methods). For instance, you can do:

NSArray sortOrders = Person.LAST_NAME.asc().then(Person.FIRST_NAME).asc()).array();

ERXKey has "plural forms" of the sort order methods. For instance, Person.FIRST_NAME.ascs() (the "s" on the end will give you an NSArray containing a single eosortordering that represents "firstName asc") -- this is just a sort-cut for cases where you just have a single EOSortOrdering that you want to pass to a fetch spec.

AjaxSubmitButton can perform a partial submit without having an updateContainerID specified now (which really could be considered a bug, which I usually don't list here, but it's handy to know). So it behaves similarly to AjaxUpdateLink and AjaxSubmitButton's without a partial submit in that it will turn into a background request only.

You can now control Ajax resource insertion by providing a delegate to ERXResponseRewriter via ERXResponseRewriter.setDelegate(yourDelegate). See ERXResponseRewriter.Delegate. This lets you override when the framework (or other code) asks to include "Ajax" "prototype.js" and instead replace it for your own custom resource. For instance, if you want to bundle all your js into a single file, you can provide a delegate that overrides requests for any of the individual files and instead use your custom ones, or replace files with a minimized version of the original which may only be used in production.

AjaxModalContainer got a bit of a face lift (this is quoted from my original post on wonder-disc:)

Previously if you put contents inside the container tag, it would always render, which could be really big if you have a repetition. Now you can set ajax=true, and it will fetch the contents in an Ajax request instead. If you set ajax=true, you must also provide an id binding.

Previously, all the Ajax requests that were happening were not tagged with the proper request header, so it made Ajax requests appear to the server to be non-ajax requests.

There is now an iBox.init() function that is exposed to allow reinitializing iBox. For instance, if you have iBoxes in an update
container, you will want to call this at the bottom of your container. We need to add a better, more generalized way, to address this problem at some point, because several of the libraries have similar requirements.

You really should carefully consider the use of the action binding. It does not execute as an Ajax request (I'm not sure why, but it's explicitly documented as such), which means you can burn your backtrack cache using it. The preferred method of use for modal container should really be external hrefs, direct contents, or the new ajax=true binding with contents. In fact, unless someone has an example where the action binding is valid (which is possible -- I just can't think of an example), I'm almost tempted to consider it deprecated, or at least the behavior might change to make it more like other action bindings on Ajax components.

Lastly, there's a new example in ModalContainerExample that shows AjaxModalContainer used inside a repetition with an ajax=true that contains a form that allows you to edit objects in the repetition.

Migrations support more batch operations. For instance, previously you had to call .create() on a table prior to calling .setPrimaryKey(..). The Migration API now keeps track of whether or not it has been created and will work the same either way. Additionally, there are some new methods on ERXMigrationTable that provide support for PK generation through the usual EOF routes.

ERXQualifierInSubquery provides support for fetching objects of an entity where one of its to-many relationships matches a given qualifier.

ERXJDBCUtilities has some more convenience methods for doing ResultSet manipulation (for use primarily in complex migrations) via processConnection and processResultSetRows (see the javadoc for more info on using). Mainly these guys take care of opening and closing JDBC resources for you based on EOF adaptors.

ERXKeyGlobalID provides support for serializable EOKeyGlobalID's.

There is a new "globalID" prototype for storing globalID values in other EO's that uses ERXKeyGlobalID.

Rather than set the 4 or 5 recommended EC locking Properties, you can now just set er.extensions.ERXEC.safeLocking=true which will set all the recommended values for you instead.

ERXExtensions.initApp and ERXExtensions.initEOF static methods have been added to support running Wonder in test cases and main methods without wrapping your code in ERXMainRunner or a WOApplication.

ERXQuicksilverQualifier is a KeyValueQualifier that compares values with ERXStringUtilities.quicksilverContains, which considers "QS" to be 'equal' to "QuickSilver" -- matches the original string as long as the letters appear in sequence, but not necessarily contiguous. This does _NOT_ work in EOF -- only in memory.

"wo:img" and "wo:image" are now built-in shortcuts for the inline bindings parser.


  1. wo:img ... thanks. Also the heading of this post required more than a few seconds to figure out what was going on with the parentheses! "Thi(e)s(e) (2.5) Week(s) in Wonder" .. but I figured it out not straight away but after about 4 seconds.... a true geek heading! Nice update. Thanks. I appreciate Wonder .. (I also appreciate Anjo's work ;-) )

  2. For the record, it's only SORT of geeky ... The This variant is sort of bogus... In retrospect I should have made it full-on geeky and made it a proper regex instead of just a sort-of geeky form. Sadly I actually debated internally about this for WAY longer than it deserved :)