Using extra CFC attributes for documentation
Thursday, November 12th, 2009For the ColdFusion on Wheels API documentation, we chose to do something a little unconventional (but pretty cool). Instead of trying to write or use a comment parser for our documentation, we just added additional attributes to our CFCs’ <cffunction> tags.
Look at this example for the autoLink() view helper:
<cffunction name="autoLink" returntype="string" access="public" output="false" hint="Turns all URLs and e-mail addresses into clickable links." examples= ' ##autoLink("Download Wheels from http://cfwheels.org/download")## -> Download Wheels from <a href="http://cfwheels.org/download">http://cfwheels.org/download</a> ##autoLink("Email us at info@cfwheels.org")## -> Email us at <a href="mailto:info@cfwheels.org">info@cfwheels.org</a> ' categories="view-helper,text" functions="excerpt,highlight,simpleFormat,titleize,truncate" > <cfargument name="text" type="string" required="true" hint="The text to create links in."> <cfargument name="link" type="string" required="false" default="all" hint="Whether to link URLs, email addresses or both. Possible values are: `all` (default), `URLs` and `emailAddresses`."> <cfscript> var loc = {}; loc.urlRegex = "(?ix)([^(url=)|(href=)'""])(((https?)://([^:]+\:[^@]*@)?)([\d\w\-]+\.)?[\w\d\-\.]+\.(com|net|org|info|biz|tv|co\.uk|de|ro|it)(( / [\w\d\.\-@%\\\/:]* )+)?(\?[\w\d\?%,\.\/\##!@:=\+~_\-&]*(?<![\.]))?)"; loc.mailRegex = "(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))"; loc.returnValue = arguments.text; if (arguments.link != "emailAddresses") loc.returnValue = loc.returnValue.ReplaceAll(loc.urlRegex, "$1<a href=""$2"">$2</a>"); if (arguments.link != "URLs") loc.returnValue = REReplaceNoCase(loc.returnValue, loc.mailRegex, "<a href=""mailto:\1"">\1</a>", "all"); </cfscript> <cfreturn loc.returnValue> </cffunction>
It makes the function declarations a little beefier, but the documentation is right there with the code. As you can see, we added examples, categories, and functions attributes to the <cffunction> declaration.
Writing a parser took a little over a week, but it was fairly simple with CFML‘s GetMetaData() function and some extra business rules.
Here’s a link to the autoLink() documentation on CFWheels.org so you can see what the output looks like. Everything on that page is generated based on the code above.



November 12th, 2009 at 7:01 pm
Cool idea, I like how it looks in the preview. Where does the categories and functions attributes come into play?
Maybe you could use cfInterface to get the example code out of the CFC file? That is really the only drawback.
November 13th, 2009 at 2:34 pm
The
functionsandchapters(not shown) attributes will associate the function documentation with related functions and chapters in the reference guide.So you’ll see something like this eventually at the bottom of each function’s documentation:
I wanted to release something of value ASAP, so I decided to delay that functionality to a later iteration. Agile development works very well with volunteer work!
The
categoriesattribute is used by the parser today to categorize the functions into aparentSectionIdandchildSectionId. It uses QoQ on a query of sections to translate the strings into IDs.That’s an interesting idea with cfinterface, but I like the idea of the examples being directly in there. Documentation authors can look at how the function works as they write the examples. Test writers can see how it should be tested when writing tests. Developers looking at the code can see how it should be used.
I agree that it is a drawback to have that extra stuff in there, but it is a matter of opinion on how pragmatic that it is.
November 19th, 2009 at 9:19 am
you might want to add a link in the article to the Documentation Guidelines particularly the section entitled Generating API Documentation in Core Source Code that explains all the attributes and what they mean.
November 19th, 2009 at 10:04 am
You just did, Tony. Thanks!