Using onMissingTemplate in lieu of stub cfm files - coldfusion

In our ColdFusion application each request goes through index.cfm
Application.cfc decides form the query and form parameters which componetes the user is actually wanted. Those components are instantiated and the content is dropped through OnRequestStart.
Rather than always hit index.cfm with a query/form parameter, for simple cases, we would like to hit a "missing" cfm (i.e. MyApp.cfm) and allow the OnMissingTemplate function parse out the fact that we really want the content of a component (i.e. MyApp).
Another way to do this would be to actualy put cfm stub files in for "generic" calls to the components but it seems like with OnMissingTemplate we do not need to do that.
Is this a reasonable use for OnMissingTemplate?

That's a great use for onMissingTemplate. Just make sure that if you're using IIS, that you make sure that the files you're linking to are actually .cfm (MyApp.cfm) files, and not directories (/MyApp/). See these links for more information:
http://www.bennadel.com/blog/1625-ColdFusion-8-s-OnMissingTemplate-So-Close-To-Being-Good.htm
http://www.bennadel.com/blog/1694-ColdFusion-s-OnMissingTemplate-Event-Handler-Works-With-CFC-Requests.htm

Related

CFC file not being processed properly in Railo when changes made to servlet-mapping in web.xml

In order to play around with search engine friendly urls, I have added the following mappings to my web.xml:
<servlet-mapping>
<servlet-name>CFMLServlet</servlet-name>
<url-pattern>/mywebsitename.com/index.cfm/*</url-pattern>
<url-pattern>/mywebsitename.com/posts/*</url-pattern>
</servlet-mapping>
This has allowed me to work with urls like this mywebsitename.com/posts/my-first-post
However, one little glitch is occurring. If I try and access a CFC file that was working before, it now simply returns the html text of that CFC instead of actually processing it in Railo.
To explain it better, if I add the servlet-mapping above to web.xml and call mywebsite.com/Components/CFCProxy.cfc - the html of that cfc is returned.I would expect to see a Railo dump of the functions.
However, if I remove the servlet-mapping from the web.xml file, then when I access that same URL, I see the proper railo dump of the CFC functions that can be called, which is what I expect to see.
So without the servlet-mapping it works fine, but with the servlet, only html text of the CFC is returned.
So my guess is that by adding the servlet-mapping, I am disabling the processing of that CFC by Railo somehow.
So all I would like to know is how to get that CFC file to process properly again?
Do I need to add another line to the servlet-mapping for that and if so, what?
Thanks
I ran into this same issue recently.
Try adding
<url-pattern>*.cfm</url-pattern>
<url-pattern>*.cfc</url-pattern>

How to get directory path up to a specific folder only?

Using: CF10 and IIS7.5
I have a section within my website called "Bookings". It is located like this:
c:\inetpub\wwwroot\mysite\bookings
Within this folder will be sub-folders and eventually webpages themselves. Heres an example:
c:\inetpub\wwwroot\mysite\bookings\holidays\new.cfm
c:\inetpub\wwwroot\mysite\bookings\carhire\edit.cfm
I include (using <cfinclude>) another page within each webpage that displays different links depending on which page is calling it. All I want to know is the directory up to the "bookings" folder. Something like this (pseudo code):
<cfset whereAmI = #GetDirectoryFromPath(GetBaseTemplatePath())#>
<cfif #whereAmI# EQ "C:\inetpub\wwwroot\mysite\bookings">
<h1>Booking Section Links</h1>
</cfif>
The above code works only if the user visits the bookings/index.cfm page of the "bookings" folder. But if they go to the bookings/holidays/new.cfm page, it is now in the holidays folder so the <h1> content will not appear. I really only want to check for any page that is in the bookings folder, even if it is within a subfolder within the bookings folder. A bit like in SQL where I could say IF #GetDirectoryFromPath(GetBaseTemplatePath())# LIKE 'c:\inetpub\wwwroot\mysite\bookings%' so it has a wildcard on the end.
I know this question is going to irritate the MVC framework advocates but please excuse me on this!
Here is a quick, easy way to solve your problem (may not work as system expands - but should get you started down the right path).
<cfset whereAmI = GetDirectoryFromPath(GetBaseTemplatePath())>
<cfif whereAmI CONTAINS "C:\inetpub\wwwroot\mysite\bookings">
<h1>Booking Section Links</h1>
</cfif>
Note, I removed the # from inside the cfset and cfif you do not need them there.
You could even scale back the path to use just 'mysite\bookings'.
Ideally, this should be wrapped up into a function so that you can easily pass different paths into it to determine if you are on a given page. Or, possibly, even determine the 'parent' folder in onRequestStart in Application.cfc and set it as a request scope variable.
This will need to be tweaked if you run the code on a *nix based system.
It is more easier with CGI variables. You can use "CF_TEMPLATE_PATH". Try this
<cfoutput>The value of CF_TEMPLATE_PATH is: </cfoutput><cfdump var="#CF_TEMPLATE_PATH#">

cfc that bring in additional functions via include

My application.cfc starts with:
<cfcomponent extends="org.corfield.framework">
later on void function setupApplication() output="false" {
I have
// tools
include "initapp.cfm";
initapp.cfm has nothing but functions in it. Things like:
<!--- Helper functions --->
<cfscript>
string function stripHTML(str) output="false" {
return REReplaceNoCase(arguments.str,"<[^>]*>","","ALL");
}
application.stripHTML = stripHTML;
</cfscript>
The nature of the functions is NOT associated with a session. Is there a better way to make functions available globally?
If you're trying to put helper functions together for use in CFCs, one option may be to use the component.cfc file.
Using the component.cfc file
All CFCs automatically extend the ColdFusion
WEB-INF/cftags/component.cfc component. (The WEB-INF directory is in
the cf_root/wwwroot directory on ColdFusion configured with an
embedded J2EE server. It is in the cf_root directory when you deploy
ColdFusion on a J2EE server.) This CFC is distributed as a zero-length
file. You can use it for any core methods or properties that you want
all CFCs in your ColdFusion application server instance to inherit.
Note: When you install a newer version of ColdFusion, the installation
procedure replaces the existing component.cfc file with a new version.
Therefore, before upgrading, you should save any code that you have
added to the component.cfc file, and then copy the code into the new
component.cfc file.
If that solution is TOO global you can extend your helper cfc, but it has to be done in every cfc and doesn't answer your one-time-set-it-and-forget-it idea. See Using CFCs effectively
If your helper functions are for use in .cfm files, I'd do like Adam suggested. I usually put my helper functions in a "tools" cfc located in a CFC folder and make it an application scoped cfc.
function onApplicationStart(){
application.tools = createObject("component", "cfc.tools");
}
One of my helper functions logs the time it takes to index a solr collection. Using it looks like
<cfset application.tools.logSolrIndex('collectionName',getTickCount()-start,qFileList.recordCount)>
Last resort:
If you had to stick with an include for use outside of the application.cfc, I might simply include initapp.cfm onRequest() before you include your page.
Put the functions in a library CFC, and then put an instance of that CFC in the application scope in onApplicationStart().
That said, you'd be kinda breaking encapsulation if you then referenced this application-scoped CFC within other CFCs, which is a consideration (not necessarily a deal breaker, but a consideration).
You could look at some sort of dependency injection approach to mitigate this (eg: ColdSpring)
Whichever way I ended up doing it, I would not be doing it the way you're doing it, I'm afraid.

Is there a "clean URL" (mod_rewrite) equivalent for iPlanet?

I'm working with Coldfusion (because I have to) and we use iPlanet 7 (because we have to), and I would like to pass clean URL's instead of the query-param junk (for numerous reasons). My problem is I don't have access to the overall obj.conf file, and was wondering if there were .htaccess equivalents I could pass on the fly per directory. Currently I am using Application.cfc to force the server to look at index.cfm in root before loading the requested page, but this requires a .cfm file is passed, so it just 404's out if the user provides /path/to/file but no extension. Ultimately, I would like to allow the user to pass domain.com/path/to/file but serve domain.com/index.cfm?q1=path&q2=to&q3=file. Any ideas?
You can mod_dir with the DirectoryIndex directive to set which page is served on /directory/ requests.
http://httpd.apache.org/docs/2.2/mod/mod_dir.html
I'm not sure what exists for iPlanet, haven't had to work with it before. But it would be possible to use a url like index.cfm/path/to/file, and pull the extra path information via the cgi.path_info variable. Not exactly what you're looking for, but cleaner that query-params.

What does this URL mean?

http://localhost/students/index.cfm/register?action=studentreg
I did not understand the use of 'register' after index.cfm. Can anyone please help me understand what it could mean? There is a index.cfm file in students folder. Could register be a folder name?
They might be using special commands within their .htaccess files to modify the URL to point to something else.
Things like pointing home.html -> index.php?p=home
ColdFusion will execute index.cfm. It is up to the script to decide what to do with the /register that comes after.
This trick is used to build SEO friendly URL's. For example http://www.ohnuts.com/buy.cfm/bulk-nuts-seeds/almonds/roasted-salted - buy.com uses the /bulk-nuts-seeds/almonds/roasted-salted to determine which page to show.
Whats nice about this is it avoids custom 404 error handlers and URL rewrites. This makes it easier for your application to directly manage the URL's used.
I don't know if it works on all platforms, as I've only used it on IIS.
You want to look into the cgi.PATH_INFO variable, it is populated automatically by CF server when such URL format used.
Better real-life example would look something like this.
I have an URL which I want to make prettier:
http://mybikesite/index.cfm?category=bicycles&manufacturer=cannondale&model=trail-sl-4
I can rewrite it this way:
http://mybikesite/index.cfm/category/bicycles/manufacturer/cannondale/model/trail-sl-4
Our cgi.PATH_INFO value is: /category/bicycles/manufacturer/cannondale/model/trail-sl-4
We can parse it using list functions to get the same data as original URL gives us automatically.
Second part of your URL is plain GET variable, it is pushed into URL scope as usually.
Both formats can be mixed, GET vars may be used for paging or any other secondary stuff.
index.cfm is using either a CFIF IsDefind("register") or a CFIF #cgi.Path_Info# CONTAINS statements to execute a function or perform a logic step.