Forms: comprehensive new forms library, including converting all Savory libraries to use it
Validation: server- and client-side, including reCAPTCHA support
Console: support for print() and println() shortcuts
Classes: new "_configure" and "_configureOnly" options for self-configuration classes
Progress: the old "processing" service was renamed to this
RPC: can now be configured via a DSL
Backup: new service for high-performance, multi-threaded backing up MongoDB to real JSON
JVM: new API: exec
Files: new APIs: openTextForReading, openTextForWriting
Lucene: search results are now returned as an interator
Ext JS: new reCAPTCHA form field widget
Ext JS Forms: standard, AJAX and Ext Direct
Ext Direct: support webform calls
JSON: can export JavaScript code (breaks JSON compatibility, but very useful!)
Dependency bumps: MongoDB-Rhino R95
And lots of bug fixes, too many to mention! Hey, we're still in Early Bird mode.
Some highlights:
FORMS
Without doubt, the most exciting addition is the forms API:
http://threecrickets.com/savory/abou...sources/forms/ There's not that much code here, but it's pretty darn sophisticated. Every web development framework needs good form support, but for a lot of frameworks out there (I've worked with dozens!) this often means that any form that is not trivial becomes an exercize in hacking into the framework code. I've really tried to learn from bad experience elsewhere and design what I hope is a sensible architecture for Savory. I've tested it a lot with various complex forms, and so far I am happy.
Savory handles both standard HTML forms and AJAX forms (such as those used by Ext JS) smoothly. It does both client- and server-side validation, also allowing for internationalization of validation error strings on both the client and the server. And it's very easy to extend and make it do things the way you need them.
Savory does OOP! Now you can use the "_configure" attribute is Savory.Classes.define to create a very common JavaScript constructor, that simply merges the single config argument to the instance itself.
Many other JS libraries allow for this, but in Savory I insisted on listing exactly which fields you want merged (and this list is concatenated from inherited classes, unless you use "_configureOnly"). I believe this is better because it avoids users essentially working around constructor limitations. The proper way to solve such problems is to create a new class, not to kludge constructor values.