Twitter: cfjedimaster


Address: Lafayette, LA, USA

Ask a Jedi: Getting the current directory

05-08-2008 13,553 views ColdFusion 24 Comments

I sometimes like to start the morning off with an easy question. Makes me feel all smarty-pants and stuff. Here is a quickie from Patrick that may actually be news to some folks, so hopefully it will be easy for me - helpful for others.

Hi Ray, me again I have a, maybe silly, question about getting the current directory. I have to get the current directory in which a template resides. But I don't want the full path.

If i run www.example.com/folder/index.cfm i should get "folder" but not path/to/somewhere/in/the/system/folder. I tried with expandpath("./") and getDirectoryFrom Path(ExpandPath(CGI.SCRIPT_NAME)) but this always returns a full path. Any built in function i forgot to try? Thanks for a hint!

This is two issues here. How do I get the directory from a full path, and how do I get the current directory. The first one is simple. The getDirectoryFromPath() function will take any full path and return just the directory. There is also a corresponding getFileFromPath() function.

The second issue is slightly more complicated. ColdFusion has two functions related to getting the current template. They are getBaseTemplatePath() and getCurrentTemplatePath(). I tend to forget which does what, but consider this first example:

view plain print about
1<cffunction name="onRequestStart" returnType="boolean" output="true">
2    <cfargument name="thePage" type="string" required="true">
3    <cfoutput>
4    getCurrentTemplatePath()=#getCurrentTemplatePath()#<br>
5    getBaseTemplatePath()=#getBaseTemplatePath()#<br>
6    <p>
7    </cfoutput>        
8    <cfreturn true>
9</cffunction>

When I run test4.cfm, I get:

getCurrentTemplatePath()=/Users/ray/Documents/Web Sites/webroot/Application.cfc
getBaseTemplatePath()=/Users/ray/Documents/Web Sites/webroot/test4.cfm

The getCurrentTemplatePath refers to the actual file being run right now, which is Application.cfc, and getBaseTemplatePath returns to the main file being executed.

If that sounds a bit unclear, forgive me. As I said, I always forget the difference (one reason I'll fail the CF8 cert probably). In general you are going to want to use getCurrentTemplatePath if you want to consider the file where the actual function is being run.

24 Comments

  • Commented on 05-08-2008 at 10:09 AM
    @Raymond:

    It sounds like he may be wanting to get the directory relative to the webserver, not from the OS path--but I could be wrong.
  • Commented on 05-08-2008 at 10:13 AM
    I don't know - he said specifically folder - which to me means a full path. Let's see what he says (I pinged him to let him know I blogged it).
  • Commented on 05-08-2008 at 10:13 AM
    @Ray and Patrick

    If understand correctly you want to get the directory, relative to your webroot, of the currently executing template right?

    For example:

    URL:http://localhost/mycfstuff/samples/index.cfm

    Full Path:C:\Inetpub\wwwroot\mycf\samples\index.cfm

    Want:\mycf\samples\

    You can use expandPath("/") to get the path to webroot
    C:\Inetpub\wwwroot\

    you can use getDirectoryFromPath(getCurrentTemplatePath()) to get the full directory: C:\Inetpub\wwwroot\mycf\samples\

    The some simple majik to get just the directory.

    right(getdirectoryfrompath(getcurrenttemplatepath()),len(getdirectoryfrompath(getcurrenttemplatepath()))-len(expandpath("/"))+1)

    gives you: \mycf\samples\

    You have to add the +1 at the end in order to keep the slash in the front.

    Perhaps not the most elegant way but from what I understood of your question you get JUST the path from the webroot to your template.

    Cheers,
  • Commented on 05-08-2008 at 10:13 AM
    Oh yeah, and if that's really want he wants I wrote a UDF a while back that will parse a URL:

    http://blog.pengoworks.com/index.cfm/2006/9/27/CFM...

    This script will parse out the path to in the URL. You could easily modify the code to only generate the path if that's all you wanted as well.
  • Commented on 05-08-2008 at 10:15 AM
    @Gary:

    One problem with the solution you posted is that it may not work in all cases--for example when virtual directories are being used with the webserver. In those cases the URL path is much different than the OS path.
  • jdbo #
    Commented on 05-08-2008 at 10:18 AM
    A related question (more theoretical than anything else, I've just always wondered if this can be done) - what if you have a template that is included by another template (i.e. via CFMODULE, CFINCLUDE, etc.) - is there a way to determine the path of the parent (calling) template? Or retrieve the stack of calling templates up to the base template?

    I'm wondering because the CFCATCH exception variable includes the complete calling stack (this is probably not the right term), and I could imagine some potential uses for accessing that info at runtime.

    ( Note: I'm thinking of something more elegant than throwing an exception and extracting the data from the CFCATCH variable; I write some ugly code, but that seems like overkill. )
  • Commented on 05-08-2008 at 10:19 AM
    @Dan,

    Thats very true, but then you could also use the PATH_INFO cgi variable to give you the relative path to the executing page, id does give you the page as well but you could also quite simply remove it.

    PATH_INFO=/mycf/samples/index.cfm

    But it really depends on what you are looking for as you mentioned in your first post, the os path or the web path
  • Commented on 05-08-2008 at 10:23 AM
    @Gary:

    Just a heads up that not every webserver will populate the cgi.path_info. I believe IIS might be the only webserver that does. You always have to be a bit wary when using CGI variables, since what's returned varies by webserver.
  • Commented on 05-08-2008 at 10:24 AM
    @jdbo:

    Yep. getBaseTagList will give you a list of everyone above you. To get the guy right above you, it would just be the last item.
  • Commented on 05-08-2008 at 10:29 AM
    Just to mix things up a bit, and I've been doing some url rewrites & php lately, what kind of curveball does this throw here(of course in CF)? Where according to the web root we might see

    /dir1/dir2/what-im-viewing

    but it might actually be

    /some/dir/index.cfm

    I'm actually not at all familiar with rewrites and ColdFusion, and I am asking this out of curiosity. Would the solutions provided be fore the actual url, or the rewritten url?
  • Commented on 05-08-2008 at 11:28 AM
    I think Patrick is actually looking for this:

    <cfset thisDirectory = ExpandPath(".")>
    <cfoutput>#getFileFromPath(thisDirectory)#</cfouptut>
  • Commented on 05-08-2008 at 11:34 AM
    Just in case people are actually wanting to get the "web path" and not the OS path, I wiped up a little UDF that should return the correct web path:

    http://blog.pengoworks.com/index.cfm/2008/5/8/Gett...

    This uses the getPageContext() to return the path info--which should be more reliable than CGI.path_info.

    @Trent:
    This *should* work for virtual or remapped folders as well (since it should be return the path as seen by the browser,) but I have not tested it.
  • Rachel #
    Commented on 05-08-2008 at 11:37 AM
    A clever developer once showed me a handy trick for dealing with paths - and getting certain parts - by using list functions (listFirst,listLast,listGetAt) and passing slashes (back or forward) as a delimiter in the list. As someone else mentioned, it all depends on what you're trying to get, but I have found that trick quite useful.
  • Patrick #
    Commented on 05-08-2008 at 12:33 PM
    Hi @ all and thanks for all the hints.
    Ray wrote me, i should use listlast(application.directory,"/\"), 'cause i have set this:
    <cfset application.Path = ExpandPath(CGI.SCRIPT_NAME)>
    <cfset application.Directory = GetDirectoryFromPath(application.Path)>

    What i need is the path relative to the executed template.
    So if my URL is www.example.com/some/other/folders/index.cfm
    I only want folders. The listlast works, but only if i'm in a subdirectory. Calling the listlast from the webroot returns htdocs, of course. But this can be handled.

    My problem is, that i don't know if the project i'm currently work on, will be placed in the webroot or in some subfolder(s).
  • Commented on 05-08-2008 at 12:38 PM
    Patrick, I read your comment 3 times and I'm still confused. What do you mean "I only want folders". Maybe you can give us an example of the result you want? Ie a real example. (Url = x, I want y).
  • Patrick #
    Commented on 05-08-2008 at 12:42 PM
    Me again. I now tried the UDF from Dan. This exactly what i searched for! Thanks!!
  • Patrick #
    Commented on 05-08-2008 at 1:12 PM
    @ Ray

    If the URL is www.example.com/shop/products/computers/index.cfm

    I want computers. With / or not never mind. (hope this is correct english, i'm german ;))
  • Commented on 05-08-2008 at 1:17 PM
    @Patrick,

    Did you see my comment? It gives you just that without having to use a UDF.

    I blogged it at http://www.stephenwithington.com

    If you use this:

    <cfset thisDirectory = ExpandPath(".") />
    <cfoutput>#getFileFromPath(thisDirectory)#</cfoutput>

    The result is "folder"
  • Commented on 05-08-2008 at 1:23 PM
    Ditto Steve. You could also use the code I originally suggested, but add the listLast to get the last folder. Steve's is shorter though.
  • Commented on 05-08-2008 at 1:24 PM
    By the way, it's nice to know this 'simple' blog entry has gotten so much discussion. ;)
  • Patrick #
    Commented on 05-08-2008 at 1:30 PM
    @ Steve
    Sorry, i missed your post. It's another good solution, of course!
  • jdbo #
    Commented on 05-08-2008 at 2:50 PM
    @ray re:getbasetaglist

    Thanks! I'd never looked closely at this tag, always having considered it one of the odder additions - now I see how it could be useful, thanks!
  • Commented on 05-09-2008 at 10:07 AM
    @Steve:

    The only issue with your solution is it does not work if you're using virutal folders or using a remapping rule. If those are an issue, it works fine.

    I wrote the UDF with the intent on working on the actually URL in the browser--which can vary drastically from the OS path.
  • Commented on 09-18-2008 at 9:53 PM
    <h5>&#171; &#171; &#171; <cfset up = ExpandPath(".")><a href="./")"><cfoutput>#getFileFromPath(up)#</a></cfoutput></a> </h5>

    Bread Crumbs ... :)

Post Reply

Please refrain from posting large blocks of code as a comment. Use Pastebin or Gists instead.

Leave this field empty