Gregory's Blog

Extending Application.cfc's using mappings and proxies

One of the most frustrating things that I have had to deal with in ColdFusion is trying to create an external application that is open to the general public and having to secure a portion of that site with an application within a subfolder and extending the logic from base application.cfc. I'll walk you through the current approach that developers use to solve this as well as showing you how to additionally use mapping when there may be a hosting provider that uses virtual directories.

This is a rather long article, if you want to jump to the condensed summary, scroll down to the bottom of this page.

Many years ago, the first time that I tried to perform this, I received the following message no matter what I tried: "Could not find the ColdFusion component or interface xxx'. In a nutshell, the problem using this approach is that both the root and the subfolders have the same name, i.e. Application.cfc, and ColdFusion can't properly identify what component to extend. Finally, after some serious investigation, someone came up with the idea to create a proxy.cfc that resides in the same root directory as the root Application.cfc, and the Application.cfc in the subfolder extends an empty proxy.cfc that extends the root cfc like so:


root directory: Application.cfc
This root Application.cfc does not extend anything


Also in the root directory: Proxy.cfc
Proxy.cfc has the following code, it's essentially empty. The only thing that the Proxy.cfc does is to extend the Application.cfc that is in the same directory:
view plain about
1<cfcomponent extends="Application">
2</cfcomponent>


Subdirectory such as a folder named admin.
This subdirectory has another Application.cfc. Let's say that this component is responsible for securing the application and has login logic as well as debugging settings for example. This Application.cfc will extend the Proxy.cfc to gain the methods and properties of the Application.cfc in the root directory like so:
view plain about
1<cfcomponent displayname="Admin" extends="Proxy.cfc">
2<!--- Lots of code --->


This approach was a godsend and it was heavily blogged about. Ben Nadel has made a number of very helpful posts which I will share at the bottom of this article.

This works quite well unless you're on a hosted domain or a server that uses virtual directories. In this case, we are in the same original boat in which we started from. Now we are back into the "Could not find the ColdFusion component or interface xxx' hell!

There is a solution for this tricky problem though, we need to also use mapping!

It is a common misnomer that you can't use mapping to extend components. I am not quite sure where this misconception originally came about, but it has been proven that this is just not true. There are occasions where we must use mapping to solve some annoying problems, like here.

This particular site is hosted by hostek.com. They are a fine company to deal with, but the server that my site is hosted on has some idiosyncrasies due to the directory structure. Here, when I use the Proxy.cfc method to extend the logic from the base Application.cfc to the Application.cfc in the admin folder I receive the dreaded 'could not find the ... component' error. When I first saw it I was dismayed thinking not this again, so I turned to ColdFusion CFC mapping. Mapping tells ColdFusion where to find the file and what the file relationships are.


Let's review CFC structure that was just discussed. For example, imagine the following directory structure:

root directory: i.e. www.gregoryalexander.com/
subdirectory: www.gregoryalexander.com/admin/

As discussed, we have an Application.cfc and the Proxy.cfc in the root directory, and we have the Application.cfc in the 'admin' subdirectory. The Proxy.cfc extends the Application.cfc, also in the root directory, and the Application.cfc in the subdirectory (admin) extends the Proxy.cfc in the root directory.

root directory: contains both Application.cfc and Proxy.cfc (that extends the root Application.cfc).
subdirectory: Application.cfc (that extends Proxy.cfc).

Now we need to also add the following mapping in the root Application.cfc. This mapping logic should be near the top of the root Application.cfc, and it should not be within any of the Application.cfc event handlers (onApplicationStart, onApplicationRequest, etc). This mapping code does not need to be anywhere else other than the root Application.cfc:

view plain about
1<!--- Define application-specific mappings. These will be used to point to this application.cfc when we extend it in the admin/Administrator.cfc template using the Proxy.cfc that resides in the same folder as this Application.cfc. --->
2<cfset this.mappings = structNew() />
3<!--- Mapping for the ROOT Application.cfc --->
4<cfset this.mappings["rootCfc"] = getDirectoryFromPath(getCurrentTemplatePath()) />
5<!--- Mapping for the admin SUBDIRECTORY Application.cfc. Note the admin prefix is attached at the end of this line. This points to the admin folder. --->
6<cfset this.mappings["adminCfc"] = getDirectoryFromPath( getCurrentTemplatePath() & "/admin" ) />

I used rootCfc to identify the Application.cfc in the root directory, whereas adminCfc applies to the Application in the admin directory. These variables can be named anything. Note that the "/admin" string at the end of the adminCfc mapping points to the 'admin' folder, which is a subdirectory.

Now that we have the mappings in the root Application.cfc, we need to apply them to the extends statement in Application.cfc located in the subdirectory. In the /admin/Application.cfc template use:

/admin/Application.cfc

view plain about
1<cfcomponent displayname="xxx" sessionmanagement="xx" clientmanagement="xx" extends="rootCfc.Proxy">
2<!--- Logic --->

Of course, rootCfc tells the Application.cfc in the subdirectory to look for the Proxy.cfc template in the root directory. Like other 'extend' statements, you don't need to specify '.cfc' at the end of Proxy.

You don't need to use this 'extend' mapping in either the root Proxy.cfc or Application.cfc templates. They can already find each other as they are both in the same root directory.

/Proxy.cfc

view plain about
1<cfcomponent extends="Application">
2</cfcomponent>


Summary

For the sake of absolute clarity:
root Application.cfc
Contains the mapping logic. Has the mappings for both of the root and subdirectory.
This mapping logic should be near the top of the root Application.cfc, and it should not be within any of the Application.cfc event handlers (onApplicationStart, onApplicationRequest, etc).
Does not use an 'extend' statement

view plain about
1<cfset this.mappings = structNew() />
2<cfset this.mappings["rootCfc"] = getDirectoryFromPath(getCurrentTemplatePath()) />
3<cfset this.mappings["adminCfc"] = getDirectoryFromPath( getCurrentTemplatePath() & "/admin" ) />

root Proxy.cfm
A simple 'extends="Application" works.
No mapping logic.

view plain about
1<cfcomponent extends="Application">
2</cfcomponent>

subdirectory Application.cfc
The extends statement must be the mapping variable name of the folder (rootCfc), a dot (.), and finally the name of the Proxy.cfc template without the .cfc prefix (Proxy)
No mapping logic.

view plain about
1<cfcomponent displayname="Admin" sessionmanagement="yes" clientmanagement="yes" extends="rootCfc.Proxy">

My apologies for being so verbose. I annoyed myself while writing this- but not as annoyed when I was while trying to solve this problem!

Take care!

Related External Posts:

This entry was posted on January 29, 2021 at 10:31 PM and has received 251 views.

Happy New Year!

I hope that everyone has a wonderful New Year and I wanted to provide a status update on Galaxie Blog.

While I have not been blogging lately as I want to dedicate all of my time right now for development; I have been working like crazy to complete the next major version of the blog. The new blog has been completely overhauled. All of the database code has been stripped out and replaced with ColdFusion ORM. This allows the blog to use any modern database, SQL Server, Oracle, MySql, etc. Also, the entire administrative section of the site has been re-written from scratch and will support mobile devices. It's a mobile first responsive design and is a single page application built with HTML5. It is my goal to be able to go out into a National Park with nothing more than my camera and phone, take some lovely snapshots, and be able to upload the images, and create a blog post using nothing but my iPhone.

There are a slew of other major features, such as incorporating a WYSIWYG editor. I have been creating my own custom plug-ins for the editor to allow the users to upload and edit images, create sophisticated galleries, and link and upload videos, again- using nothing but your phone. There are also new HTML5 grids that have been incorporated to allow you to find and edit information quickly. All of the new user interfaces are themed, so if you choose a particular theme the theme will also be used in the new user interfaces, i.e. the new grids, editors, and image editing tools. It's also my goal to improve loading performance by using sophisticated caching.

I can't promise any release date at this time. I want to make sure that everything is done right. Since I had to completely overhaul the entire code-base, it is a good time to revisit some of the original approaches. I'll try to keep everyone updated during the course of this New Year. Once I am in final testing, I assure you that I will be blogging again.

Thank you for your interest!

Gregory

This entry was posted on January 22, 2021 at 1:51 PM and has received 146 views.




Footer Logo

Your input and contributions are welcomed!

If you have an idea, BlogCfc based code, or a theme that you have built using this site that you want to share, please contribute by making a post here or share it by contacting us! This community can only thrive if we continue to work together.

Images and Photography:

Gregory Alexander either owns the copyright, or has the rights to use, all images and photographs on the site. If an image is not part of the "Galaxie Blog" open sourced distribution package, and instead is part of a personal blog post or a comment, please contact us and the author of the post or comment to obtain permission if you would like to use a personal image or photograph found on this site.

Credits:

Portions of Galaxie Blog are powered on the server side by BlogCfc, an open source blog developed by Raymond Camden. Revitalizing BlogCfc was a part of my orginal inspiration that prompted me to design this site. Some of the major open source contributers to BlogCfc include:

  1. Peter Farrell: the author of 'Lyla Captcha' that is used on this blog.
  2. Pete Freitag: the author of the 'ColdFish' code formatter that is also used on this blog.

Version:

Galaxie Blog Version 1.50 November 22 2019