HTML Formatter ColdFusion-friendly code cleanup tool

No matter how clean your code, there's something to be said for a fast, clean pre-launch cleanup with a reliable code formatter . My favorite by far is the HTML Formatter from LogicHammer.com:  http://www.logichammer.com/html-formatter/

Complete with a full set of ColdFusion-friendly options, this simple tool makes cleaning your code a snap. I use it as I'm working, to clean up the work-so-far at any point, and before final launch to make sure the production code will be as easy as possible to maintain and revisit later on. It is a standalone executable, which means there's no installation, and you can put in anywhere you like on your hard drive.

I simply create a taskbar shortcut on my Windows PC and drag the files I want to clean directly from the 'project' view in Eclipse onto the icon - couldn't be faster, simpler or easier. I prefer to have my original files altered, with the originals automatically put in a specified backup location - you can also assign the option to leave the original alone and create a cleaned-up copy.

Among other fav features, HTML Formatter ships with a simple text-based config file which makes it incredibly easy to specify tags to ignore or to indent, and file extensions to be formatted or skipped ( you can run the formatting on specific files, or an entire directory).

For only $14.99 you get all the features and 2 years of updates (there is also an 8.99 version with a basic feature set). The program's developer has answered every question I ask directly and has been very helpful with customizations, even building in some features I requested a while back (for the record - I'm not affiliated with logichammer in any way, just very pleased with this slick little tool).

How to find lowercase (no caps) values in mySQL (and Capitalize them with ColdFusion)

I have a request from a client to help clean up some customer-entered data in a mySQL database, specifically, we need to capitalize all of the values in a column called 'user_city'

For the actual capitalization, I am using the very handy CapFirstTitle() function from CFlib : http://www.cflib.org/index.cfm?event=page.udfbyid&udfid=116

But first, I need to find all of the entries that are not already capitalized. This dataset has tens of thousands of records , including some with a blank value in the 'city' field - no need to loop all of that just to fix our caps!

So, here's the SQL query code to find all of the records with no capital letters at all, by comparing to a lower() all lowercase version of the same value:


SELECT user_city, ID
FROM site_users
WHERE user_city = lower(user_city)
AND NOT user_city = ''
ORDER by user_city

And here is the full CFoutput / CFquery code for the loop and update with Coldfusion, and the CapFirstTitle() function in the head of the page:


<cfoutput query="myQueryAbove">
    <cfquery datasource="#application.dsn#">
    UPDATE site_users
    SET user_city = '#capFirstTitle(myQueryAbove.user_city)#'
    WHERE ID = #myQueryAbove.ID#
    </cfquery>
</cfoutput>

for other columns you could use OR in the first query and an additional statement in the second, or just change the queries, run the page again, or even, make the column name a variable and just change it once in the head of the page... easy.

Show any Twitter Feed on your site with ColdFusion and CFFEED

This is so simple, I'll let the comments do the 'splainin:



<!---
start CF Twitter Feed
--->


<!--- SET THE URL: add your username instead of mine --->

<cfset feedurl="http://search.twitter.com/search.atom?q=from%3Agowestweb" />

<!--- CFFEED does all the work --->

<cffeed
source="#feedurl#"
properties="feedmeta"
query="feeditems"
overwrite="true" />


<!--- CFOUTPUT shows the feed like a query --->

<ul class="tweet">
<!--- change maxrows to suit your layout --->
<cfoutput query="feeditems" maxrows="3">
<li>#content#</li>
</cfoutput>
</ul>

<!---
end CF Twitter Feed
--->


<!---
NOTE: in addition to #content#, you can show date and other columns related to each feed item.
Use <cfdump var="#feeditems#"> to see all the available columns in the query
--->



ColdFusion Form Spam Prevention: CF Meetup Notes and Follow-Up

Thanks to all who attended my first CF Meetup presentation.

Info: http://www.meetup.com/coldfusionmeetup/calendar/11596049/?a=nr1p_grp&rv=nr1p

Recording: http://www.meetup.com/coldfusionmeetup/pages/Recordings_of_the_ColdFusion_Meetup-2009/

Demo Page (as seen in the presentation): http://www.gowestwebdesign.com/demos/contact-form/index.cfm

As far as I can tell we had a good turnout, and though talking to a silent connection takes some getting used to, the live-chat comments and interaction during the talk really made it fun (and helped me fill the full time slot with this simple subject!).

I really enjoy meeting other developers and designers, and I hope anybody who attended, had questions or just wants to get more involved in the community will drop me an email, check out our web developer newsgroups (see the link top right of this blog), and of course... be my Facebook and/or Twitter friend.

Thanks also to Charlie Arehart for all of his efforts keeping the CF Meetups going, and growing strong. He was the perfect balance of aggressive and encouraging in getting me to present this topic, and I am very glad he persisted. He's definitely the right guy for the positing of CF Host and quickly removed any concerns or worries I might have had just before we went live.

Now that it is done, I would like to do another! On that note, if there is anything you think I know about, that you'd like to see me share, please do drop me a line.

Several people asked to have a copy of the code used in the presentation. The sample below is directly from the file shown in the demo.



<!--- START PROCESSING --->
<cfif isDefined('form.senderFrom')>

<!--- VALIDATE FIELDS --->

<!--- check email --->
<cfif NOT len(trim(form.senderFrom)) gt 6 or NOT isValid('email',form.senderFrom)>
<cfset request.formError = 'A valid email address must be provided'>

<!--- message --->
<cfelseif NOT len(trim(form.senderMessage))>
<cfset request.formError = 'Be sure to include a message'>

<!--- honeypot --->
<cfelseif len(trim(form.email_address))>
<cfset request.formError = 'Spam!! <br />(Run away! Run away!)'>
</cfif>

<!--- /end VALIDATE FIELDS --->

<!--- CHECK FOR UNWANTED CONTENT--->
<!--- loop all form variables --->
<cfloop index="f" list="#form.fieldnames#">
<!--- set variable for field value --->
<cfset value="#evaluate('form.#f#')#">

<!--- BANNED WORDS --->
<cfset bannedWordsList = "herring,albatross,dragon,grail,lumberjack">

<!--- loop the banned words list and see if we have a match --->
<!--- Check for banned words --->
<cfloop list="#bannedWordsList#" delimiters="," index="w">
<cfif FindNoCase(w,value)>

<cfset request.formerror="<br />Beg your pardon? <br />Your WHAT hurts?">

<cfbreak>
</cfif>
</cfloop>
<!--- / end BANNED WORDS --->

<!--- HTML BLOCK --->
<cfset leftChar = '<' >
<cfset rightChar = '>' >

<!--- look for both characters contained in our content --->
<cfif findNoCase(leftChar, value) AND findNoCase(rightChar, value)>
<cfset request.formerror = "Text only please - no HTML">
<cfbreak>
</cfif>
<!--- / end HTML BLOCK --->

</cfloop>
<!--- / end CHECK FOR UNWANTED CONTENT --->

<fieldset>
    <legend>
        <cfif isDefined('request.formerror') and len(trim(request.formerror))>
        Error!
            <cfelse>
        Thank You
        </cfif>
    </legend>

<!--- SHOW RESPONSE --->
<cfif isDefined('request.formerror') and len(trim(request.formerror))>
<p><strong>ERROR: <cfoutput>#request.formerror#</cfoutput></strong></p>
<p>Go <a href="javascript:history.back()">back</a> and try again</p>

<cfelse>
<p>Thank you. <br /><br />Your message has been sent and we will reply soon!</p>
</cfif>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
</fieldset>

<!--- IF FORM NOT SUBMITTED (show the form) --->
<cfelse>

<fieldset><legend>Sample Contact Form</legend>

<cfform name="contactForm" action="#cgi.SCRIPT_NAME#" method="post">
<div>
<label for="senderName">Name:  </label><cfinput type="text" name="senderName" size="48" value="" required="true" message="Your Name is required">
</div>
<div>
<label for="senderFrom">Email:  </label><cfinput type="text" name="senderFrom" size="48" value="" required="true" validate="email" message="Email Address is required">
</div>
<div>
<label for="senderPhone">Phone:  </label><input type="text" name="senderPhone" size="20" value="">
</div>
<div>
<label for="senderPhone">Your Message:</label><textarea name="senderMessage" cols="30" rows="12" style="width:310px;"></textarea>
</div>
<div style="text-align:center">
<input type="submit" value="Submit">
</div>

<div id="email_wrapper">
<input type="text" name="email_address" value="" size="20">
</div>

</cfform>

</fieldset>

</cfif>
<!--- / end IF FORM SUBMITTED --->

Thanks again to Charlie and everyone else - this has been a very positive and rewarding experience, and I hope to return with more good CF-Stuff to share.

Come to my (first) CF Meetup: Captcha-Free Spam Prevention for ColdFusion Forms

Tired of Spam? (Who isn't?)

No matter how good our filters are, or how careful we may be about making our email addresses publicly accessible, some of the nasty stuff still gets through.

But there is a way to fight back, defending your websites' contact forms and other form-to-email inputs, without making your website visitors jump through extra hoops, solve puzzles or read fuzzy scrambled letters (captcha) just to drop you a note.

To learn more, tune into my ColdFusion Meetup presentation this Thursday, October 15, 2009. (If you haven't yet attended the CF Meetup, this is a good time to start!)

Details here: http://www.meetup.com/coldfusionmeetup/boards/view/viewthread?thread=7841126

The live meetup will be here: http://experts.acrobat.com/cfmeetup/

Recording will be posted here: http://recordings.coldfusionmeetup.com/

See you at Noon Eastern (10am here in Utah) on Thursday, October 15 !

How to use the CFEclipse Scribble Pad as a fast and easy ColdFusion sandbox

Like most developers I know, I'm always checking functions, testing little changes and trying to find just the right syntax for certain bits and blocks of code. Every project usually ends up with a 'test.cfm' file, which gets written and overwritten with all sorts of little snippets, queries, and other scribbly things, then deleted. To use the test file, I open it like any file in my editor, make changes, then load that page's local url in the browser, refresh, repeat... not bad, it works... but I just discovered something much better!

Thanks to Mark Esher's MX Unit blog post about the CFEclipse Scribble Pad , I've now got a one-click (or one key, F8) instant sandbox to scribble whatever I like, across all projects in my Eclipse workspace. Launching the CFEclipse scribble now (F8) causes 2 things to happen automatically: my 'scribble.cfm' file (stored in a _temp project in my workspace) opens for editing, and the Eclipse browser view (which I seldom use otherwise but is perfect for viewing little bits, cfdumps and snippets) pops up, showing me the rendered output. Very nice.

It isn't just saving the clicks, but saving the thought process. While coding, the distraction of stopping, making a temp file, going to that file in the browser.. every step takes my mind further off of the super-intensive outrageously-important totally-impressive thing I was doing when I decided I needed to scribble in the first place.

Setting it up was easy - just follow the directions : http://blog.mxunit.org/2009/04/timesavers-cfeclipse-scribble-pad.html . This is another perfect example of the powerful, practical tools and timesavers that hide behind a previously-unnoticed menu option or toolbar icon - and though one of the simplest, I have no doubt this will be among my most-used commands when working in Eclipse!

 

Add Leading Zeros to a Numeric Value with ColdFusion

ColdFusion's numberformat() allows for the use of '_' (underscore) or '9' as a placeholder in a numeric mask. But these do not add a leading zero to non-decimal values. ( If the number contains fewer digits than the mask, you get the truncated number without any zeros on the left side).

In some cases, however, you want those zeros. The super-simple CF solution? Use a '0' as the mask character!


<cfset theNumber = "1287">
<cfoutput>#NumberFormat(TheNumber, "000009")#</cfoutput>

This returns 001287


<cfset theNumber = "1287">
<cfoutput>#NumberFormat(TheNumber, "999999")#</cfoutput>

This returns 1287

Get the recordcount of a ColdFusion update, insert or delete query using CFquery result attribute

When you run a cfquery using SELECT, the number of records returned is easy to find using #queryname.recordcount# - but what about the other types of SQL queries, our good friends Update, Insert and Delete ? Those query types don't return a total of rows in the same way.

But there's an easy solution ... once again, we can use 'recordcount', but in this case it is a node of the 'result' variable as defined in our cfquery tag.



<cfquery datasource="#request.dsn#" name="saveChanges" result="updateResult">
UPDATE table_name
SET
column1 = '#value1#',
column2 = '#value2#'
WHERE column3 = 1
</cfquery>

<cfset recordsChanged = updateResult.recordCount>

That query is just a sample, you could have any 'where' statement, values, etc... but notice the "result" attribute of the cfquery tag, which will accept any variable name you want to use. Then, immediately following the query code, we simply get the 'recordcount' node of the result structure, and we have the number of updated records from the query.

( Note: this example is for mySQL - ymmv with other db types)

Get the ID of a newly created record from a ColdFusion insert query using CFquery result attribute

When inserting a new row to a mySQL database table using <cfquery>, it is often necessary to find the ID of the new record so you can refer to it in subsequent queries or other code further down the page.

There are a few ways to do this, but I like this one best:



<cfquery name="insertRecord" datasource="#request.dsn#" result="insertResult">
INSERT INTO my_table
(
column_1,
column_2,
etc
)
VALUES
(
'#value1#',
'#value2#',
'etc'
)
</cfquery>

<cfset newID = insertResult.generated_Key>

Notice the "result" attribute of the cfquery tag, which will accept any variable name you want to use. Then, immediately following the query code, we simple get the 'generated_Key' node of the result value, and voila - we have the ID of the new record, ready for whatever is needed next.

(Note: This example is for mySQL - not sure how this plays out in MS SQL or other DB engines... your mileage may vary.)

Verify remote images exist - prevent missing images with CFHTTP

I am creating a photo gallery where the images actually reside on a third-party service. To prevent 'blank' or missing images from showing up in my html gallery markup, I needed a way to verify the remote image actually exists before including it into the dynamic markup.

This seems to work quite nicely:



<cfoutput query="myImageQuery">

<cfset imgURL = "http://remotesite.com/images/#imageFilename#">
<!--- check for the image via cfhttp:
Note:'head' method gets only headers, which is all we need (thanks @ScottP) --->

<cfhttp url="#imgURL#" method="head">    
<!--- isolate the 'mimeType' value from the cfhttp results --->
<cfset myStatus = cfhttp.mimeType>
<!--- if the mimeType is jpg (jpeg), include the image in our output --->
<cfif myStatus eq "image/jpeg">
<img src="#imgURL#" alt="#imageTitle#">
</cfif>

</cfoutput>

Add alternate pricing option to Cartweaver

A Cartweaver user asked how he can add alternate pricing to his Cartweaver ecommerce site. He was understandably concerned about the need to edit the database, and how much code editing might be involved. But if you take a systematic approach, it is pretty straightforward.

The first part of setting up any alternate pricing system is to get that info into your database and admin, so you can work with it. In this case, since the basic goal is to duplicate the existing 'price' system, that is exactly what we are going to do.

more...

More Entries

blogcfc 5.9.1.002 by raymond camden
contact michael evangelista