|
|
YOUR FEEDBACK
SOA World Conference
Virtualization Conference $200 Savings Expire May 16, 2008... – Register Today! Did you read today's front page stories & breaking news?
SYS-CON.TV SYS-CON.TV WEBCASTS |
TOP COLDFUSION LINKS Journeyman CF
Calling All Custom Tags Part 2
By: Charlie Arehart
Digg This!
In my Journeyman column last month (CFDJ Vol. 2, issue 4) we began looking at how - and why - to call custom tags in different ways. So far, we've learned that the CF_ approach will look first locally, then in the shared \cfusion\customtags directory, while the CFMODULE NAME= approach will look only in the shared directory. But what if you can't place files in the shared customtags directory? Perhaps you work in a tightly controlled corporate environment where you have to get all sorts of permissions to place files in the shared directory or, worse, you're in a hosted environment where you're extremely limited in what you can do and they absolutely refuse to place any tags you'd like to use in the shared directory? Well, it's good to know that at least one solution exists. You can place the intended tag in the local directory and execute it from there using the CF_ approach. For many folks, this will be a revelation. If you have refrained until now from creating custom tags or exploring and enjoying the vast benefits of preexisting custom tags available in the Allaire Developer's Exchange (www.allaire.com), then let me welcome you to this world! You're not forced to use the shared directory. Go to town! But there's a catch. You now know that you can place the intended custom tag in your local calling template directory and you're good to go. But what if you have code in several subdirectories? If you place the custom tag in all those directories, it will work; but you're exposing yourself to the risks and challenges of keeping all those versions updated and in sync. Of course, if you have access to the shared customtags directory, just place it there. But what if you don't? Are you forced to make those copies and suffer the indignities of multiple redundant and possibly out-of-sync versions?
A Template by Any Other Name... This approach allows you to name the specific location - anywhere on the CF server - in which the custom tag's file can be found. This could be used to name some alternative "global" directory that all can see or, more useful, it could name some "subglobal" directory that all the templates under the directories of a related group of applications could see. They could all point to this one directory, thus eliminating the redundancy problem. And the coolest thing for those in a hosted or otherwise tightly controlled environment is that this "subglobal" directory, as I've termed it, could be placed anywhere in the directory structure that you do have control over, making it great for sharing a custom tag among all your (and only your) applications. As with the CFMODULE NAME= approach, there are actually two different ways to use the TEMPLATE= approach. The first is for you to specify the physical path to the custom tag relative to the location of the caller. At the end of the last article, we introduced an example custom tag called format.cfm. If that were placed in the current directory with the template calling it, we'd be using it in what I have referred to as a "local" mode. It's intended to be used by templates in the same directory. Using the CFMODULE TEMPLATE approach, we could call this local custom tag with the following syntax: <CFMODULE TEMPLATE="format.cfm" TEXT="#fname#"> Note that the difference (besides use of the TEMPLATE attribute) is that the .cfm file extension is now used. Now it may appear that this is just a lot of extra work with little benefit, and in fact in this specific use you really haven't gained much over the CF_ approach. (Actually, there is one difference: it will now execute only the local version and not any shared one. But that's not usually a valuable benefit.) But the key benefit comes when you specify some relative path information before the name of the custom tag template file name. For instance, consider a directory structure as depicted in Figure 1. Assume we have several programs in a "mygroup" directory (under our Web root, where our Web files are located - we're not discussing here subdirectories under the shared customtags directory). If there were no further subdirectories under APP1 or APP2, then all the templates in those directories could call upon a shared customtags directory, depicted in the figure as "ourcustomtags." Assuming our format.cfm file were placed in this directory, we could easily call it from any of our "mygroup" subdirectory templates using relative naming conventions that are common to folks familiar with using the operating system command prompt or even HTML tags like <IMG SRC> and <A HREF>. We specify a path above ours using ".." notation, which refers to our parent. And we can refer to a sibling (a directory at the same level as our own under our parent) as "..\sibling". In our case, if our code is running in, say, the APP1 directory, we could call the format.cfm in the mygroup \ourcustomtags directory using the following syntax: <CFMODULE TEMPLATE="..\ourcustomtags\format.cfm" TEXT="#fname#"> Notice the "..\" preceding "ourcustomtags\". These tell CF to go up to our parent and down to the ourcustomtags directory to find format.cfm. (In the last article, we learned that our fictitious format.cfm custom tag was designed to accept a parameter called "text," and we were passing it the value of a local variable called "fname.") For those in hosted environments, this is A Good Thing, because you can use this approach to share a given custom tag among all the apps in your server directory. The only drawback is that as soon as we start to put subdirectories under our APP1 or APP2 directories, for example, the relative paths for programs placed in those subdirectories become a little clumsy, since we now need to specify a grandparent reference, as in "..\..\ourcustomtags\format.cfm". This can become difficult to read and maintain.
My Kingdom for a Mapping A directory mapping is a setting made in the ColdFusion Administrator that maps a virtual name to a physical directory path (see Figure 2). That is, we could create a virtual name in the administrator to refer to our "mygroup\ourcustom-tags" directory with a single word. Let's say we called it "mygrouptags". (That is, let's say we had the administrator create a mapping of the word "mygrouptags" to the physical directory"c:\inetpub\wwwroot\my-group\ourcustomtags".) Now we could refer to the tag in that location using this new mapping. The key to using mappings in the TEMPLATE= approach (as well as with CFINCLUDE, which can also use mappings) is to specify a "\" and the name of the mapping before the name of the custom tag file name. So our example would become: <CFMODULE TEMPLATE="\mygrouptags\format.cfm" TEXT="#fname#"> Pretty nifty! And the beauty of this approach is that it doesn't matter where in our entire mygroups directory structure our calling template is located. We can even move code around within the directories and the call to the custom tag will always use this syntax to refer to the location of the custom tag. Not only that, another great benefit of directory mappings is that should anyone decide to move the "ourcustomtags" directory anywhere else in our tree structure - or really anywhere on the server - our code will again not have to change. Only the mapping in the administrator needs to change. As with the CFMODULE NAME= approach, this call will not find a local version of the custom tag. It will find and use only that version in the named directory. And we can't really have different "versions" of the tag unless we create and use different mappings. Furthermore, this approach opens up a bit of a security hole. You are making this mapping in the administrator; thus, technically, others on the server could become aware of and access the custom tag in your directory more easily. Of course, that's a thorny issue that deserves its own entire article. Mapping doesn't spawn the security problem in and of itself; it does, however, arguably increase exposure to the problem. There is a solution, if you're willing to make the commitment to using Advanced Security features. We'll address it briefly in a moment since it is indeed an important issue.
Getting to the "Root" of the Problem In fact, there is a predefined mapping called simply "/" defined in the administrator by default. And it does map to the Web root of the Web server on which CF is installed - such as c:\inetpub\wwwroot on an IIS server installed on the c: drive. So you can, in fact, use that to specify subdirectories off the root in a form that looks like an absolute path, such as "\myapp\customtags\format.cfm". This means, of course, that in some situations there is no real need to create a separate mapping for your particular directory. Just be aware that things can get confusing in a hosted environment, where your "server" is actually just a "virtual server" under the directory tree of the entire Web server. In such a case, this "absolute" path defined in the administrator is relative to the root of the CF server, not relative to your own "virtual root." One last note. I said that this TEMPLATE= approach allows access to a custom tag located anywhere on the CF server. If you can point to it with a relative or mapped path, you can run it. Actually, there's no limitation that says the path specified even needs to be to a file on the same server. Since we're specifying the physical path to the file, it can really be anywhere that the server can find it, whether on a mapped drive or a UNC path. As long as the server can see it, we can place and run our custom tags there.
Security Matters If we're in a secure environment, perhaps we may have a tag that performs a function to return data that may be restricted. In a hosted environment, perhaps we have paid for a commercial custom tag and must restrict access for licensing issues.
Advanced Security to the Rescue Using Advanced Security requires considerable forethought and some rather lengthy setup procedures to create and administer users, resources and policies to map users to resources. Though the benefit is very likely well worth the price, it seems many have been slow to make the move. Maybe this is due to the rather sparse documentation or to the rather daunting user interface for administering it. Fortunately, both have been improved in 4.5. There's also coverage of the topic in Ben Forta's book Advanced ColdFusion Development, published by Que. As for custom tags, they are just one of the many "resources" that can be protected in Advanced Security. Protectable resources actually include all manner of things such as files, directories and data sources, as well as applications, tags, functions and, indeed, custom tags. You owe it to yourself and your organization to look into and take the time to implement Advanced Security. The benefits are manifold. And in a secured or hosted environment, it's imperative (though hosted environments are among the last to consider advanced security, paradoxically). By the way, some presume that it's a feature available only in the Enterprise version of ColdFusion. But it's not. All that's missing from the Professional version is "Server Sandbox" security - which, while it may seem to encompass what we're describing here, in fact doesn't. Do check out Advanced Security.
Tales from the Crypt Encrypting tags is a valuable option for secured environments, and especially for commercially sold tags. The process is actually just an encoding, not an encryption, of the tag. In fact, as of Release 4.5, Allaire now calls it encoding, and the utility, formerly called CFCRYPT, is now called CFENCODE. For more information see the Allaire manual Developing Web Applications with ColdFusion.
You're No Custom Tag
CFEXECUTE
CFHTTP
CFOBJECT
Java Processing The createobject function allows you to create and use JAVA CFXs or objects, and by extension Enterprise JavaBean (EJB) objects. (As of 4.5, EJBs can be called via CFOBJECT as well.) Other features you may come across for running Java objects include CF_ANYWHERE (an older form of executing servlets) and CFX_J (an older way to run Java objects now superseded by Java CFXs).
Final Thoughts First, I mentioned previously that you can find many (in fact, hundreds of) prebuilt custom tags at the Allaire Developer's Exchange (formerly known as the Tag Gallery). It is accessible from the Developer section of the Allaire site (www.allaire.com). When you're working with custom tags, you may encounter an interesting problem that will arise if you move a custom tag from one directory to another (such as moving it from a local directory to the global one). If, before you move it, you execute a template that finds the custom tag in the first location, and then after you move the custom tag you execute that template again, you'll receive an error message indicating that the custom tag cannot be found. CF is still trying to find it in the original location, and even though it's been moved to a location where CF should be able to find it, it doesn't. It seems to be a template code-caching thing. The problem will be corrected if you restart the CF server process. I'm not aware of another way to resolve the problem, though I'm confident there may be one. Also, as Ben Forta pointed out in his article "Preserve Precious Resources - Recycle" (CFDJ, Vol. 2, issue 2), the notion of paired custom tags and nested custom tags has also been enabled in Release 4. They're very useful in some situations, and they work just like the CF_ approach described above. Unfortunately, that means that they're not able to take advantage of some of the control offered by the CFMODULE approaches. Finally, it's worth noting that with respect to all aspects of referring to file names when using custom tags, case sensitivity is significant in UNIX operating environments. The Developing Web Applications with ColdFusion manual indicates that custom tag names must be lower case on UNIX. So that's it. It has taken me two months' worth of columns...practically a mini-novel! There's probably more to using custom tags than you originally thought. It's really great to know the power and possibilities available with them. These solutions can definitely come in handy in some environments. As always, check out the Allaire reference manuals and user guides to learn more and find real examples. But, most important, try things out yourself. There's no better way to learn! CFDJ LATEST STORIES . . .
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||