cftopper.com

Tip: Easily protect your include files

Hi All. Sorry I haven't posted in a while, I've been very very busy. Thanks to everyone who has been encouraging me to release our Content Management Software I demonstrated as CFUnited EUrope... soon I promise.

I just thought I'd share this quick and useful tip:

Put the following code in all your Application.cfm or Application.cfc fles to automatically protect your include files such like "inc_test.cfm" or "act_deleteUser.cfm" from being called directly.

UPDATE: This code had a bug which was fixed 30th April 2008
<!--- Any script such as inc_file.cfm or dsp_file.cfm can not be called directly --->
<cfif mid( ListLast( cgi.script_name, "/" ), 4, 1 ) IS "_">
    <cflocation url="#APPLICATION.siteURL#" addtoken="no" />
</cfif>

There is some code in fusebox that prevents calling files other than index.cfm but we have found this too limiting.
Tags: ColdFusion | Tips

CFUnited Europe 2008

Mission accomplished - I spoke at CFUnited and survived.

Charlie Arehart was nice enough to give me some tips and help me rearrange and improve my Powerpoint presentation for the 2 hours before my talk.

With minutes to go, I saved my Powerpoint and suspended my laptop, then headed upstairs to the conference room. Now this was my first time speaking in front of more than 6 people and I was extremely nervous.

I get to the conference room and there are a few people in there already. I head up to the stage, laptop in hand and start setting up... I hit the power button to restore my laptop and.... what the hell... my laptop is rebooting, not restoring.

OK, not too bad, I'll just have to start ColdFusion, open the presentation and Firefox windows again. My laptop takes an age to start up.

So I am 3 minutes into the presentation and still waiting for my laptop to warm up. Fortunately there are still a few stragglers filing into the small conference room.

I double click to open the presentation and wait. And wait. It is taking ages to open. My laptop is being projected onto the 8 foot screen; everybody in the room feels my pain when Powerpoint reports that the file is corrupt and asks if I would like to restore it. Hell yes, restore that thing and fast.

I start the presentation. My freyed nerves are shattered but the show must go on. I start into the slides and notice something strange on the "About Me" slide. It's not exactly right.

Then I get to the "Contents" slide and notice that all the changes Charlie helped me make have been lost. Now this is a major curveball - there were entire topics that I had dropped, new sections I added and the whole thing had been rearranged.

Next disaster. The first section in my presentation should have been the last - it's all about "Source Control". I ask for a show of hands to make a point - "How many people in this room use source control". I had expected about 4 hands. I am dismayed to see that of the room of maybe 35 people, only 1 does not have his hand up.

Anyhow, I persevered and bluffed my way through the rest of the presentation. I'd like to thank everybody who was in the audience for their support. As promised here is the real presentation. Hopefully you all got something from the rest of the presentation. Topics covered:
  • Quick Tip: AJAX debugging
  • Supporting Different Timezones
  • Foreign Language Support
  • Advanced File Uploading
  • Quick Tip: CSS Hacking for IE6
  • Working with Multiple Domains
  • Database “Sharding”
  • Source Control.
I also gave a demo of our content management system, TeamworkCMS, and it's powerful plug-in architecture. As promised this will be released in May 2008. Stayed tuned.

I learned a lot from this experience and i'm sure that next time, i'll be more prepared and much more confident. It was a great experience all-in-all.
This is the latest CF9 prototype (codename MoHawk):
CF9 (foot) at CFUnited 2008
Tags: ColdFusion

I'm speaking at CF-United Europe!

I'm going to be speaking at CF-United Europe! It's my first real public-speaking effort so please lend your support.

The topic is:
How we made it: Teamwork Project Manager - tips for development of highly-scalable web2.0 apps in ColdFusion.

We developed Teamwork Project Manager over the last 7 months. There aren't many web2.0 CF apps taking on the Ruby crowd these days and I think my speech will be interesting.

Some items would include:

  • Industry Analysis
  • Ajax & ColdFusion
    • Debugging techniques
    • Processing the response
    • Using JSON with CF
  • Handling Multiple Domains with one application
  • Advanced file uploading - hundreds of files in one go
  • Database design
  • Scalability
  • Support
  • Sales & marketing

Teamwork Project Manager - The Sstory

We hear a lot about people building web2.0 apps like Twitter using Ruby on rails. Rarely do we hear a mention of ColdFusion being use to build a scalable high-availability ajax enabled application. But at Digital Crew we recently launched Teamwork Project Manager - an application that as the name suggests, allows organisations to manage their internal and external projects and get productive.

The whole thing is built on our own 'SiteEngine' framework using ColdFusion and MySQL.

Here is the story so far.


The Teamwork Project Manager Story

January 2007


Peter Coppinger & Dan Mackey founded their company Digital Crew almost 8 years earlier and have made a living building websites, intranets and custom web-based solutions for clients in Cork, Ireland. At this point their company has a good reputation internationally and they sell website components online.

However they found themselves up to their eyeballs in client projects.
Peter Coppinger says, "Every Monday we held a meeting and discussed the current projects - reassigned tasks and set milestones. We maintained a large whiteboard separated into 5 segments - Active Projects. Upcoming Projects, Sales, Meetings and Billing.

The whiteboard was neatly organised and gave us a sense that we were organised.... but we weren't.

The meetings were taking longer and longer. We knew we needed a better system.
".

March 2007


Peter and Dan spent some time reviewing and using project management software. Many are very expensive and all are overly complex. They wanted something intuitive that doesn't take time to learn and maintain. Something everybody in the company can use - not just the project manager.

Peter dreams of a software system that would basically manage a company. Call it a project management system, if you will - something extremely easy-to-use and generic enough that it could be used by all sorts of companies. He starts scribbling ideas on paper. In the morning he returns to work and the confused whiteboard overlord.

May 2007


Peter and Dan discuss the software they want to make almost daily now. And they have a name - Teamwork Project Manager (styled after TeamworkCMS - Digital Crew's bespoke website content management system).

A credos is set - "Project Management Made Easy!"

Peter and Dan are too busy with 'real work' to dedicate time to developing the product idea. But fate intercedes and a manager from a multinational client calls Peter to ask if he would have time to do a "simple" project management system. They want something extremely easy-to-use that would list upcoming and late milestones. This is the opportunity Peter has been waiting for. He eagerly tells the client about the software he has been thinking about making for a while and the client agrees that it is exactly what they need.

Peter first reviews other popular project management systems to find out what they are doing right and what they are doing wrong. Although other Project Management solutions exist, they are all too slow, clunky and badly designed. None are what the client wants and Peter has in his head. He makes a list what he likes and dislikes and puts pen to paper designing the software.

While on holiday to visit his sister in Boston for 3 weeks, Peter shamelessly neglects holidaying to stay up night-and-day working on the 'Project Management System'. Dan, busy with other client work back in Cork, checks in every morning. Screenshots fly back and fourth but Peter is reluctant to show the software running "until it's ready". Dan, also passionate about the development of their first "real" product, provides a steady steam of encouragement and suggestions.


June 2007


The software is installed for the client. Peter nervously waits for their feedback. Will they love it or loath it? Peter checks back an hour later and the client manager has already set-up several projects, added staff, assigned tasks and milestones. Just then, the phone rings. The client manager tells Peter that this is exactly what he was looking for. He was able to use it right off-the-bat with no instruction manual. Software, the way it should be.


August 2007


Dan works post-haste on TeamworkPM adding his fair share of sleepless-nights to the tally. The software is lovingly sculpted bit-by-bit with sometimes heated 'discussions' over items such as the color of a link. Their mission is simple - to make the worlds most easy-to-use, fastest and best Project Management System.


September 2007


Weeks of preparation. Servers are set-up. Database is optimized. Software continually improved. The promotional website is made. And finally the launched date is set.


October 2007


Everything is ready and has been tested a hundred times.
Teamwork Project Manager is launched on October 4th 2007.

Almost immediately, through their respective software development blogs, curious users start browsing the website and Teamwork Project Manager receives it first sign up within a hour of launch!

It's only been 3 weeks so far and the feedback has been great. We didn't expect the sales to start until at least the 30-day mark but we things are going better than expected. We believe we have a great product and we are now working hard on the marketing side of things.
Stay tuned to the blog. I look forward to updating this story.

Thanks for reading the story. So far we have had a great response and we are continually improving the software. We believe that our software lives up to our credos - "Project Management Made Easy". We want the software to be so easy-to-use, our own computer-shy mothers could use it (and indeed they do).

We are working extremely hard to deliver more features and continually improve TeamworkPM. Please try Teamwork Project Manager for free.

We have launched!

We have finally launched!!

And what a wild ride it has been getting everything ready.

Check out Teamwork Project Manager at www.teamworkpm.net

The Website - Final Days

About a 5 days ago we had this marketing website almost complete. We stood back and looked at what we had created... and we decided... it sucked. Against the pressure of the looming launch date chiseled in stone on the preview website, we started again. We threw away the old website and said to our designer, Adam, "Hey Buddy, um... we don't like the site. Can you cook us up something prettier?".

Lo and behold, he disappeared off the face of the Earth for 2 days and returned with the new website design. And we saw that it was good. We worked round the clock slicing and dicing, XHTMLizing and CSSing, content-managing, tweaking and testing.

A few hours behind the intended launch time, we made the critial change to the IIS web server and set the new site live, flying open the doors allowing all to sign up for the shiny new kid on the block - Teamwork Project Manager.

Here we are in my office seconds after putting the website live. We are tired, we are hungry, we have sore backs and aching asses... but we're happy. That's me, Topper, on the left and Dan on the right.
We are holding the camera in our out-stretched hands (attempt number 10 to take a photo with both of us in the frame. The bad quality reflects that this was taken on my trusty K750i camera phone.)



We still have a lot to work to do on this website of course but we are proud of what we have created.

Teamwork Project Manager - Final Days

We started making some important changes with just days left to launch.

For example, our testing had revealed that user were getting confused between project view and top-level/dashboard view. They would just blink wildly and we've have to explain that you have to click-into a project. Also in project view they wondered where all the other projects had gone.

We fixed this by redesigning the navigation system into two bands of tabs in stead of just one with and extra "Project View" tab at the top level to make it obvious that the user was now indeed, in project view. It's so much more intuitive this way.

What else - oh yes, Dan whinged on about the need for starring of projects for so long that I finally relented. I didn't plan on getting this done for launch but I'm very glad I did now. Now, when you are members of a whole host of projects and the dashboard is getting a little busy, the user can switch to custom view where he will only see the projects he has starred.

Also when there are loads of active projects such as here at Digital Crew, we now only list the projects that have been active in the last 14 days on the sidebar. Other projects can then be shown by clicking "All projects". It looks so simple but we had a good 10 minute discussion over the best way to present this to the user. We considered tabs for "Recent Projects" and "All Projects"  but in the end, I think the way we have it now is much better.

TeamworkPM is launched at last and Dan is a happy little camper

Après Launch

This morning I woke up and eagerly turned on the computer, anxious to see if we got any sign-ups or feedback. I was delighted to see a very positive email - " I have started playing with the app and am incredibly impressed with the ui and the streamlined approach to project management.". He then asked us to provide a roadmap and listed a few more features he would love to see.

This type of feedback just hours after launch is great motivation for me. I'm going to get busy cooking up the extra feature this guy wants and serve it hot! Stay tuned.

TeamworkPM Launched - Topper has his legs up! A job well done.

PS. I will be adding a roadmap page to the Teamwork site before the end of the day,
PSS. I just added a "Chat Now" link in the footer of this website so feel free to get in touch.

Check out Teamwork Project Manager at www.teamworkpm.net

Quick Tip: I Forgot the ColdFusion (CFMX7) Administration Password?

OK, It happens - you forgot the password. Maybe your working on a client web server and nobody knows what the password was set to 2 years ago when they set it up. Maybe your just suffering brain-freeze. Or maybe your just thick. Messing

Anyhow, you've tried everything and your pulling your hair out.
Here's the solution, it works with CFMX6/CFMX7.
  1. Open the file C:\Program Files\ColdFusionMX\lib\neo-security.xml.
  2. Change:

    <var name="admin.security.enabled">
       <boolean value="true" />
    </var>

    to read

    <var name="admin.security.enabled">
       <boolean value="false" />
    </var>
  3. Restart ColdFusion and you can now log into the administration without any password.
  4. Make sure to pick a new password and turn the security back on. You can do this in the administration.
Tags: ColdFusion | Tips

How to Change the CFMX Dev Server Port

I installed a demo website on one of our sales guys laptops earlier today and needed to change the port on the CFMX built-in server from 8500 to 80. Here's how it's done for posterity:
  1. Open C:\CFusionMX7\runtime\servers\coldfusion\SERVER-INF\jrun.xml
  2. Find "8500", replace with "80"
  3. Save file and restart CF.
Tags: ColdFusion

Password Generator

If you ever need a quick random password, just visit:

Aside: I knocked this up in 30 seconds using dcRandomPass.

Free Query to Excel Function

generateExcel SampleI'm working on extending a system with excel reports so I knocked up a handy function that will turn any Query into an excel view.

Download


Syntax


The function generateQuery takes 4 arguments: the query, the columns, the mode and the filename. The syntax is:

generateExcel( theQuery, columnList, mode, filename  )

But you can call it with just the name of the query if you want, e.g.:

generateExcel( myQuery  )

Options


  • You can be specific about the columns:

    generateExcel( products, "productname, productCost" )

    The Column list argument allows you to specify the order you want the columns displayed in, or omit columns you don't want. If you want you can just leave it blank and it will just use the query column list - but the columns could be in any order.
  • There are 3 output modes: "display", "save" and "debug":

    generateExcel( products, "productId, productname, productCost", "save" )

    The default mode is "display".

    Mode "display": This will try to display the excel chart within the browser. If the end-user's browser does not allow this, Excel will launch and show the output instead.

    Mode: "save": This will just do a download and will not attempt to display within the browser.

    Mode: "debug": Will display the columns as a normal HTML page with <pre> tags.

  • The filename attribute allows you to specify the filename that the excel should be saved as. The default is "report.xls".

If you find this function useful, please just send me an email to say thanks peterATdigital-crew.com

Enjoy!

Update May 15 2007


I made some improvements yesterday - the code uses <cfcontent reset="yes"> so that it will reset the output before rendering the excel view and now supports exporting dates properly.
Tags: ColdFusion | Tools

My Lastest Masterpiece: ProFlashDownload

Cue Drumroll... my latest ColdFusion component is complete!

ProFlashDownload allows developers to make a list of files available for download to a user. These files will download with a progress bar and the developer can have a page called in the background when a file has completed downloading.

ProFlashDownload - Click for real demo

I was specifically asked to develop this component based on my existing work on ProFlashUpload.

Just like ProFlashUpload, ProFlashDownload is highly customizable, easy-to-use and easy-to-program.

Sidenote: You would think that Flash programming is browser-independent, but with this sucker, I had a bunch of issues with Internet Explorer causing all sorts of strange behaviour that I had to tediously program around.

Sidenote 2: It has been suggested that I combine ProFlashDownload and ProFlashUpload to make the mother of all web based file management utilities... and i'm considering it.

I'll be making this tag available for purchase at $50 on www.cftagstore.com in the coming days.

GZip Encode your CFML

There is an excellent article in the latest ColdFusion Developers Journal on how to enable GZip compression on your ColdFusion pages for free.
First, HTTP Compression is a great way to speed up your Website and lower bandwidth utilization all at the same time. In this example, your ColdFusion server (6.1 and above) will encode CFML output using GZIP and have the browser decompress this data on the fly. In a corporate environment, Webmasters may choose to go with third-party software such as Port80 Software's httpZip, which can compress other files as well, including .js, .css, and your HTML files. In this example, we are only compressing the generated HTML output from a .cfm template execution.

I just implemented it on one of our servers in 2 minutes. It reduced a 7Kb page to only 2306 bytes.
Date: Wed, 28 Mar 2007 23:01:45 GMT
Server: Microsoft-IIS/6.0
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip
Content-Length: 2306

200 OK
Tags: ColdFusion | Tips | WebDev

Image Gallery in 30 Seconds

How long would it take you to create an image gallery on your client's website?

Even using off-the-shelve scripts or purchased components, your probably still looking at an hours work, minimum, right? Maybe even a half-day or days work when you take into consideration the development of the administration section for the gallery.

How about reducing that time to 30 seconds?

With the plug-in architecture we developed for our in-house content management system, TeamworkCMS, you can! See for yourself...




Complete with administration. The database tables are created for you automatically when you install your first gallery. All aspects of the gallery including image size, thumbnail size and the CSS can be easily tweaked to suit your client's website.

This is just one of a myriad of page add-ons that we have developed.
Plug-n-play web development = saved time = money.

We will be releasing TeamworkCMS to the ColdFusion community FOR FREE in the coming weeks. BETA Testers wanted. Comments, feedback and suggestions would be great.

Topper Contributes to Open Source

I *think* this is the first time I have ever actually contributed to an Open Source project. Sure, I've given out free code, but I've never actually contributed to a community based software project until today.

I didn't want to have to use a CFX tag for image resizing anymore (even If I did make CFX_Jimage) so I tracked down Rick Root's ImageCFC.

In the project I was working on, I needed to create thumbnails that were exactly 90x90 with no whitespace from any size of source image. The source image could be any size.

To do this correctly, you need to figure out whether to resize on the X or Y axis, do so, then and clip off the remaining bit.

Figuring out the Axis to Resize on


You have to get the scale of the destination width over the current width and compare it to the destination height over the current height:

if( deltaX/currX < deltaY/currY ) then Resize on X Axis
else Resize on Y Axis

Then you have to clip the center piece of the remaining image:

        <cfset cropOffsetX = max( Int( (imgInfo.width/2) - (newWidth/2) ), 0 )>
        <cfset cropOffsetY = max( Int( (imgInfo.height/2) - (newHeight/2) ), 0 )>

It was a little tricky to get right (mainly because my brain was refusing to cooperate yesterday), but eventually I cracked it and it work's perfectly.

I submitted my new resizeBestFit function to Rick. Within a few short hours, he has integrated it nicely into the existing resize function and added an extra option, cropToExact.

ImageCFC Version 2.14 is available now. Cudos Rick.
Tags: ColdFusion | Tools | WebDev

Teamwork CMS Demo Online!

This weekend I got the thumb out and put the documentation website we build for our own documentation portal up on CFTagStore.com as a full product complete with CMS. As part of putting the product online, I also setup a working demo of the Portal and CMS.

 This is the first time that we have put a complete working demo of the latest version of our Teamwork Content Management System online for the general public to play with.

I invite you to log in and mess around with TeamworkCMS and then to let us know what you think:

The TeamworkCMS Demo is available here:
http://demos.digital-crew.com/documentationportal/cms/

Login with "admin" and password "admin".

You can view the pages you add or edit on the Demo Website here:
http://demos.digital-crew.com/documentationportal/

The database and codebase will reset automatically every 2 days (or when we get complaints that some Ejit has messed it up too much).

Prevent URL access to CFML include pages

Hackers can link directly to your ColdFusion include pages to bypass security or gleam information about the application from resulting errors.

For example, suppose you had 2 files - login.cfm and inc_success.cfm - the hacker could bypass the login.cfm and try to execute inc_success.cfm.
This is a bit of a strange example but I'm sure you get the idea.

There is a brilliant piece of logic in the Fusebox application.cfm file that prevents would-be hackers from directly accessing any CFML file other than "index.cfm". The code is blindingly simple and it goes a little something like this:
  1. <cfif right(cgi.script_name, len("index.cfm")) neq "index.cfm"
  2. and right(cgi.script_name, 3) neq "cfc">
  3.     <cflocation url="index.cfm" addtoken="no" />
  4. </cfif>

Regardless of what framework, if any, that you are using, I recommend adding this code to you application.cfm.

ps. Bear in mind that Ajax or flash movie calls to CFML pages will only be able to get data from pages named "index.cfm". Also any popup window pages must now be accessed through or named "index.cfm".

How to Beat Form Spam-bots

...without resorting to an annoying CAPTCHA.

Those bloody form spam bots were driving our clients crazy with hundred of bs emails arriving every day. I came up with this simple but effective method to beat these form spam-bots.

Part 1 - Duping New Bots


Warning: This method assumes needs JavaScript enabled and is thus not blah-blah compliant.

  1. Change the action of your form to "about:blank". (Remember the real action for later.) Robots indexing this will now go to "about:blank" instead of your action handler page.
  2. If your form has a JavaScript validation function, add this line just before the form is OKed or submitted:

    document.[form name].action = "[path to form handler page]"

    Otherwise just stick in something like this in the form:

    onsubmit="this.action='[Path to handler page here]'"

It's pretty simple, but since implementing this at the crew, we haven't encountered any robots smart enough to figure out that we are duping them with the about:blank. If the robots evolve, then so will we.

Part 2 - Blocking Old Bots (they're using Form Caching!)


Part 1 will prevent robots indexing your form action URL; but what about the robots who have already indexed your form and are storing the form details in their database? Here's how to block them:

  1. Add this line to your form:

    <input type="hidden" name="formSecurity" value="<cfoutput>#Hash( DateFormat( now(), "dd/mm/yyyy" ) & "YOUR_SECRET_KEY" )#</cfoutput>"/>

  2. In your handler page insert the following at the start:

    <!--- FORM SECURITY --->
    <cfif NOT isdefined( "FORM.formSecurity" ) OR ( FORM.formSecurity IS NOT Hash( DateFormat( now(), "dd/mm/yyyy" ) & "YOUR_SECRET_KEY" ) )>
        <cfabort>
    </cfif>

Tada! Your done. Welcome to zero-spam.
Alternative method: Cut the internet cable running out of Nigeria.

ColdFusion-alike List Functions for Javascript

Those ColdFusion list functions are pretty useful so I made a Javascript version of them. Enjoy.
Download
/* ColdFusion List Functions
   These functions manipulate lists just list ColdFusion does.
   (c) Digital Crew
   Happy Christmas. Knock yourself out.
   email: topper@digital-crew.com
   web: www.digital-crew.com   /   www.cftopper.com
*/
function listFind(c,n,d)
{
	if(arguments.length<3)d=",";
	var e = c.split(d);
	for(var i=0;i= 1 && p <= e.length )
	{
		return e[p-1];
	}
	alert("Out of range");
	return "";
}
function listSetAt(c,p,v,d)
{
	if(arguments.length<4) d=",";
	var e = c.split(d);
	if( p >= 1 && p <= e.length )
	{
		e[p-1] = v;//set the value
		//rebuild the string
		for( var i=0,c=""; i < e.length; i++ )
			c = (c!=""?(c+d):"")+e[i];
	}
	else alert("listSetAt: Index " + p + " is Out of range");
	return c;
}
function listInsertAt(c,p,v,d)
{
	if(arguments.length<4) d=",";
	var e = c.split(d);
	if( p >= 1 && p <= e.length+1 )
	{
		e.splice( p-1, 0, v );//insert the value
		//rebuild the string
		for( var i=0,c=""; i < e.length; i++ )
			c = (c!=""?(c+d):"")+e[i];
	}
	else alert("listSetAt: Index " + p + " is Out of range");
	return c;
}
function listLen(c,d)
{
	if( c == "" ) return 0;
	if(arguments.length<2)d=",";
	return c.split(d).length;
}

Good coding style #1: Use Whitespace

Coding readability is important! But only to to a degree - when people get religious on this issue I just zone out.

IMHO, if you have decided that you are a professional programmer, why not be the best programmer you can be. Try to evolve everyday. Look for things to learn. Improve, improve, improve. Get faster, learn the shortcuts. Every little time saver adds up.

#1 Use Whitespace

Which is easier to read, the first SQL statement or the second. Also most editors will allow the use of control-left, control-right to skip keywords with spaces between them but without the spaces, it skips the entire line.

There are basic examples, and as-such probably bad examples, when more code is involved the readability gets much harder when spaces aren't used.

SELECT moduletitle,modulelongtitle,moduleStatus,modulelevel
FROM modules
WHERE moduleId=#moduleId#
or
SELECT moduletitle, modulelongtitle, moduleStatus, modulelevel
FROM modules
WHERE moduleId = #moduleId#
 
Example 2:
html+='<option value="'+this.freqOptionVals[i]+'">'+this.freqOptions[i];

or

html += '<option value="' + this.freqOptionVals[i] + '">' + this.freqOptions[i];

You decide.

Tags: ColdFusion | WebDev

ColdFusion MX7 European Cost BS

Dear Macromedia Adobe, any chance you could stop raping us European customers.

ColdFusion MX7 Standard Edition pricing analysis

Price for Ireland:

American price:

Difference:

  • Inc. VAT: $672.48
  • Ex. VAT: $330.32

Your European price should be €1,035.87.
note: 1 USD = 0.797434 EUR 23 Oct 2006

Conclusion

<cfif $1,299 IS NOT €1,299>
       <cf_rape suckers="Europe">
</cfif>
Tags: ColdFusion

Tabs for UDI

Those of you familiar with my UDI product should be delighted to hear I've added tab functionality to the interface!

I've been working flat-out on a rush job for a local college and they wanted tabs so I bit the bullet and made tabs a feature of UDI. It's great when I can use paid work to extend one of my components.

Seen below is a screenshot if the tabs in action on this project. You can add as many tabs as you want, it's cross browser and it makes for nicer interfaces.

UDI now with Tabs

If anybody wants to email me directly I will send them on the latest version of UDI. Otherwise expect an update available on www.cftagstore.com within a week or two.

My Scorpio (ColdFusion 8) Wish List

OK OK, I know this has been done to death, but here is my 2c. I think a lot of the requested features from other developers wouldn't really benefit me on a day to day basis but here are some things I would find useful:

  1. Components that aren't just code - Build-in support for the something like dcCom architecture I came up with. This architecture allows 'components' to store image files, flash files, javascript file etc as parts of a 'component' and allow the component to easily be invoked. One component might be a visual Ajax-style file manager, another might be a sexual flash image gallery. Having build-in support for this level of code reuse with zero configuration would be outstanding! Components are often more that use a bunch of CFML files and that should be considered.
  2. CFImage - Even though I have made and sell online my CFX_JImage component, I would prefer to see comprehensive support for CFImage built into the ColdFusion runtime, no setup required. We need to be able to crop, resize, rotate etc images easily. This feature is very important for community websites or Content Management Systems that need to resize/modify images.
  3. Better reporting in the Administration - I want to see how much memory each application is consuming, which are the most used applications, how many sessions are in each, the request frequency, the load a given application is causing on the server, the load a given template is causing on the server, queries that are slow to execute and any other useful metric you can think of.
  4. Application Level CustomTags/Library - The CustomTags directory is often not used because it is way down there at C:\CFusionMX7\CustomTags and we want our applications nicely portable. How about allowing a "_lib" folder within an applications root to contain libraries, functions and CFCs which would then be automatically available within the application. With this, users would build, share, download and use useful libraries more readily.
  5. Advanced scheduled Tasks - others have commented about how schedule tasks can be mission critical for business related software and I tend to agree. We need scheduled task that are bulletproof and that will send a notification email if it fails. Also the executed code CFML should be able to notify the ColdFusion engine that everything went OK and this should be visible from within the ColdFusion administration.
  6. Code Lockdown and Redeployment - Many developers resell their products through sites such as www.cftagstore.com. At the moment the only way to lock-down your code to prevent dabbling is to encrypt it which of course can be easily decrypted.
  7. Upgrade CFML - Take the best 100 libraries on www.cflib.org and build them in.
  8. Better Local Variables - Allow a local variable in a function to be created anywhere inside in, instead of just at the top - it's a little thing that's quite annoying.
  9. Command-line execution - of CFCs and other correctly configured CFML files. This would make ColdFusion so handy for all sorts of one-time or maintenance tasks.
  10. Speed - Make ColdFusion even faster.
  11. Programmable caching - I wrote my own dcCache component for ColdFusion which i can programmable reset through a list of reset words. This type of functionality would be great to have build into ColdFusion. Limiting caching to time-spans simply isn't powerful enough.
  12. Inter-application communication - One application should be able to send a message to another application on the same-server without resorting to SERVER variables or HTTP requests.

And here are a handful of other feature requests, I scanned from other sites and agree with:

  1. Better management of whitespace.
  2. JDK 1.5 support.
  3. Deprecate cfscript.
  4. IMAP support
  5. Ability to throw objects rather than strings
  6. Syndication support - built-in RSS/ATOM tags.
Tags: ColdFusion

Tip: Use Local Variables for Queries in Recursive Functions

Groan, it's 1.06am and my ass is sore from sitting in this position. I've been trying to figure out what the hell is wrong with my recursive ColdFusion function that copies the structure of a site into a ColdFusion structure...

I was convinced that something was wrong with ColdFusion, hell I even went as far as downloading the updater for 7.01.

Then it struck me - maybe I also have to define the variable used with <cfquery> as a local within the function. I somehow assumed that a <cfquery> would automatically be local. One <cfset Var getSubPages2 = ""> near the rest of the local variables and it was fixed. Hours later. Sore Ass. Lesson learnt.

I think I'm a ColdFusion master Messing but this was a neat blow to my ego - I should have known that. Goodnight world.

Tags: ColdFusion | Tips

..Not the best 'Pages' Design in the World...

..oh no, this is just a tribute! This is the latest Digital Crew database design for storing website pages.

I have evolved this design over the years and I'm pretty happy with this result - this design supports multiple sites, page redirection, page short name (for navigation) and page long name, page HTML (for basic pages or intro text on complex pages), meta information, visibility, security, published status, alternative URLs, alternative files, making page for special (dynamic) processing and the ability to open the page in a new window.

Use it, if you like.

Design view of MySQL 'Pages' table

CREATE TABLE `pages` (
  `pageid` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `siteId` int(11) UNSIGNED NOT NULL DEFAULT '1',
  `pageparentid` int(10) UNSIGNED DEFAULT '0',
  `pageCode` varchar(50) character SET latin1 NOT NULL,
  `pageNavName` varchar(100) character SET latin1 NOT NULL DEFAULT '',
  `pageName` varchar(150) character SET latin1 NOT NULL DEFAULT '',
  `pageHTML` text character SET latin1 NOT NULL,
  `pageDisplayOrder` smallint(5) UNSIGNED NOT NULL DEFAULT '2000',
  `pageIsPublished` tinyint(1) NOT NULL DEFAULT '1',
  `pageDescription` varchar(255) character SET latin1 DEFAULT NULL,
  `pageKeywords` varchar(255) character SET latin1 DEFAULT NULL,
  `pageIsFolder` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
  `pageIsDynamic` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
  `pageIsVisible` tinyint(3) UNSIGNED NOT NULL DEFAULT '1',
  `pageIsLocked` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
  `pageAccess` enum('O','I','A') character SET latin1 NOT NULL DEFAULT 'A' COMMENT 'A=All, I=Logged In, O = Logged Out',
  `pageRedirectPage` varchar(50) character SET latin1 DEFAULT NULL,
  `pageAltFile` varchar(255) character SET latin1 DEFAULT NULL,
  `pageAltURL` varchar(255) character SET latin1 DEFAULT NULL,
  `pageOpenNewWin` tinyint(3) UNSIGNED DEFAULT '0',
  `pageShowOnInPageNav` tinyint(3) UNSIGNED DEFAULT '1'
  PRIMARY KEY  (`pageid`),
  KEY `pageparendId-pageId` (`pageparentid`),
  CONSTRAINT `pageparendId-pageId` FOREIGN KEY (`pageparentid`) REFERENCES `pages` (`pageid`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Tracking RSS Feeds

I was thinking that I'd love to have some sort of idea how many people are subscribed to this site.

The Solution

Solution 1: Some people suggest using a HTTP 301 Moved Permanently header to redirect RSS Readers to a unique URL that you can use to track the feed.

Solution 2: Others recommend that you display/make-available a unique RSS feed URL every time you display your blog.

The Problem

The problem with solution 1 is that RSS readers *should* remember that the page is permanently redirected - if they don't you'll get users always being redirected to unique URLs looking like unique subscribers all-the-time.

The problem with solution 2 is that it doesn't track your existing subscribers.

What I Decided to Do

I decided to combine both solutions and hope that there aren't too many stupid RSS readers out there. Now, If you browse to to rss/ you will be redirected to a unique URL.

Also when you view this page, both the RSS feed in the header and the feed displayed on the right hand side are unique.

The Code (in Brief)

For the redirect if URL.ref isn't defined, I used:

<CFHEADER statuscode="301" statustext="Moved Permanently">
<CFHEADER name="Location" value="#UniqueRSSURL#">

For the unique Id in the RSS URL I simply used:

replace(CreateUUID(),"-","","ALL"Wink

For logging to the MySQL RSSHits table I used:

<cfquery name="updateBlogHitCounter" ...>
INSERT INTO RSSHits(ref,blogId,hits)
VALUES (<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#ref#">,
<cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#URL.blogId#">,1)
ON DUPLICATE KEY UPDATE hits = hits + 1;
</cfquery>
Tags: ColdFusion | Tips

Source Control - 3 months later

For years we knew that we should be using source control. But we weren't. We didn't want the hassle of using source control.

But here's the thing: We make software components for ColdFusion. Some of these components are the cornerstones of our content management solutions which are in turn the cornerstone of our successful website and Intranet development business. In the past, when I made a change to UDI, a component for managing database content, I'd manually copy the code back to a central location. Then I would get the code again when starting a new project. The current version and change log were stored within the main.cfm file of each component. Painful.

What were we thinking?! About 3 months ago, I decided to take the bull by the horns and investigate the incredible complex, tedium world of source control. I got some manuals on Subversion and read a lot about CVS and source control systems. All pretty scary stuff to begin with.

But in truth, with the most excellent amazing fantastically brilliant TortoiseSNV extension for windows, source control is absolutely painless. Made changes? Just right click on the directory and select check-in, provide a short message and your done. Need the latest version, just right click and choose SVN Update. Wow, painless and simple.

And here is the thing I've come to notice, and it's a compelling reason to use source control - and not just because you should. You will be one hundred times more productive. How? You see, with the hassle of maintenance gone, I find myself making hundreds of little fixes and improvements all-the-time now.

If you make software and your not using some sort of proper source control, your officially living in the dark ages.

Tags: ColdFusion | Tips | Tools | WebDev

Chaos Blog Entry #1

OK, it's 12.16am on 4th September 2006.

I changed how projects work - I have removed most project tasks functionality from the dashboard - the logic being that somebody should really have a single project selected before things get more complex.

I updated the navigation with the list of projects. I succumbed to the argument with Dan and put the New Project link in the project list also. I'm thinking that only starred ie. active projects will appear in the main nav. To access long term projects and such, a "view other projects" link will be provided off the dashboard... or maybe in the navigation - yeah that'd make more sence... "more projects".

The goal is to keep this lightning speed like GMail - what I'm calling GSpeed. I've been analysing how GMail works and they have some pretty clever shit going on. They load an almost blank page when you click an email to open it - this makes it seem to the user that the browser is doing the usual loading thing with proper loading message and I imagine that it allows the app to track the user moving backwards and forwards in the app.

But I won't have GSpeed initially - Only the header and footer are being spat out from javascript at the moment. I want to get the functionality and tweaking and changing done right before I convert all the forms to script-based template loading - basically only raw data should ever be outputted for the main screens of the app.

I'm thinking that a top frame will hold the app keeping the URL constant. A middle frame will hold the primary data and the javascript files - preventing nasty updates-since server hits. The data frame will then load a current view data screen.

When adding a new task, I am fading out the background with a 50% transparent black "cover" div then displaying an absolutely positioned div with a higher z-index on top of it. It all works great except that the bloody cursor on the input text box ceases to work. Where I am at the moment, I don't have access to the Internet so I'll have to leave this for tomorrow nights work.

I would like to have absolutely no real hyperlinks in the application - i don't want users right clicking. At the moment, when a user hovers over a project, they get extra options appear - it allows for a nice, clean interface. At every turn I'm pausing and spending ages thinking about the design - should I remove the background color - should the star option be kept in the same place, what is the best way to list this, should this option be in a 'pop-up window' or inline? If it seems like a really simple application when I'm done, then I've achieved my goal. Definitely going to get different people to use it while I watch them and fix any issues before the first release.

For the first release, I plan to get the bare bones working - none of the niceties that Dan and Myself would love. For example there will be no sub-tasks in V1. Definitely something I want. But something we can live without for now. Also I would like to able to say, hey, "use this project as a template called X" and then users could select that template when creating a new project.

I think our app will be significantly easier to use and must faster that all the other pm apps out there. I really hope this is received well! Shit we still need a good name.

Progress has been slow. It's just me working on this so far and I have to fit this side-project in around my real job developing websites, maintaining and supporting our sites, tags and components.

Tags: ColdFusion

Rant Warning: Ruby on Rails Sucks

I think Ruby on Rails sucks. I'm sick of hearing about it.

I just watched all the videos at:

http://www.rubyonrails.org/screencasts

and i'm not excited. OK maybe "sucks" is extreme, but in fairness, it definitely is way over-hyped. It's nowhere near as great as it hype. Really!

One thing I will say, the documentation doesn't make RoR look like a piece-of-cake.

It's late - I'm too tried, lazy and inarticulate to make a decent argument so I'll leave it to the experts... just do a google search for "ruby on rails sucks". I just did... wow apparently I'm not the first to blog this exact opinion - people are sick of reading "yet-another-ruby-sucks-bait-post" so i'll shut up now.

But there, I said it. I'm happy now.

ColdFusion is a much better platform in my humble, biased opinion.

Update

Excellent - Joel shares my opinion.... and he's actually used it. And it makes interesting reading. Aside from all the hype, it looks like RoR ain't no smoking joe.

The solution is to stop playing and start over at the beginning and DO THINGS RIGHT THIS TIME, DAMMIT! Here is an actual entry from the Rails FAQ:

"Q012:That stinks... I want the scaffold code without starting over!

Too bad. Start a new rails project, run scaffold, then manually add the missing stuff to your new project from your old project with copy and paste."

Are we having fun yet?

Tags: ColdFusion | Rant

Finding the filename of the parent tag

Sometimes I've needed a custom tag to perform an operation on the actual code file that called it. However in coldfusion, there is no way (that I know of) to easily get the name or file path of the parent CFM file.

So I used to have to pass in the current file name like this:

<cf_someTag thisFile="#GetCurrentTemplatePath()#">

But yesterday, I cheated. When making the QueryWizard, I thought that the full list of executed templates is available and displayed when an error is thrown. Eureka! I simply throw a deliberate error within the tag, catch the error and extract the data I need like so:

<!--- Get the path to the caller template path by creating a
deliberate error and getting the path from the stack trace --->
<!--- I don't know of a better way! --->
<cfif NOT isdefined( "ATTRIBUTES.thisfile" )>
<cftry>
 <cfset abc = TheVarWontExist>
 <cfcatch type="Any">
  <cfset ATTRIBUTES.thisfile = cfcatch.tagContext[4].template>
 </cfcatch>
</cftry>
</cfif>

I know it probably won't work in everything (read:Bluedragon/CF5) so I still allow the attribute 'thisFile' to be passed, if required.

If there is a better way I am ignorant of, please educate me.

Tags: ColdFusion | Tips

CF_ProFlashUpload - Live at Last

I've finally released the flash upload component - the development of which I was blogging about here. Took a while for myself and Dan to come up with a good name. We were throwing all sorts of crazy ideas out there. Anyhow, please please go ahead and try it out. The demo is fully functional apart from a banner that asks you to purchase it.

I'm selling this baby for $50 per website - a fair price I think given the amount of work that went into this sucker.

What Is CF_ProFlashUpload? This widget creates a interface that allows your site user to easily upload multiple, even hundreds of files to your server. Each file has an individual progress bar and there is also an overall progress bar. The upload rate is also displayed.

 

The component allows you to use a multiple file upload component of any size as part of any ColdFusion application. It is extremely easy-to-use. You can call the component passing in just the upload directory and nothing else. Or you can use any of the advanced options to customise security options, file-type options and the look-and-feel of the component.

One of the nicest features of this component are per-file progress bars. The upload rate is also displayed along with the overall progress.

The demo is completely functional - just download it and you'll be up and running in minutes.

InfinityCMS Button for Google Toolbar

I'm just finished another small website project and it should be launched within a matter of days:

WebWorks Cork

But that's not the reason I'm posting this. Yesterday, I was searching for something completely different when I came across some pages on Google's site describing how to add your own custom buttons to the new Google BETA toolbar.

My imagination was captured (=all real work ceased Messing). An hour later (OK to be honest, about 3 hours later) and I had my very own icon for our own InfinityCMS Content Management System. Check it out:

Simply click this icon and it launches InfinityCMS

Installation: I added a page to our CMS system where the user can click a link to install this button in his/her Google Toolbar.

What Happens? Once clicked, the button sends the current URL to infinitycms.digital-crew.com. A ColdFusion page there checks the URL and performs a test to see if InfinityCMS is installed on that website.

If it isn't, the user gets a quick message displayed and is returned to where he/she was with history.back().

But if InfinityCMS is detected, a new window launches InfinityCMS and in the old window the user is again returned to where he was with history.back().

The Cool Bit: InfinityCMS is passed the URL of the page you were on when you clicked the icon... There are a series of regular expressions in the database (which can easily be updated in InfinityCMS by an administrator) that handle the request in a smart way...

For example, if the user was on the home page and clicks the icon, a window will appear allowing the user to quickly edit just the home page without all the other elements of the CMS solution:

InfinityCMS Quick Eidt Mode

And if there are several corresponding 'Quick Edit' options for a page, then the user will get a list of options. For example, on the following Quick Edit of the "Contact Us" page, the user can choose to edit the page or review messages from the contact form which have been logged in the database:

InfinityCMS Quick Edit of Contact Page - Options

Now that I've been using it for a bit, I find this little icon invaluable for making quick changes here and there. Of course if the user isn't logged into the CMS system, the login page appears first. I must add on the ability for the user to switch from Quick Edit more to full edit mode which looks like this:

InfinityCMS for WebWorks in Full Mode

Would love to know what you think of this little hack?

Update

I was giving a demo of this to Cormac and his popup blocker (Google Toobar - haha - the irony) was preventing the Quick Edit window from opening.

I remembered when the other day, GMail popped up a message for me saying that a popup blocker was blocking a window from opening so I knew it was possible to detect this. I did a bit of googling and it turns out it's pretty easy to detect:

<script language='JavaScript'>
<!-- <![CDATA[
function userHasPopupBlocker() {
var oWin = window.open('','child','width=50,height=50,status=no,resizable=yes');
if( oWin==null || typeof(oWin)=="undefined" ) return true;
else oWin.close();
return false;
}
//    ]]> -->
</script>

So now my script displays a friendly message asking to user to disable the popup blocker for the redirect site and "click here to try again". All working as it should again.

Flash Security Wrecking My Head

FFS, all I want to do is ask the license server if this component is OK to run on this website. My code was working perfectly from localhost - cummunicating perfectly with the licensing server but when I put it out in the real world, it couldn't get a connection.

Turns out Flash's security model is preventing loading data from another domain.

There are three methods (I've found so far) to allow the communication, but all of these require that the license server know who the requesting server is, in advance. So not too good for my needs then.

I think the WebService API might be able to get around this restriction... It's 2.18am however and that's another days work. This article looks positive...

http://www.adobe.com/devnet/flash/articles/flmxpro_webservices_03.html

MultiUpload Demo - 171 Files

Interesting to see that, since yesterday, users of this site have uploaded 171 files messing around with the Multiple Upload Demo.

Among the files are a plethora of interesting MP3s, excel sheets, PSD files and of course some porno - thanks Guys.

Whomever uploaded "film_ze_mucha_nie_siada.mpg" - that's just weird.

Updated Demo

I've updated the demo with a few more options and started updating the descriptions. I haven't tested all these options yet, so please let me know if you find a bug.

IE users, you may want to reset you cache as I updated the flash control and IE is brutal for not updating the cached version flash movies.

Some Minor Updates

I changed the names of some attributes such as "color" which is now "statusTextColor".

I also re-jigged some of the internal Flash default parameter coding to make the flash control smaller and more robust in that it can handle color codes in any of the following formats, "0xFF4466", "#FF4466" or just "FF4466".

It's all these little things that are delaying the launch but will ultimately make this incredibly easy-to-use and dummy-proof.