HOME | FERGUSON Digital Blog

CALLER Scope counting calls

ColdFusion · By Michael Ferguson No Comments »

A few years ago an update to Internet Explorer and "Active X activation issues" caused a bounding box to be displayed around all flash objects. I needed to come up with a solution to bypass the imposed requirement for customers to click on the OBJECT tag to activate.

I chose the SWFObject as a work around but it meant re-writing every page with a hardcoded fix. Not a good plan for a corporate web-presence that was at the very core of its mission execution.

Here is a link to SWFObject.

The solution was to design a custom tag that would detect which was the first SWF on the page and include the SWFObject call to load the JavaScript. Using the custom tag CALLER scope and counting how many times the custom tag is called per page, the code below adds the JavaScript on the first call and skips past each subsequent call. This way the page doesn't return multiple functions with the same name, reduces clutter, speeds up processing, and delivers content with control over the SWF attributes...all without hard coding pages.

<cfparam name="CALLER.cfFlashMX" default="0">
<cfparam name="ATTRIBUTES.FlashHeight" default="0">
<cfparam name="ATTRIBUTES.FlashWidth" default="0">
<cfparam name="ATTRIBUTES.FlashVersion" default="10.0.45.2">
<cfparam name="ATTRIBUTES.FlashColor" default="FFFFFF">
<cfparam name="ATTRIBUTES.FlashWMode" default="transparent">

<cfset CALLER.cfFlashMX=CALLER.cfFlashMX+1>
<cfif CALLER.cfFlashMX EQ 1>
   <script type="text/javascript" src="/Media/fnSWFobject.js"></script>
</cfif>

<cfoutput>
   <script type="text/javascript">
      var so#CALLER.cfFlashMX# = new SWFObject("#ATTRIBUTES.FlashFile#", "#ATTRIBUTES.FlashName#", "#ATTRIBUTES.FlashWidth#", "#ATTRIBUTES.FlashHeight#", "#ATTRIBUTES.FlashVersion#", "#ATTRIBUTES.FlashColor#");
      so#CALLER.cfFlashMX#.addParam("wmode", "#ATTRIBUTES.FlashWMode#");
      so#CALLER.cfFlashMX#.addParam("menu", "false");
      so#CALLER.cfFlashMX#.write("flashcontent#CALLER.cfFlashMX#");
   </script>
</cfoutput>


This example called SWFObject v1.5 when it was originally designed.

If you find this post useful please leave a comment and let me know how you used the information.

StructKeyExists vs IsDefined

ColdFusion · By Michael Ferguson No Comments »

I recently took over a corporate project from a team of ColdFusion Hobbyists. They had been performing code baby-sitting for the last couple of years and it was evident in the source code for their ColdFusion project. As you grow and learn more, your knowledge expands, you have more experiences, your perceptions change, and you receive insight or wisdom. Go back and examine old code. The longer a project sits in production, the more it requires updating. From day to day, especially across different versions of ColdFusion, there are bound to become better ways of performing actions faster, more secure, less tedious to manage, etc.).

Here is a problem that was inherited, the gratuitous over-use of IsDefined. I know, it's an old argument, but hold on tight because here we go again, yes StructKeyExists versus IsDefined. Simply put, StructKeyExists tests for a specific variable defined in a specific scope. IsDefined, without scope definition, will check for a specific variable as it searches through many different scopes. Here is the order of precedence IsDefined will take during the search:

  • VARIABLES
  • CfQuery
  • CGI
  • CfFile
  • URL
  • FORM
  • COOKIE
  • CLIENT

When you know exactly what scope you are testing for, StructKeyExists will always perform faster, except when using IsDefined for searching in the VARIABLES scope.

<cfset FORM.Test="ABC">
<cfset URL.Test="DEF">
<cfset VARIABLES.Test="GHI">
<cfif IsDefined("Test")>
   <cfdump var="#Test#">
</cfif>


The results will return the letters GHI, not because it was the last variable in the last scope defined, but because the VARIABLES scope is at the top of the list of precedence. If we had been testing for the existence of FORM.Test then we should have used IsDefined("FORM.Test"), but IsDefined will test its value against the other scopes anyway.

<cfif IsDefined("UserScope.Test")>
   Test 1
</cfif>
<cfif StructKeyExists(UserScope, "Test")>
   Test 2
</cfif>


This example will throw an error that Variable USERSCOPE is undefined for the StructKeyExists line because the scope is undefined in the search and IsDefined checked to see if it was VARIABLES.UserScope.Test and so on through the list. Even though you define the left side of FORM.Test as the scope, IsDefined will assume it to be a variable anyway if it can't find it in any scope. StructKeyExists fails in this example because the scope UserScope is undefined, which means the only scope it checked for is the one defined.

When the variable names become varied throughout a project, and it becomes difficult to always keep track of those used in one specific scope or the other, it would be easier for the programmer and faster for the page to execute to utilize StructKeyExists over IsDefined.

If you find this post useful please leave a comment and let me know how you used the information.

Append URL to FORM and FORM to URL

ColdFusion · By Michael Ferguson No Comments »

Ever need to quickly append the FORM scope to the URL scoped variables on a page or the other way around?ᅠ Dealing with FORM scoped variables is certainly cleaner in the browser address bar, but sometimes code reuse dictates that you revamp your design concept, rewrite your custom modules, or just append the URL and FORM scopes together and just get back to work.

Here is a fast way to combine both, but you could just use one or the other if you were simply targeting links or form results:

<cfscript>
   StructAppend(URL, FORM, "no");
   StructAppend(FORM, URL, "no");
</cfscript>

If you find this post useful please leave a comment and let me know how you used the information.

Outlook 2007 vCal

ColdFusion · By Michael Ferguson 4 Comments »

It's very easy to have ColdFusion send an email message to someone to tell them that they have an appointment. Turns out it's just as easy to have ColdFusion send out the actual Calendar appointment (in a corporate environment) directly into the Outlook Appointment Calendar.

To learn how the appointment is actually set, try making an appointment in Outlook (not Outlook Express) and save it as an ICS file. Then open the file with an ASCII editor of choice (notepad works just fine) and you will find all the parameters needed to slip into a CFMAILPART parameter. This example uses Outlook 2007 and will not work with POP3, only Exchange Servers.

The person receiving the email also receives an ICS file attachment which Outlook accepts as a valid calendar entry and makes the appointment. Now all you have to do is make them show up for the appointment!

<!---
#ATTRIBUTES.MailTo# = email address of recipient
#ATTRIBUTES.MailFrom# = email address of sender
#ATTRIBUTES.MailName# = name of recipient
#ATTRIBUTES.MailMessage# = email message
#ATTRIBUTES.MailAppoint# = brief description of appointment
#ATTRIBUTES.MailStart# = appointment start date (01/01/2010 12:00:00)
#ATTRIBUTES.MailStop# = appointment end date (02/02/2010 12:00:00)
--->


<cfset DTStartDate=DateFormat(DateConvert("local2UTC", ATTRIBUTES.MailStart), "yyyymmdd")>
<cfset DTStartTime=TimeFormat(DateConvert("local2UTC", ATTRIBUTES.MailStart), "HHMMSS")>

<cfset DTEndDate=DateFormat(DateConvert("local2UTC", ATTRIBUTES.MailStop), "yyyymmdd")>
<cfset DTEndTime=TimeFormat(DateConvert("local2UTC", ATTRIBUTES.MailStop), "HHMMSS")>

<cfmail to="#ATTRIBUTES.MailTo#" from="#ATTRIBUTES.MailFrom#" subject="Reminder (vCal)">
   <cfmailparam name="Disposition-Notification-To" value="#ATTRIBUTES.MailFrom#" />
   <cfmailparam name="content-class" value="urn:content-classes:calendarmessage" />
   <cfmailparam name="content-type" value="text" />
   <cfmailparam name="method" value="request" />
   <cfmailparam name="charset" value="utf-8" />
   <cfmailparam name="content-transfer-encoding" value="7bit" />
   <cfmailpart type="text">#ATTRIBUTES.MailMessage#</cfmailpart>
   <cfmailpart type="text/calendar">
<!--- Do NOT Indent This Part --->
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
BEGIN:VEVENT
DTSTART:#DTStartDate#T#DTStartTime#Z
DTEND:#DTEndDate#T#DTEndTime#Z
TRANSP:OPAQUE
SEQUENCE:0
UID:#CreateUUID()##DateFormat(Now(), "yyyymmdd")##TimeFormat(Now(), "hhmmss")#
DTSTAMP:#DTStartDate#T#DTStartTime#
DESCRIPTION:#ATTRIBUTES.MailName# on #ATTRIBUTES.MailStart# until #ATTRIBUTES.MailStop#
SUMMARY:#ATTRIBUTES.MailAppoint# Appointment
PRIORITY:5
X-MICROSOFT-CDO-IMPORTANCE:1
CLASS:PUBLIC
END:VEVENT
END:VCALENDAR
</cfmailpart>
</cfmail>

If you find this post useful please leave a comment and let me know how you used the information.

CamelCase

ColdFusion · By Michael Ferguson 2 Comments »

I like standardization, in naming conventions, file organization, and especially in variable and record set usage.ᅠ My prefefred method of programming is to use "CamelCase" which is just typing compound words with the first letter of each word capitalized.ᅠ What I find in ColdFusion is slightly lazy.ᅠ For example "isDefined" should be "IsDefined" to be camel case.ᅠ The built-in functions in ColdFusion skip capitalizing the first letter in the compound word.

I don't like wasting time when a customer needs immediate results, with trying to scan through several hundred lines of code and discern the difference between thiscompoundword, thisCompoundWord, ThisCompoundWord, and this_compound_word while intermingled with other functions and variables that don't adhere to a standard.

These variations do not affect the ability of ColdFusion, they merely reflect the broken thought processes behind the author who types the mish-mash.ᅠ The first three in the example above will work exactly the same in ColdFusion.ᅠ When I teach ColdFusion to new programmers, I stress the importance of case sensitivity in file names.ᅠ The file "index.cfm" and "Index.cfm" are the same files in Microsoft, but are two different files in Linux.ᅠ The lesson continues with not stopping with the naming convention of the files, other than if you are going to capitalize the first letter of the file name then do the same for every file in the project.

Then there is the underscore.ᅠ Actually, I hate the underscore in programming.ᅠ First, it's an extra character in the compound word, which is clutter, which is contradictory to efficiency.ᅠ Second, I can't double-click on it with the mouse while editing with SQL Server Management Studio and select the entire entry!ᅠ To prevent accidently typing the right word incorrectly, there is a lot of double-clicking, copying, and pasting during the creation process for me.ᅠ The underscore causes each word of a compound name to be treated as an individual element in word processors and SQL Studio.ᅠ Dreamweaver (my IDE of choice) doesn't seem to care.

To prevent having to divide their attention between the two processes (CamelCase with Dreamweaver and under_score with SQL Studio), my students are encouraged to stay within one standard that fits into all aspects of ColdFusion programming.ᅠ This practice doesn't just stop with CFM and SQL, but extends to include JS and CSS as well.ᅠ Camel Case works perfectly throughout the project as a clean, efficient standard.

If you find this post useful please leave a comment and let me know how you used the information.

© Copyright 1997-2024, All Rights Reserved Coldfusion and MS SQL2008
Powered by Mango Blog.   Design by FERGUSON Digital