Beware of Implicit Structs Bug in ColdFusion 9,0,1

This has been driving me nuts and I'm not sure how well documented this is, but I've stumbled across a bug in ColdFusion 9,0,1,274733 where implicit structs can end up as 'undefined' and crash your application.

I was working through an example from jQuery in Action, Second Edition (you know, because I was trying to figure something else out) when this happened to me again and I thought I would go ahead and share a simple way for others to test and let me know if it's happening to them.

Create a page called test.cfm and drop this code in it, point your browser to it and you'll probably see an error of 'Variable TERMS is undefined'.


<cfscript>
    if ( not IsDefined('term') ) {
        term = 'unknown';
    };
    term = lcase(term);

    terms = {
        'oil-tanned' = 'A method of leather tanning in which oils or fats are used to cure the leather. Such leather is usually very supple and has a matte or "oily" finish and is not generally polishable.',
        'full-grain' = 'Leather which has not been altered beyond hair removal. Full-grain leather is the most genuine type of leather, as it retains all of the original texture and markings of the original hide.',
        'vibram' = 'A brand of boot and shoe sole created by Vitale Bramani in the 1930s, orginally for climbing boots. They are easily identified by the distinctive yellow Vibram® octagon. The Vibram® brand is recognized worldwide as the leader in high performance soling products for outdoor, dress casual, and service footwear.',
        'goodyear welt' = 'The Goodyear welt is a method of attaching the sole of a shoe to the upper that is hand-stitched and allows multiple sole replacements, extending the life of the footwear.',
        'cambrelle' = ' A non-woven synthetic fabric used primarily as a lining for shoes, boots and slippers.',
        'cordura' = 'A certified fabric from INVISTA used in a wide range of products from luggage and backpacks to boots, to military wear and performance apparel. Cordura® is resistant to abrasions, tears and scuffs.',
        'gore-tex' = 'A water-proof and breathable fabric that offers superior insulating abilities in a light-weight fabric.',
        'stitch-down' = 'A method of boot construction that helps seal the boot against dirt, mud, and water and maximizes flexibility.',
        'unknown' = 'Unknown term.'
    };
</cfscript>
<cfoutput>#terms[term]#</cfoutput>

The funny thing is, if I move the code at the top of the page below the implicit struct, the page loads fine! Here's some code that should work now:


<cfscript>    
    terms = {
        'oil-tanned' = 'A method of leather tanning in which oils or fats are used to cure the leather. Such leather is usually very supple and has a matte or "oily" finish and is not generally polishable.',
        'full-grain' = 'Leather which has not been altered beyond hair removal. Full-grain leather is the most genuine type of leather, as it retains all of the original texture and markings of the original hide.',
        'vibram' = 'A brand of boot and shoe sole created by Vitale Bramani in the 1930s, orginally for climbing boots. They are easily identified by the distinctive yellow Vibram® octagon. The Vibram® brand is recognized worldwide as the leader in high performance soling products for outdoor, dress casual, and service footwear.',
        'goodyear welt' = 'The Goodyear welt is a method of attaching the sole of a shoe to the upper that is hand-stitched and allows multiple sole replacements, extending the life of the footwear.',
        'cambrelle' = ' A non-woven synthetic fabric used primarily as a lining for shoes, boots and slippers.',
        'cordura' = 'A certified fabric from INVISTA used in a wide range of products from luggage and backpacks to boots, to military wear and performance apparel. Cordura® is resistant to abrasions, tears and scuffs.',
        'gore-tex' = 'A water-proof and breathable fabric that offers superior insulating abilities in a light-weight fabric.',
        'stitch-down' = 'A method of boot construction that helps seal the boot against dirt, mud, and water and maximizes flexibility.',
        'unknown' = 'Unknown term.'
    };

    if ( not IsDefined('term') ) {
        term = 'unknown';
    };
    term = lcase(term);
</cfscript>
<cfoutput>#terms[term]#</cfoutput>

If I'm doing something wrong, please don't hesitate to point it out to me. Thanks!

How to Force Mura CMS to Use Primary Domains in SEO-Friendly Way

Mura CMS allows you to have multiple URLs assigned to each particular site. For example, you could have http://domain.com be your 'primary' domain and http://www.domain.com and http://www.anotherdomain.com set up as 'domain aliases' so that when you navigate to any one of these domains, Mura will serve up the desired site. This is pretty cool actually and there are a number of use cases out there on why you would want that to happen. However, if you want the 'primary' domain to be the one and only one used for SEO purposes and such, then you'll need to make just a couple of minor tweaks to make that happen. The best part is, I'll show you just how easy this is!

The first thing you'll need to do is copy the following method into your local contentRenderer.cfc. It's located at /{siteid}/includes/contentRenderer.cfc (or if you want this to be 'theme-specific' then edit the one located at /{siteid}/includes/themes/{themeName}/contentRenderer.cfc).

<cffunction name="doEnforceDomain" access="public" output="false" returntype="any" hint="By default, I will redirect users in an SEO-friendly way to your primary domain ... you may optionally override this by giving me an alternate 'primary' domain to enforce.">
    <cfargument name="domain" required="false" default="#$.siteConfig('domain')#" />
    <cfscript>
        var local = StructNew();
        local.doRedirect = false;
        local.servername = getPageContext().getRequest().getServerName();
        if ( local.servername neq arguments.domain ) {
            local.doRedirect = true;
            local.servername = arguments.domain;
            local.baseurl = getPageContext().getRequest().getScheme() & '://' & local.servername;
            // if not using a standard port, we should prolly include it
            local.port = getPageContext().getRequest().getServerPort();
            if ( local.port neq '80' and local.port neq '443' ) {
                local.baseurl = local.baseurl & ':' & local.port;
            };
            // uri returns '/index.cfm/path/to/page/'
            local.uri = getPageContext().getRequest().getRequestURI();
            local.urlstr = local.baseurl & local.uri;
            // append query string, if any
            if ( len(trim(getPageContext().getRequest().getQueryString())) ) {
                local.urlstr = local.urlstr & '?' & getPageContext().getRequest().getQueryString();
            };
        };
    
</cfscript>        
    <cfif local.doRedirect>
        <cflocation url="#local.urlstr#" addtoken="false" statuscode="301" />
        <cfelse>
        <cfreturn />
    </cfif>
</cffunction>

The last thing you'll need is an itsy-bitsy, teeny-weeny line of code that can actually be dropped in a number of different places. More on that in a second. However, if you want your entire site to always use the primary domain, then drop the following line of code into your local eventHandler.cfc in the onRenderStart() method. This is located in the same locations as the contentRenderer.cfc.

<cffunction name="onRenderStart">
    <cfargument name="$" />
    <cfset $.getContentRenderer().doEnforceDomain() />
</cffunction>

Remember how I mentioned you could drop this in a number of different places? Well, let me explain. Let's say you have an area of the site that uses a particular template and you want ONLY that area of the site to use a specific domain...for example 'http://docs.domain.com' for a documents area. Well instead of using the eventHandler.cfc route, you could just drop this at the top of the template and then anytime someone visits this area, they'll get re-routed properly and in a SEO-friendly manner. Isn't that sweet?

<cfscript>
    $.getContentRenderer().doEnforceDomain('docs.domain.com');
</cfscript>

As always, I hope this helps!

Cheers!

cf.Objective() 2011 Pricing Announced

Yo! ColdFusion peeps! It's hard to believe it, but cf.Objective() 2011, the world's only enterprise engineering conference for ColdFusion, will be here before you know it. The conference will be held in sunny downtown Minneapolis, MN and runs May 12-14, 2011. In fact, pricing has just been announced and is available on the cf.Objective() web site. Oh, and register by February 14th, 2011 and save an extra $100!

So, when you prepare your budget for next year, if you haven't already done so, don't forget to include cf.Objective() 2011.

Hey, CFUnited Attendees ...

If you have EVER been an attendee of CFUnited, you are eligible for a $100 Alumni Discount! How cool is that?

Vote Now!

While you're at it, tell cf.Objective() what you're interested in learning about by completing a brief Topic Suggestion Survey >>

Hope to see you there!

More Entries

© 2026, Stephen J. Withington, Jr.  |  Hosted by Hostek.com

Creative Commons License   |   This work is licensed under a Creative Commons Attribution 3.0 Unported License.