So as I announced in my last entry, I’ve been working on something called Foundry for CF. Foundry’s aim is to provide a platform for modular CF applications and utilities.
It is not a framework used for building a full blown web application. It doesn’t have ORM, databases, controllers, views, etc. It serves a different purpose.
But I’m not going to talk about Foundry today, I’m going to talk about 1 piece of Foundry, the Path module.
Now, Most of us have used ColdFusion’s nice and convenient cfdirectory, cffile, and path functions. These are great, and perfect for what they do and what most people need them for. But they aren’t infinitely useful for building paths, and manipulating hyphothetical path structures that may or may not exist. They are meant to work with the file system directly (generally).
Almost lost sight of the topic again… sorry…
The Path.cfc component of Foundry Core is a direct port of the Node module to CF.
This module is incredibly useful and is used in like 90% of all Node modules so therefor it was a natural fit in Foundry.
Path.cfc is fairly self explanitory for the most part, it deals with… well paths.
But not PHYSICAL paths that exist on the drive, but paths that could or may exist.
Let’s start with a few examples…
Let’s say you would like to step up 3 directories of a given path string.
Ideally, in a terminal, you would take your current directory and type “cd ../../../” and instantly be taken to that directory.
In ColdFusion, you could do this with something like so:
This definitely would work… but… not very elegant or clean.
With Foundry Path module, you would just type:
//given the path /Users/rountrjf/Projects/my_cool_app/
<cfset myPath = Path.resolve("/Users/rountrjf/Projects/my_cool_app/test/what/hotness,'../../../') />
<cfoutput>#myPath#</cfoutput> <!--- output: /Users/rountrjf/Projects/my_cool_app/ --->
Now, you might say… well I could have done that by just typing
That’s true, but that only works for your current CF context and will only return the root of that context.
Path.cfc works with ANY PATH string, it’s aim is not to make or manipulate paths relative to any physical path, as stated before, it manipulates path strings.
Foundry is meant to do more than attach to your existing web applications, it’s meant to be a workhorse for building useful things that don’t always end up in a tag. It’s meant for doing heavy lifting and help you approach the problems of the next generation of CF.
<cfset myPath = Path.resolve('/Users/rountrjf/Projects/my_cool_app/test/what/hotness','../images/','../../','../controllers') />
This one is much harder to mentally wrap your head around outside of context of a terminal window but if you walk through it from left to right, you can resolve it…
So we start in the
hotness directory, and we type
That places us in the
images directory within the
what directory. So
From there, we
cd ../../ which would take us out of
images, and up 2 directories which would put us
Then we do a
cd ../controllers which would take us out of
test and up a directory, then into the
Our final resolved path should be
That’s just the
resolve function, and whether or not you find it applicable in your development will determine if you’re still thinking in the typical CF mindset of building streamlined web apps with a front end public purpose, versus a workhorse to help you develop useful extensions to CF.
This is quite the opposite of
Path.resolve() always returns an absolute path where relative’s goal is to give you a relative path.
Let’s say you need to determine what steps it would take to get to a path from another path… given the example above, let’s try this out…
<!--- grab the path module --->
<cfset path = new foundry.core.path() />
<!--- use it --->
<cfset myRelativePath = Path.relative('/Users/rountrjf/Projects/my_cool_app/test/what/hotness','/Users/rountrjf/Projects/my_cool_app/controllers') />
This statement will return the relative path to the
controllers directory based on the first path provided in
So let’s say we’re in
/test/what/hotness and we want to know the steps it takes to get to
controllers. The response would be
../../../controllers since controllers is in the
Easy, but not something you use everyday in regular CF apps probably until you start thinking about building other things with CF.
There are 7 functions in the Path.cfc and these are 2 of big ones.
Join is a very useful function.
It’s about the equivalent of the following:
<cfset myPaths = [
<cfset joinedPaths = arrayToList(myPaths,'/') />
Except for the fact that it actually cleans it all up and makes it valid based on your file system (windows or posix).
The result of the above example would be roughly
But if you use
<cfset joinedPaths = Path.join('/Users\rountrjf\','/Projects','\my_cool_app','/test','..') />
//or on windows
<cfset joinedPaths = Path.join('c:','Users/rountrjf\','/Projects','\my_cool_app','/test','..') />
This would return
/Users/rountrjf/Projects/my_cool_app on posix, or on Windows provided you added a
C: or something in front, you would get
It’s sort of like path.resolve, except it doesn’t need a from path, it simply joins all your paths by a separator and normalizes the output based on the current operating system it’s running on. (ie.
/ for posix and
\ for windows).
Also, it ignores non-string arguments.
If you just had a jumbled struct of mixed paths + arrays mixed in, it would ignore the arrays and join the paths.
The rest of them are much simpler in nature…
I’ll have you checkout the rest via Foundry documentation for more information.
Or, the node documentation too! It all applies.
Path module documentation for Foundry: