Ever wish you could just install a frequently used UDF to the server since you use it so much? Take any of the numerous UDFs found at CFLib.org for example. How about... QueryRowToStruct()? That's a pretty useful function. Wonder why they didn't build this in? With Railo 3.1 RC, you can build this in yourself. With this blog post, I'm going to outline two different installation concepts, server wide and local context.
First, server wide:
- Click on the "Download" link on QueryRowToStruct and you'll be prompted to download QueryRowToStruct.cfm
- For server wide installation, you'll want to put this in the following directory:
{railo installation directory}/lib/railo-server/context/library/function/ - Restart the server (I had to, I'm going to verify if this step is really necessary or if it can be fixed :) )
Once installed, I shouldn't have to cfinclude or copy/paste that function anywhere. I can create a test.cfm in my localhost and run the example code on QueryRowToStruct description page.
Now, you may be in a particular situation where you can't have this server-wide because you share the server with other people or because there's a conflict. You could just install it to your local context. Each virtual host you make should have its own WEB-INF directory, so you have a global admin and a local admin.
You would repeat all of the steps above, except for #2, you'll want to install this here instead:
{your website root directory}/WEB-INF/railo/library/function/Remember, you don't have to use anything specific from CFLib.org. You can write your own user defined function or install the one that you frequently use. I bet this makes you wonder if Railo 3.1 could give you the ability to create your own Built-In-Tag? ;) You can and there's been some changes, so I plan on investigating and outlining in a new blog post. If you want to see if you can figure it out for yourself, you can use Andrea Campolonghi's <cfajaxproxy> as a great example. This example includes installation directions and will only work on Railo 3.1.020 build or higher.
Update: The resin webserver doesn't need to be restarted, but the Railo servlet engine does. You can do this one of two ways, log into the admin portal and click Restart or via code: <cfadmin action="restart" type="server" password="serverPassword">
19 responses so far ↓
1 todd sharp // Jul 23, 2009 at 3:36 PM
2 Garrett Johnson // Jul 23, 2009 at 3:45 PM
3 Dan G. Switzer, II // Jul 23, 2009 at 3:54 PM
4 Peter Bell // Jul 23, 2009 at 5:30 PM
Understand where you're coming from but that's just how CF is. It's a powerful, dynamic language and you can already do plenty of stuff to confuse the heck out of people. For some, oMM() will be pretty confusing as they try to find the methods that don't exist. If that isn't enough, try some object based mixins where you pass methods to objects at runtime. Again a powerful tool that can make an awful mess if it is misused.
This is one more tool in the toolbox and comes with the same caveat as all power tools - be careful how you use it.
5 Mark Drew // Jul 23, 2009 at 5:47 PM
Its a nice way to extend the functionality of the engine with out having to write more code.
You could say the same thing for custom tags in any version of CF, where you can add random files in the /cf/CustomTags directory.
Ok, the directory path isn't as nice but if it is a documented feature, surely its all good?
6 Sean Corfield // Jul 23, 2009 at 6:38 PM
7 Gerald // Jul 23, 2009 at 7:37 PM
8 Dave Shuck // Jul 23, 2009 at 7:39 PM
9 todd sharp // Jul 23, 2009 at 8:30 PM
If I look at it like Peter laid out (be careful how you use it) then I guess it makes sense. Maybe there could be _some_ indicator though - perhaps exposed as metadata or some standard naming convention that would easily cue developers in on a custom function?
Also, what happens if I try to override an existing built in function?
10 Todd Rafferty // Jul 23, 2009 at 8:54 PM
==================
iif.cfm:
<cffunction name="iif" access="public" returntype="string">
<cfreturn "iif() sucks anyways. Use the ternary operator instead!">
</cffunction>
test.cfm:
<cfset foobar = true>
<cfoutput>#iif(foobar IS TRUE,DE('true'),DE('false'))#</cfoutput>
Result:
iif() sucks anyways. Use the ternary operator instead!
11 Todd Rafferty // Jul 23, 2009 at 8:55 PM
12 Todd Rafferty // Jul 23, 2009 at 8:58 PM
13 Todd Rafferty // Jul 23, 2009 at 9:08 PM
14 Oscar Arevalo // Jul 24, 2009 at 8:11 AM
In fact I think this should be the way any further extensions to the language should be made, instead of creating more and more functions (i.e. all those imageXXX() functions)
15 denny // Aug 1, 2009 at 8:31 AM
16 Sean Corfield // Aug 1, 2009 at 9:45 AM
Also, would you want to edit a core installed component like that? On the other hand, Railo lets you specify any CFC as the uber-base-class so you can easily redefine the behavior per-web-context which is much safer and more flexible.
17 denny // Aug 1, 2009 at 8:16 PM
Really tho, either way, you're doing a trade. Pragmatism vs. pattern.
Sometimes it's a good trade, sometimes not. When is it which?
To quote a famous CFer, "it depends". =]
18 David McGuigan // Aug 14, 2009 at 7:39 AM
I think for consistency's sake, though, you should implement it parallel to custom tags. A set of managed directories ( with a starter default sibling to the default custom tags store ) in the administrator as well as a per-app option ( this.customFunctionsPaths ). You should also be able to just add .cfc files and have it parse and use all cffunctions within it/them. Breaking up well-organized, related libraries from existing CFCs into 1 cff per .cfm is benefitless.
Again, SPECTACULAR FEATURE. I tip my hat.
19 Todd Rafferty // Aug 19, 2009 at 4:02 PM
Leave a Comment