Showing posts with label ColdFusion. Show all posts
Showing posts with label ColdFusion. Show all posts

Wednesday, April 9, 2008

My CF IDE Wish List

I drafted this awhile ago and never published it ... but as I was cleaning out some comment spam I came across it and thought I should put it out there. So here goes!

[In response to a a community-published survey about a ColdFusion IDE] I appreciate the reasons for doing a survey, but I really don't see the value in this particular survey or its predecessor from Adobe. My answers were basically... Yes. All of that. Important. Happy to pay for it. What else?

The features listed are basically what's available to us now, although not in a single IDE and perhaps at varying levels of quality. Although it would be a big improvement to see those things done right in a single environment, I think there are a lot of additional features that would really make the IDE worthwhile. Some things I would like to see – pie in the sky – are…

Integrated support for CF Reports – not a separate development IDE – it may or may not be a good idea from a performance standpoint, but it sure would be convenient! Or alternatively, opening up the CF Report format (CFR) into an xml-type language that can be generated by any number of tools - either community created, or perhaps, if I may be absolutely ridiculous, InDesign?! Reporting IDEs across the board are atrocious, but a single one, done right, could be revolutionary.

Integrate the server into the IDE so that the CFML you write is being actively compiled/interpreted sort of like it is in FlexBuilder. Then I can catch errors and typos as they are written – when I’ve mistyped a method name or not included a dependency. I believe this is a really complicated thing to do, but it would truly enhance productivity.

Improve support for SQL code. I know this was mentioned, but I want to emphasize it. I think the current workflow most developers use for writing SQL sucks. I don’t want to have to switch to my database IDE – that does nothing for me when I’m writing dynamic queries. The RDS Dataview query builder in FlexBuilder is ok, but limited – it doesn’t understand complex queries and is not intuitive for use with parameters/variables. And I want SQL syntax highlighting within my CF IDE.

I think the CF Extensions for FlexBuilder for generating CFCs are nice, a good start, and I’d like to see them enhanced and customizable. The XSLT or CFML approach that Brian Rinaldi uses for Illudium PU-36 CFC Generator templates works well for me. In fact, I really like Illudium, but if it was all within the CF IDE, even better. I'd also like to see some options to generate CRUD forms based on database tables. I realize you can sort of do this with the application wizards, but I'd rather be able to do it in small pieces, which I can then easily integrate into my application or site, instead of having to build the whole shebang, extract out the small parts I need, and then modify it so heavily I may as well have written it from scratch. In other words, I'm sick and tired of hand coding forms...

I think this one should be simple…fast access to CFIDE/Admin console from the IDE! Maybe sort of like the RDS approach – list all the CF instances you can connect to, and then click once to get to that particular admin. Or be able to browse admin settings right within the IDE.

This may make some hard core developers squirm or perhaps vomit…but I think having some well written “starter” applications bundled with CF would be useful. Sort of like Access comes with database templates for several common types of applications – contact management, inventory, project management, issues database, survey, blog, simple CMS… the same idea, but web-enabled. One key factor: have a well designed model that can be ported to various frameworks with minimal effort. It would be difficult to choose one particular framework, but if it was done right, it could be easily customized.

I understand there are probably good reasons to not do many of these things, but I’m just saying, as a developer/designer, these things would make my life a lot easier, and that’s what CF is all about, right?

Monday, September 10, 2007

Long Time Coming, Death of CFDJ

I think enough has been said about this on other blogs that adequately express my feelings on the subject, but I just love this blooper that Cliff caught...

http://histos.typepad.com/histos/2007/09/cfdj-pwnz-itsel.html

Great find!

Friday, May 11, 2007

Belated CF Objective Wrap Up

I'm finally starting to get my head back above water at work after returning from CF.Objective(), so I thought I'd share some of my experience. The conference was great! A huge improvement over last year, which itself was excellent, and what high quality content. I can't say enough.

The big topics at the conference this year were Scorpio and ColdSpring. Maybe I say ColdSpring because about half the sessions I attended at least mentioned it, or maybe because I was hanging out with Adam (ColdSpring's self-appointed agent) , Chris and Dave. But since I've been using ColdSpring and MG:Unity, without really understanding ColdSpring all that well, I thought I should get to know it a little better. Hey, I'm a designer - it takes me awhile to grasp these things!

And of course, what everyone wants to hear...what's coming with Scorpio? I'm really excited about several things that were announced
  • AJAX tags - there are 12 new ones! Not just new UI widgets using the YUI library while wrapping it up into the ever-simple CF syntax; but also JSON serialization for CFCs, data binding, error handling, and a JavaScript debugger. A lot of the concepts seem to echo Flex, so if you've done any work with Flex these features will come very naturally. This is just one more step towards my life goal of never having to write JavaScript again :)
  • PDF tags - not just improvements to , but which allows you to manipulate PDFs in dozens of ways (combining docs, watermarking, rotating pages, etc), and process Acrobat Forms. The functionality is taken from LiveCycle, and from what I hear, we should all be very appreciative of the power that's being added to CF at a fraction of what it would cost to get LiveCycle. A very SMALL fraction. A few people grumbled that you won't be able to create PDF forms with CF, but I say to those people, just wait and I think you will find out that you really don't need that functionality. If you need to create a dynamic form so badly, ever heard of...ahem...HTML? Or how about that thing they call Flex?
  • Geek features - I didn't attend the Scorpio 1337 session (features only geeks could love) because there was something else on the schedule I wanted to see at the same time (although that seemed to happen every time slot, there were so many great topics). But there were promises of some very geeky features like Interfaces, the debugger, and well, I don't remember them all because I didn't attend this session, but I'm sure if you are a geek there will be lots of things for you to appreciate.
  • The new CFAdmin interface and server monitoring features are sweet. You can drill down into every connection and request on your site, to see where the load is and what exactly is going on at any moment in time (right down to the values of variables in various scopes), along with completely customizable alerts (you can even write a CFC to do your own alert handling). It's really amazing that you can find out so much about what's happening on your server in such a simple way.
  • There's lots more, but this post is getting long.
It's not common that I leave a conference with no complaints. In comparison to CFObjective, other conferences are too long (by the last day I'm not interested or up to seeing any more sessions), don't have enough good content (all three sessions I want to see will inevitably be at the same time, while there are entire afternoons full of nothing I want to see), have too many sales pitches, have crappy food (hey, details matter), have bouncers working the door at every session to ensure no unwanted guests get in (bad vibes), or cost too much (something you begin to question when you go to an extravagant social even that's actually kinda lame, and realize that half your registration fee went to pay for that one night). Great job Jared, Steven, Jim and team...I'm looking forward to next year!

Thursday, May 3, 2007

Off to CF.Objective!

I'm about to sign out and leave for the airport to head to Minneapolis for the 2nd ever CF.Objective() conference. From what I've heard about this year's conference so far, it sounds like it's going to be great and I'm excited! I'll try to blog some talks I attend if I'm not too distracted...if you're going too, see you there!

Tuesday, April 10, 2007

Launch of MSL.com, my latest project

I'm pleased to announce the launch of my company's new website:

http://www.msl.com

It's been in the works for awhile, but since I'm the lone wolf doing all the content, design and development, it's taken awhile. Needless to say I'm happy it's done and quite pleased with the results. Of course, it's never really done! I had to hold back on many of the features I wanted to build, because we really just needed to move away from our old, static HTML tag-soup site. However like all sites, it's a work in progress and will continue to change over the coming months.

For the geeks, it's built with ColdFusion 7 and utilizing the Model-Glue framework. It also uses YUI for the menus and some of the layout, and SPRY for some of the other AJAX/DHTML stuff. The markup is XHTML/CSS, it did validate at one point but the YUI menus don't validate...bummer. Oh well! I've never been that sort of standardista...

Friday, April 6, 2007

Dreamweaver Extensions for Model-Glue XML (and FB and M-ii)

On a couple of occasions I have thought that someone needs to write a Dreamweaver extension for ModelGlue, as well as the other frameworks, especially a tag library (and a file browser/inspector wouldn't hurt - those ModelGlue.xml files can get long...). I can't tell you how many times I've habitually hit ENTER after typing "na..." to add a name attribute, which auto-completes in CF but not for XML.

Well at least there is a solution to my first desire! The ever-productive Massimo Foti has a series of Dreamweaver tag libraries for the popular frameworks. They can be found on www.massimocorner.com. The site seems to have a thing against deep linking, but you can find the .mxp file downloads under the Dreamweaver > ColdFusion section.

Thank you, Massimo!

(now I just need to find a file inspector, perhaps any good XML one would work...)

Monday, April 2, 2007

Serving a Downloadable File with ColdFusion in Model Glue

I thought maybe it's time for another "real" blog post. I learned a little something today (with some help from Adam) so now I'll share. A hyperlink to download a PDF file - seems simple and straightforward enough. But I've been building this site using the Model Glue framework (and learning MG in the process -- so far so good!), and I wanted to serve the file with <cfcontent>, not just a plain hyperlink, so it wasn't as straightforward as just <a href="myfile.pdf">Download It</a>...

Here's my solution, I'd be interested to hear how others have done this. It seemed like a little bit overkill as I was writing it, but I also realized that I would never need to write this snippet of code again, so that kind of makes up for the long-windedness of it.

The solution is composed of all the standard files and snippets in a Model Glue application.
  • the "model" CFC - in this case, a simple object
  • a .cfm view file where the "cfcontent" resides
  • a function in the Controller.cfc to create the download object and add it to the event
  • a message broadcast, listener, and event handler in the ModelGlue.xml file
  • all the views, which compose my page and contain the links to download the file

First, let's look at the "Download" Bean CFC: Download.cfc represents my "file" object that stores my file information. It basically just stores values for the file name, file path, and mime type of the file I'm serving for download. It lives in my "model" folder.


<!--- Download.cfc --->
<cfcomponent displayname="Download" hint="retrieves a file for download to be served with cfcontent">

<!--- init() --->

<cffunction name="init" access="public" returntype="any">

<cfargument name="fileName" type="string" required="yes" hint="name of file once downloaded">

<cfargument name="filePath" type="string" required="yes" hint="full path of file to be served">

<cfargument name="fileType" type="string" required="yes" hint="mime type of file">

<cfset filename =" ARGUMENTS.fileName">
<cfset
filepath =" ExpandPath(ARGUMENTS.filePath)">
<cfset
filetype =" ARGUMENTS.fileType">

<cfreturn this>

</cffunction>

<!--- getters --->

<cffunction name="getFilename" returntype="string" access="public" output="false">
<cfreturn filename>
</cffunction>

<cffunction name="getFilePath" returntype="string" access="public" output="false">
<cfreturn filepath>
</cffunction>

<cffunction name="getFileType" returntype="string" access="public" output="false">
<cfreturn fileType>
</cffunction>

</cfcomponent>

Notice that the CFC uses ExpandPath() so that a relative url can be passed in as the location of the file, which is much easier when it comes time to build your link, and then the app is not server-dependent. Yes, I could write setters and use those setters to construct the CFC, but I'm never going to build these objects to say, insert into a database, so I didn't bother.

Then I have the actual "download" include. It's called _download.cfm because the underscore preceding the filename is a common convention for files that should not be called directly, but need to be included in another file, it also differentiates it clearly from your "template" view files.

This file gets dynamically included on the page when the "download" viewState value is present. It also only serves the file if it's not a simple value (to ensure the values we need are there). It lives in the "views" folder. Notice there are separate values for the file path and the file name. The file name is what the user sees when they download the file, the file path tells CF where to locate the file. Being able to set the file name in the header is nice because you can use a short, sweet and simple file name for the end user, but your own convoluted, datestamped , purpose-coded file naming convention for the actual file (ok maybe that's just me).

Also we use the http header so that the user will be prompted with the browser "download" dialog, rather than leaving it to the browser to try and open the file directly. It prevents us from having to list some weird instructions like "right-click and choose Save Target As" for the less-savvy users (arent' they all).



<cfset download =" viewState.getValue('download')">

<cfif NOT isSimpleValue(download)>
<cfheader name="Content-Disposition" value="attachment; filename=#download.getFileName()#">
<cfcontent type="#download.getfiletype()#" file="#download.getfilePath()#" deletefile="no">
</cfif>


My Model Glue Controller.cfc contains this function to build the Download object. It just calls the Download.cfc, creates the "download" object, and then adds the instance of said object to the event so it can be found when the page is rendered.

<!--- Controller.cfc --->

<cffunction name="getMyDoc" access="public" returntype="void" output="false">
<cfargument name="event" type="any" required="yes">
<cfset fileDownload = createObject("component","model.Download").init('MyDoc.pdf','assets/docs/MyDoc_123.pdf','application/pdf')>
<cfset arguments.event.setValue("download", fileDownload)>
</cffunction>


In My ModelGlue.xml file, I hook my application into the above function with this XML snippet.

<message-listener message="getMyDoc" function="getMyDoc" />

The event handler for that message is...

<event-handler name="download.mydoc">
<broadcasts>
<message name="getMyDoc" />
</broadcasts>
<results>
<result do="page.mydoc" />
</results>
</event-handler>

The broadcast, obviously, requests the download object via the Controller.cfc. The result - "do" is the same page that my link is on - so the user does not leave that page when they click the "download" link, they are just served the file. Lastly, on the page where I want the link that is clicked to download this file, this is the <a> tag:

<a href="#viewState.getValue('myself')#download.mydoc">Download My Doc</a>

Nice. That's all there is to it.

Of course this sample doesn't show any security or anything, this would only be appropriate for a public download. Sorry if the spacing and indentation is ugly, Blogger's code formatting is a pain! Hope you find it helpful!

Monday, January 29, 2007

CFEclipse Tips: Line Numbers, Updating to 1.3

I started using CFEclipse a few months ago when I got FlexBuilder, it just made sense for a CF/Flex project. It was definitely an adjustment after years of using Dreamweaver and there were immediately some things I liked, but also some annoyances that I took for granted in DW. One of those annoyances was that line numbers never show up by Default for CF files...however I dug around in the preferences a bit and found that there is indeed an option to turn on line numbers permanently, so they will always show when you edit CF files.

Go to Window > Preferences > CFEclipse > Editor and check the "Show line numbers" option.

May be obvious to some, but for someone just getting into CFEclipse I was very happy to find this setting!

Tip #2 is an issue I ran into when I updated to version 1.3. I ran the updater from the "Find Updates" feature, and restarted just to be safe, but I started getting all sorts of errors when I tried to open CF files.

On a hunch I went in to Help > Software Updates > Manage Configuration, expanded the tree and noticed that 1.2 was still listed in addition to 1.3. I disabled 1.2, and the problems went away. Makes sense that having two versions running simultaneously would make Eclipse very unhappy.

SQL "IN" Clauses, and CF Single-Quotes

I firmly believe that problems can always teach you something, it's sometimes just not that fun of a "learning process." So last week I had this really annoying problem trying to pass a comma-delimited list to a SQL "IN" clause. In the past I've solved the dynamic IN clause issue with code that looks something like this:


AND (

<cfloop list="#myList#" delimiters="," index="i">

(myTable.myCol = '#i#')

<cfif i IS NOT ListLast(#myList#)>

OR

</cfif>

</cfloop>

)


I always felt it was kind of ugly but never bothered to learn a better way. I should have looked it up sooner! I knew I could use an IN clause but the problem was wrapping the IN clause list with quotes. Doing that manually seemed worse than just looping over the list. The real problem with the above code arose when the list contained multiple list items of the same value. In that case, the ListLast function did not produce the desired result, and the resulting SQL was invalid.

I started out looking for some type of function that would remove duplicates from a list. I then stumbled across ListQualify(list, wrap character, delimiter, scope), which turned out to be a super-handy function. Pass it a list, a character, a delimiter and a scope and it will wrap each list item in the desired character - you can even choose to only wrap characters, or all list items. So I could wrap my list values in single quotes, and then use the SQL IN clause. Yay!

As a side note, I ran into a very annoying but rather funny issue with CFEclipse's auto-correct feature. I dare you to try typing this string in CFEclipse: "'" (that's double-quote, single-quote, double-quote). Yeah, not happening. I had to type it in Notepad and then paste it in. Sometimes you just feel like the world is against you!

I was ready for that ugly error to finally be gone when I refreshed the page, but lo and behold, a new error. Apparently each single quote mark in my list was being doubled. I did not know that CF automatically escapes these characters in such a situation. That's when Adam reminded me of the PreserveSingleQuotes() function, which does just what it sounds like, and viola, no more error.

In addition to learning something new, it's sure nice to have someone who knows everything about CF right at home!