In this installment of my CFML 101 series, I'm going to show you how you can read and update a INI file with just a very little bit of code. I'll have to admit, when I first tried to do this I was surprised at how simple it was. I guess I shouldn't have been surprised, though. Making hard things easy like this has always been one of the hallmarks of CFML. This is true regardless of whether you're using Adobe ColdFusion, Railo, or Blue Dragon. The CFML language is built in a way that allows you to accomplish a lot of work with just a little bit of code. So many things are just so neatly packaged together that all you have to do is call one tag or function, and it runs a whole whoost of java code behind the scenes for you.
To start off our example, we need to create an initialization file. The initialization file (or INI file as it's also referred to) is simply a file that stores entries and their values. Using an INI file is a quick and easy way to specify configuration settings for your application, things that you may not want to store in a database, but you also don't want to have to hard code them in your application. We'll call our file settings.ini, and it will contain the following:
Getting entries from our initialization file.
To interact with INI files, CFML has three built in functions: GetProfileString(), SetProfileString(), and GetProfileSections(). The first function, GetProfileString(), is used to read entries from the INI file. It takes three parameters: the path to the initialization file; the section your entry is in (in our case, [people]); and the name of the entry you want to read. Here's an example of how to use GetProfileString():
<cfset variables.cfgFile = getDirectoryFromPath(GetCurrentTemplatePath()) & "settings.ini">
<!--- get values from settings.ini file. --->
<cfset variables.firstName = GetProfileString(variables.cfgFile, "people", "firstName")>
In the above code, we tell GetProfileString() to look in our settings.ini file, and get the value of the "firstName" entry in our "people" section. This would set the variable "firstName" equal to the value "Homer".
Updating entries in our initialization file.
Now that we know how to read our initialization file, let's learn how to write to it. Let's say we want to change the value of our "firstName" entry. In order to do that, we'll need to take a look at the SetProfileString() function. SetProfileString() is used almost exactly as GetProfileString(), except that it takes a fourth parameter, which is the new value that you want to set. So, building off of our previous example, if you wanted to change the .ini entry "firstName" from "Homer" to "Bart", you would do so like this:
<cfset SetProfileString(variables.cfgFile, "people", "firstName", "Bart")>
After running the SetProfileString() function, if you were to look in the settings.ini file you would see that it now reads:
Likewise, if you were to run our first code example again, this time the variable "firstName" would be equal to the value "Bart" instead of "Homer".
But what about adding new entries?
Adding new entries to our initialization file is the easiest part of all. All you have to do is try to update a value that doesn't exist. If the entry you're trying to update isn't in the INI file, it will be created. Even if you try to update an entry and you specify a section that doesn't exist, both the section and the entry will be written to the initialization file for you. So, let's say we want to add new entries for "drink" and "hangout" to our settings.ini file, and we want them to be listed in a "favorites" section.
<cfset SetProfileString(variables.cfgFile, "favorites", "hangout", "Moe's Tavern")>
<cfset SetProfileString(variables.cfgFile, "favorites", "drink", "Duff Beer")>
Now if you were to look in the settings.ini file you would see:
See, wasn't that easy?
But wait, there's more!
Working with INI files is great, but the larger the files gets the more cumbersome it can be to work with. I mean, if you've got 50 entries in your file, you really don't want to have to code 50 cfset statement all calling GetProfileString(), do you? Well, neither do I. But don't fret, there's a nifty way to get all of the entries in your file and set them to variables. Remember I told you that there are three CFML functions for working with initialization files? Now we get to use the last one, GetProfileSections(); All this does is, you guessed it, return the sections of your initialization file (in our case, [people] and [favorites]). Specifically, it will return a structure with the section name as the key, and the list of entries under that section as the value of the structure.
So, armed with that info, here is how you would loop through all of the sections and entries in our INI file.
<!--- loop through .ini file and create variables. --->
<cfloop collection="#variables.profile#" item="variables.section">
<cfloop list="#variables.profile[variables.section]#" index="variables.entry">
<cfset variables[variables.entry] = GetProfileString(variables.cfgFile, variables.section, variables.entry)>
And there you have it. That last example will give you a variable for each entry in your INI file, named the same thing as that entry, with the value of that entry.
Aren't INI files fun?
This post is part of a continuing series of CFML 101 articles. My intent is to produce a blog series aimed at the beginning CFML developer, one which helps to explain basic techniques and concepts to those new to the CF world. The topics and examples covered in this series focus on the CFML programming language in general, not a specific application server. So whether you're using ColdFusion, Railo, or Blue Dragon (referred to as CF/R/BD) to run your CFML applications, these concepts still apply.