css

Saturday, January 15, 2011

Convert a relative url to an absolute url in coldfusion

To my surprise there is not a default function in coldfusion that converts relative urls to absolute ones. So i created one. This function relies heavily on regular expressions. If you are not familiar with regular expression i suggest you do not change any of the functions that use it (like rereplace and refind). So use the function simply input the relative url and the absolute url the relative url comes from. E.g.
Relative url = "/example.html"
Absolute url = "http://www.example.com/a/b/c/index.html"
Result = http://www.example.com/example.html

Example call function
#regex_UrlRelToAbs('/example.html','http://www.example.com/a/b/c/index.html')#

Complete function
<cffunction name="regex_UrlRelToAbs">
 <cfargument name="RelativePath">
 <cfargument name="AbsolutePath">
 <cfset var tempstruct = structnew()>
 <cfset var AbsolutePath_arr = ''>

 <cfset RelativePath=ReplaceNoCase(RelativePath,"&apos;","'","ALL")>
 <cfset RelativePath=ReplaceNoCase(RelativePath,"&quot;","""","ALL")>
 <cfset RelativePath=ReplaceNoCase(RelativePath,"&lt;","<","ALL")>
 <cfset RelativePath=ReplaceNoCase(RelativePath,"&gt;",">","ALL")>
 <cfset RelativePath=ReplaceNoCase(RelativePath,"&amp;","&","ALL")>


 <cfif isvalid('url',RelativePath)><cfreturn RelativePath></cfif>
 <cfif refind('^\/\/',RelativePath)>
  <cfset RelativePath = rereplace(RelativePath,'^\/\/','','one')>
  <cfreturn "http://#RelativePath#">
 <cfif>

 <cfset tempstruct.domain =  reReplace(AbsolutePath,"(^\w+://)([^\/:]+)[\w\W]*$","\1\2","one") />

 <cfset AbsolutePath_arr = #refind("^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^##?\s]+)(.+)?(##[\w\-]+)?$",AbsolutePath,1,true)#>
 <cftry>
  <cfif AbsolutePath_arr.len[5] gt 0>
   <cfset tempstruct.folders =  #trim(mid(AbsolutePath,AbsolutePath_arr.pos[5],AbsolutePath_arr.len[5]))#>
  <cfelse>
   <cfset tempstruct.folders =  ''>
  </cfif>
  <cfcatch type="any">
   <cfset tempstruct.folders =  ''>
  </cfcatch>
 </cftry> 

 <cfif left(RelativePath,1) eq '/'>
  <cfreturn "#tempstruct.domain##RelativePath#">
 <cfelseif left(RelativePath,1) neq '.'>
  <cfreturn "#tempstruct.domain##tempstruct.folders##RelativePath#">
 <cfelse>
  <cfset regex_UrlProperties_oc = #arraylen(rematch('(\.\./|\./)',RelativePath))#>
  <cfset regex_UrlProperties_newF = ''>
  <cfloop from=1 to=#listlen(tempstruct.folders,'/')-regex_UrlProperties_oc# index="i"><cfset regex_UrlProperties_newF = "#regex_UrlProperties_newF##listgetAt(tempstruct.folders,i,'/')#/"></cfloop>
  <cfreturn "#tempstruct.domain#/#regex_UrlProperties_newF##rereplace(RelativePath,'(\.\./|\./)','','all')#">
 </cfif>
</cffunction>