Getting the URL/web folder path in ColdFusion

Posted by Dan on May 8, 2008 @ 12:33 PM

Raymond Camden blogged about a question someone had about getting the folder path for the current template. While Raymond addressed how to get the OS path, how would you get the URL path? So, if you had your user was on the URL http://www.example.com/some/folder/and/file.cfm, how would you go about getting the "/some/folder/and/" path?

While there are always many ways to solve a problem, I've tried to come up with a solution that should work for any version of ColdFusion from 6.0 and above. I wanted to avoid using CGI variables (since those vary by webserver,) so I went with using getPageContext() instead.

Here's the solution I wiped up:

<cffunction name="getWebPath" access="public" output="false" returntype="string" hint="Gets the absolute path to the current web folder.">
    <cfargument name="url" required="false" default="#getPageContext().getRequest().getRequestURI()#" hint="Defaults to the current path_info" />
    <cfargument name="ext" required="false" default="\.(cfml?.*|html?.*|[^.]+)" hint="Define the regex to find the extension. The default will work in most cases, unless you have really funky urls like: /folder/file.cfm/extra.path/info" />
    <!---// trim the path to be safe //--->
    <cfset var sPath = trim(arguments.url) />
    <!---// find the where the filename starts (should be the last wherever the last period (".") is) //--->
    <cfset var sEndDir = reFind("/[^/]+#arguments.ext#$", sPath) />
    <cfreturn left(sPath, sEndDir) />
</cffunction>

If you just call getWebPath() it will return the current web folder path for the current base template.

We use a regular expression to strip out additional path info information that can sometimes be present for people using SEO-friendly URLs. For example, the URLs on my site appear like: http://blog.pengoworks.com/index.cfm/2006/9/27/CFMX-UDF-Parsing-a-URI-into-a-struct which returns a path of /index.cfm/2006/9/27/CFMX-UDF-Parsing-a-URI-into-a-struct. We need the regex to find the last period in the string and assume everything else is additional path info. The default regex should work in the vast majority of cases, but you can adjust it for the corner cases.

You can also manually supply a path such as: #getWebPath('/index.cfm/2006/9/27/CFMX-UDF-Parsing-a-URI-into-a-struct')#. This would return "/" as the web path.

Anyway, hopefully some of you will find this little UDF useful.

Categories: HTML/ColdFusion, Source Code

12 Comments

  • Thanks Dan! That's exactly what i searched!
  • @Patrick:

    Glad that helped you!
  • something similar in flex? i find that an almighty PITA.
  • Dan, your the man.
    It wasn't exactly what I needed but I got the idea to use getPageContext().getRequest().getRequestURI() from you.

    Finally I think I have nailed a function to get the CurrentURL is all scenarios including sub folders etc. Heres the code:

    <cffunction name="GetCurrentURL" output="No" access="public">
        <cfset var theURL = "http">
        <cfif (cgi.https EQ "on" )><cfset theURL = "https"></cfif>
        <cfset theURL = theURL & "://#cgi.server_name#">
        <cfif cgi.server_port IS NOT 80 AND CGI.server_port IS NOT 443>
            <cfset theURL = theURL & ":#cgi.server_port#">
        </cfif>
        <cfset theURL = theURL & getPageContext().getRequest().getRequestURI()>
        <cfif len(cgi.query_string)><cfset theURL = theURL & "?#cgi.query_string#"></cfif>
        <cfreturn theURL>
    </cffunction>
  • @Topper:

    Just remember that CGI variables vary by web server--which is why I try not to rely on them to much. If you're dealing with an application that's in a very controlled environment it's usually not an issue, but it's something you always want to keep in the back of your mind.
  • I agree Dan.

    15 minutes after I posted the code above I rewrote the function. Here is a version that will work everywhere and doesn't reply on the CGI vars:

    <cffunction name="GetCurrentURL" output="No" access="public">
        <cfset var theURL = getPageContext().getRequest().GetRequestUrl()>
        <cfif len( CGI.query_string )><cfset theURL = theURL & "?" & CGI.query_string></cfif>
        <cfreturn theURL>
    </cffunction>

    Sweet sweet code. :)
    I must admit I got the idea to use the underlying java from Ben Nadel.
  • Topper, thank you for your code. Works great for me, and also allows me to get just the page name by taking out cgi.query_string and doing a quick string manipulation on the url.
  • Hey, Dan!

    Why not stick with getPageContext().getRequest(), this time for the getPathInfo() method, and use it to remove the junk at the end of the URI?

    My thought is to replace the last 2 lines of the function with this one:

    <cfreturn getDirectoryFromPath(left(sPath, len(sPath) - len(getPageContext().getRequest().getPathInfo()))) />
  • @Josh:

    That works provided you're only examining the current URL. It doesn't work if you need to try and get the root from an arbitrary URL:

    getWebPath2('/index.cfm/2006/9/27/CFMX-UDF-Parsing-a-URI-into-a-struct')

    I wanted to write a solution that could parse URLs outside of the current context.
  • Ah, right--indeed. I'm so stuck in my world of needing info on the current request that I forgot your function is more general. :) Well, for anyone reading this who does need the path for the current request (which I would imagine is much more common than needing the path for general URLs), note my approach--the nice thing about it is that you don't have to worry about passing in the extension or having it in the default RegEx. I think it's simple enough that you needn't create a UDF for it, but that's your call. Note that if you want to replace the work of Dan's entire UDF (again, this would only be for where you only are operating on the current request, not an arbitrary URL), you'll need to also include trim in your equation as such:

    trim(getDirectoryFromPath(left(sPath, len(sPath) - len(getPageContext().getRequest().getPathInfo()))))
  • Thanks for this simple function for grabbing a complete url. I needed it here at work and just added it to the site's functions so I can use it on any page! Grabbing the variables in the url as a complete string can come in handy...
  • Thanks a million, it works perfectly!

Comments for this entry have been disabled.