ColdFusion TIPS PLUS
Issue 00127 http://www.cftipsplus.com
I. My CommentsII. ColdFusion In Context: Something Extra
By R. Martin Ladner
martin.ladner@charter.net
Advanced, Intensive ColdFusion Training!Visit this site. If you have plans to get training here is a company
that provides Advanced, Intensive ColdFusion Training. Check them out.
http://www.coldfusiontraining.com/index.cfm?ref=cftipsplus
I. Comments:
Well my wife and I got the shock of our lives. My wife is going to have another baby. I have two boys so I hope it will be a girl. However I love my boys and we have a blast so I will not mind if it is a boy. I guess it is a good thing we have not picked out a house yet. Now we need a room for a baby.
I love my new job. We are using UML or a version of it. I am still trying to make sure I am on the same page as my boss and co-workers. I am currently working on a class page showing the system I am building.
Let me know what type of applications you would want me to put in my book for the
CFTipsPlus: Project 1 ColdFusion Intranet
I have started working on it. I am working on some code now so when I get through I can make sure my screen shots all are correct. I am including a style sheet that should work for all items you need in a website with a few exceptions.
My YIM is BroStanford and my AOL IM is ZnathanZ. However remember if I am busy at work I may not be able to say much as there are a lot of you out there.
Keep Coding,
Nathan Stanford
http://www.cftipsplus.com
If you have suggestions for articles send them to us.
If you would like to write for cftipsplus.com
send us an email to:
NathanS<at>nsnd.com
IF YOU WANT TO BE AN AUTHOR SEND IN YOUR COLDFUSION TIPS.
Remember this is a great way to get your name known in the
ColdFusion Community.
II. ColdFusion in Context: Something Extra
By R. Martin Ladner
martin.ladner@charter.net
Suppose you have a module you want to use in several different ways and only need to pass it one parameter to make it work. Now suppose you want to want to pass the parameter in the URL without stopping robots from indexing the result. Here's one way that works. Along the way, you'll see why applications using the original version of Fusebox could be hard to install.
Background
When an indexing service encounters a question mark in a URL, it usually stops indexing at that point. However, you can pass extra information after the filename in the URL without using a question mark as a separator. One way to do this is to append the extra information after the filename, separating the filename from the extra information with a slash. The Web server and ColdFusion will work together to call the actual file, but they will pass the file the entire URL.
As this demonstration will show, the instant you start doing non-standard things to the URL, you're on your own. You wind up having to create absolute URLs or relying on absolute mappings in ColdFusion administrator or the Web server in order to make the URLs look right again.
Applications using the original version of Fusebox could be hard to install for this reason. The form2urlattributes custom tag that allowed fusebox modules to treat all URL and form variables as attribute variables had the side effect of rewriting the URL to permit operations similar to those demonstrated for this tip. (See its documentation.) Other kinds of ColdFusion applications will usually run fine if you copy them to your box and tweak the code for their new environment. However, these applications typically required changes in ColdFusion adminstrator and possibly the Web server as well as mentioned above. If you see extra slashes where they don't belong or the navigation breaks on an application that uses the original version of Fusebox, look beyond the code itself.
Example
For this demonstration, create a file that passes extra information in the URL; call the file menu.cfm. As you can see, this part is easy.
<h4>Leave notes on these subjects...</h4><a href="FileEdit.cfm/Design">Design</a><br>
<a href="FileEdit.cfm/Build">Build</a><br>
<a href="FileEdit.cfm/Install">Install</a>
Now create a file that does something with this information. Call it FileEdit.cfm and let it hold the remaining code for this demonstration.
Begin by copying the extra information to a form variable if the variable doesn't already exist. If the URL doesn't have ".cfm/" in it to start with, or if it ends in ".cfm/" - this text begins 4 characters from the end - then there's no extra information; stop processing.
If there is extra information and the form variable needs to be created, work with the appropriate number of characters from the right-hand end of the string in the browser window. Notice the position where the ".cfm/" begins. Remove everything up to this point; remove additional characters to lose the file extension and forward slash. What's left is the extra information. You may have seen other sources recommend that you simply use cgi.path_info to get this information. However, not all Web servers populate cgi.path_info; that's why this demonstration doesn't use it.
<cfif not isDefined("form.Context")>
<cfif not findNoCase(".cfm",cgi.script_name) or
((findNoCase(".cfm/",cgi.script_name)+4) ge len(cgi.script_name))>
The context must follow the filename: e.g., file.cfm/context
<cfabort>
</cfif>
<cfset form.Context=right(cgi.script_name,len(cgi.script_name)
-findNoCase(".cfm/",cgi.script_name)-4)>
</cfif>
If the form tries to use a relative filename to get back to the menu when done, the server will add it after the extra information in the existing URL: for example, "/context/extra/FileEdit.cfm/Design/menu.cfm". However, the Web Server and ColdFusion will ignore everything after the first .cfm when looking for the file to be used, and the browser won't return to the menu. Therefore, an absolute filename is needed. A way to get this filename without hard-coding the whole thing is to drop the length of the extra information (Context), the length of the slash (1), and the length of the script name from the URL; what remains is the directory to which the bare filename of the menu can be appended.
It's easiest to get the bare filename of the script from cf_template_path. cgi.script_name is a good place to look for the URL. That's why this procedure uses length information from cf_template_path to make a shorter string out of cgi.script_name. [For my Web host, I use cgi.path_info instead of cgi.script_name.]
<cfset MyMenu=left(cgi.script_name,
len(cgi.script_name)-len(form.Context)-1
-len(getFileFromPath(cf_template_path)))&"menu.cfm">
However, this demonstration lets the user create files on the server; it needs some protection to stop the user from creating arbitrary files. So, if the context isn't on your expected list, stop. Otherwise, show the user which choice is active at this time.
<cfoutput>
<cfif not findNoCase(form.Context," Design Build Install ")>
Please limit yourself to menu choices; go back.
<cfabort>
</cfif>
Now editing #form.Context# notes
</cfoutput>
<hr>
The remaining code implements a function to make this demonstration interesting. It's adapted from an earlier column to produce a notice to be included in the home page as required. It uses the context to build the name of the file to be created or edited. If the form has submitted and content exists, replace the content, creating the file if it doesn't already exist. If the file exists, read its contents into a field for editing. Otherwise, start with a single space. Using physical wraps with the textarea input type preserves newlines used for formatting.
This form has three special features. It has no action; the action is understood to be the current file. If the action were explicitly specified, it would be appended to the URL, which already has extra information. (Try this if you're not convinced.) It carries the context in a hidden field so the form will still know what to do when it's submitted. When the user selects the exit, it uses javascript to change the location to the absolute URL created earlier to represent the menu.
<cfset Fullname=#getDirectoryFromPath(cf_template_path)#&"#form.Context#"&".txt"><cfif isDefined("form.Doit") and len(trim(form.Notice))>
<cffile action="write" file="#Fullname#" output="#form.Notice#" addnewline="Yes">
</cfif>
<cfif fileExists("#Fullname#")>
<cffile action="read" file="#Fullname#" variable="NoteText">
<cfelse>
[There is no message text file yet.]
</cfif>
<cfparam name="NoteText" default=" ">
<form name="Setnotice" method="post">
<textarea name="Notice" wrap="physical" rows="5" cols="60">
<cfoutput>#trim(NoteText)#</cfoutput></textarea>
<input type="Submit" name="Doit" value="Change">
<input type="hidden" name="Context" value=<cfoutput>"#form.Context#"</cfoutput>>
<input type="button" name="byebye" value="Return to Menu"
onClick="javascript:document.location = '<cfoutput>#MyMenu#</cfoutput>'; return false;">
</form>
Review and Ruminate
Try this out by browsing menu.cfm; then think about it. Adding non-query characters to a URL and extracting information from the resulting extra path information can be done. However, this is a lot of work to move a little extra information.
If your intent is really to use multi-purpose modules without inviting your users to be creative with URLs, you might consider self-submitting forms instead of URLs to pass parameters. Or, you might use URLs as usual but mask them by enclosing the related pages in a frameset.
If your intent is really to simplify indexing, it might be easier and put less strain on your server to periodically generate static pages for robots to follow and index. When humans follow indexed static pages, consider using cookie information (or the lack of it) to shift human users them to the dynamic equivalents of these pages. I've seen "File Not Found" logic that parses extra path information back into query strings and uses it to generate a likely page equivalent. You might not even need a one-for-one equivalent. If you don't want to get this fancy, you could simply provide a button on the static pages that invites humans to get more current information.
This tip provides a way get a little extra information; it also discusses alternatives.
=Marty=
SPONSOR ADS:
This e-mail is sponsored by the following ads.
Advanced, Intensive ColdFusion Training!Visit this site. If you have plans to get training here is a company
that provides Advanced, Intensive ColdFusion Training. Check them out.
http://www.coldfusiontraining.com/index.cfm?ref=cftipsplus
Publisher and Creator:
Nathan Stanford,
NathanS<at>nsnd.com
http://www.cftipsplus.com
Macromedia and ColdFusion are U.S. registered trademarks.
Copyright (c) 2000 - 2003
CFTIPSPLUS.COM and NSND.COM
Permission is granted to circulate this publication via
MANUAL forwarding by email to friends provided that the text is
forwarded in its entirety and no fee is charged.