Today's Best of ColdFusion 9 entry is Hyrule from Dan Vega. This entry is - to me - a slight break in the rules. It is an existing project and not something created brand new for the contest. I don't think I was specific in that regards and since the code is ColdFusion 9 specific and therefore pretty much new, I'm letting it slide here. Plus it has a Zelda-based name and therefore it must be cool.
At it's heart, Hyrule is a validation framework. Now - I don't know about you - but one thing I've yet to really nail down in my development is a good way to do validation. I have a few different ways I do it in my applications, and I don't expect to have "One Right Way", but I would like to have a method that I feel confident in and that I use most of the time. I'm just not there yet. Hyrule looks to be a solution for that problem.
In his readme, Dan says that Hyrule is based off of both the QuickSilver project and Hibernate Validation. Neither of those are projects I've been exposed to so I can't really comment on how well Hyrule implements them.
Hyrule makes use of annotations. An annotation is a non-code based comment that is treated specially by either the server compiling the code or other code processes. Certain tags in ColdFusion, since the MX time frame, have allowed you to add additional arguments. So for example, your component tag can look like this:
<cfcomponent name="Cobra Commander" snakevoice="true" egoOfARubyDev="true">
Now obviously those last two attributes aren't supported by ColdFusion, but if you run code like this you won't get an error. Instead, ColdFusion simply copies those arguments into the metadata about the component.
With the introduction of script based components in ColdFusion 9, we now have a new way of doing this. For example:
/**
* @name "Cobra Commander"
* @snakevoice true
* @egoOfARubyDev true
*/
component {
So technically none of this is very useful. Some metadata items are used in documentation, but outside of that they really don't do anything. That's where Hyrule comes in. By following some basic rules, you can quickly add validation to a component. So for example, consider this simple User component (which comes from the nicely documented samples):
/**
* @output false
* @accessors true
*/
component {
/**
* @display First Name
* @NotEmpty
*/
property string firstname;
/**
* @display Last Name
* @NotEmpty
*/
property string lastname;
}
You can see that each of the two properties have a few comments above them. Each of these annotations will be picked up by Hyrule. Here is a quick example of running the validator against the component:
<cfset user = new User()>
<cfset user.setFirstName("")>
<cfset user.setLastName("")>
<!--- create an instance of the hyrule framework --->
<cfset hyrule = new hyrule.Validator()>
<!--- validate the object by passing it to the validate method --->
<cfset hyrule.validate(user)>
Once you've validated your component, you can then get the result:
<!--- did this object have any errors --->
<cfdump var="#hyrule.hasErrors()#">
<!--- dump the errors array --->
<cfdump var="#hyrule.getErrors()#">
The result:
Pretty nifty. There is a long list of validators supported by Hyrule, including basic type checking (numeric for example), range checking, regex patterns, etc. And if you don't find a validator to your liking, you can actually create a custom one:
/**
* @custom hyrule.samples.custom.isUniqueUsername
*
*/
property username;
All in all, very slick. As a framework, it has the typical "installation" process of copying the folder. It then have one glaring fault - and this may already be fixed in the latest release. The code tries to load a resource bundle for error messages. That's nice because it means you can localize the errors. However, it uses a . Line 34 of ValidatorMessage.cfc has:
var rbPath = dir & "resources\" & getResourceBundle();
Repeat after me: Stop using . / works just fine on Windows and Unix. If this isn't fixed in the latest version, simply replace the \ with a /, and next time you see Dan, tell him Ray said he has to buy you a beer.
Ignoring that - everything works smoothly. I like the samples page - although I wish he would also show more of the code. So instead of just telling me about a feature and linking to a result, actually show the code you used to set up the validation. That would save me from having to open the CFC and look at the code directly.
Archived Comments
I _really_ like this framework although I dislike the style of adding annotations in what looks like but isn't really a comment.
I prefer this style though am interested in others opinions on likes/dislikes:
component accessors="true" output="false" {
property type="string" name="firstname" display="First Name" NotEmpty="true";
property type="string" name="lastname" display="Last Name" NotEmpty="true";
}
I prefer that style as well. I should have made it clear he supports both which is nice. (Well technically he doesn't do anything special for it - both end up in the same metadata.)
First off thank you so much for taking the time to review my project Ray. After seeing all of the cool projects being reviewed I agree that I probably should not of submitted it. What is done is done though so I hope you will all take some time to look at the project. I have not added much code since the start of it because I have not really gotten any feedback and I could really use some to drive the project forward.
Also FYI - This framework is not really *based* on Quick Silver. I need to fix my descriptions. It was more of an inspiration for this project because of its annotion based properties.
Totally on the side, TY RAY for plain option for code!
Great point guys - You don't *have* to use them as comment annotations. ColdFusion will extract the meta data either way, its just a preference for me.
@Chuck: That's Jason Delmore's ColdFish plugin. This version will be in the next BlogCFC release, which will be tonight.
At first, I didn't care much for the comment annotations, but now I actually think it's a good way to separate "framework-specific" annotations from standard property attributes. So my preference would be keep the validation annotations in the javadoc style and standard stuff (like "hint" and "displayname") inline.
@Dan -- Hyrule looks really cool -- great work! I'll have to make time to play with it.
Way to be late to this thread but... I do hate annotations. They are note *meant* to change the behaviour of the code but they actually DO change it.
(add a /** @output true */ to a function for example)
They feel ugly and dirty as a Divine Brown to me.
Wow, _way_ late Mark. ;)
A "Divine Brown" - this sounds interesting but I'm a bit scared to Google it. ;)