New features introduced with Railo
New Features for CFML with Railo
OK, new engine... New features? Absolutely.
Since we started developing Railo as an improvement of other CFML engines and ourselves beeing kind of fond to CFML, its only natural that we wanted our own small improvements to be included in Railo. So we tried to look for things that bother us when using CFMX or BD. Below you will find a list of my top 5 improvements in Railo compared to the other CFML engines.
1. Creating populated Arrays, Queries and Structs
With Railo you have a very easy way of generating populated Array, Queries or Structs. Just compare the following two code fragments:<cfset aNames = ArrayNew(1)>
<cfset aNames[1] = "John">
<cfset aNames[2] = "Tom">
<cfset aNames[3] = "Stephen">
<cfset stNames = StructNew()>
<cfset stNames.FirstName = "John">
<cfset stNames.LastName = "Wayne">
<cfset stNames.Children = ArrayNew(1)>
<cfset stNames.Children[1] = StructNew()>
<cfset stNames.Children[1].Name = "William">
<cfset stNames.Children[2] = StructNew()>
<cfset stNames.Children[2].Name = "Andrew">
Instead of this in Railo you can write the following:
<cfset aNames = array("John","Tom","Stephen")>
<cfset stNames = struct("Firstname":"John","Lastname":"Wayne","Children":array(struct("Name":"William"),struct("Name":"Andrew")))>
Or just imagine creating a Query from scratch:
<cfset qry = QueryNew("Name,Firsname,Age","String,String,Numeric")>
<cfset QueryAddRow(qry, 3)>
<cfset QuerySetCell(qry, "Name", "Wayne", 1)>
<cfset QuerySetCell(qry, "FirstName", "John", 1)>
<cfset QuerySetCell(qry, "Age", 47, 1)>
<cfset QuerySetCell(qry, "Name", "Riddle", 1)>
<cfset QuerySetCell(qry, "FirstName", "Tom", 1)>
<cfset QuerySetCell(qry, "Age", 16, 1)>
<cfset QuerySetCell(qry, "Name", "Potter", 1)>
<cfset QuerySetCell(qry, "FirstName", "Harry", 1)>
<cfset QuerySetCell(qry, "Age", 17, 1)>
Now the same thing in Railo:
<cfset qry = Query("Name":Array("Wayne","Riddle","Potter"),"FirstName":Array("John","Tom","Harry"),"Age":Array(47,16,17))>
Now that's a little shorter I guess. But this coding brings you one hickup. You will not be compatible to the other CFML engines unless you write three UDF()'s named Array() Struct() and Query() and build the functionality in there. But I guess it is not easy.
So just use Railo :-)
1a. The serialize function
Since this function is the reason we invented the functions array(), struct() and query(), I will address her a separate entry labeled 1a. This function turns everything it get's passed into a understandeable string. You can afterwards use this string in order to genearate the same variable content. Serialize() indeed generates correct CFCode. It is the opposite to evaluate(). Check this out:
<cfquery name="getBlogEntries" datasource="blog">
SELECT id, title FROM tblBlogEntries
</cfquery>
<cfdump eval="serialize(getBlogEntries)">
This ouputs the following:
| serialize(getBlogEntries) | |||
| |||
This feature can be wonderfully used when storing content in a CF way. You can also use CFWDDX but the created string can be used anywhere.
2. CFDUMP with attribute eval
This is a short but handy one. I use it so often that it's one of my favorite enhancements. The following code lines are identical:<cfdump var="#variables#" label="variables">
<cfdump eval="variables">
Short and easy. In addition to that Railo adds the function dump() to CFML which can be used inside CFScript and does exactly the same:
<cfscript>
dump(variables);
</cfscript>
<cfdump eval="variables">
3. Enhancement to <cfloop>
I have often read newgroup entries concerning the reading of large files (often logfiles) in order to do something with the content. This is not easy to do using CFML. You can use Java for this purpose but you have to know how. So we invented three new attributes to the tag cfloop. The following code will explain the functionality:
The lines in the log from Line 500 to 560 are:<br>
<cfloop file="myLogFile.log" index="line" startLine="500" endLine="560">
<cfoutput>#line#</cfoutput><br>
</cfloop>
The size of the file is not important. Railo loops row by row through the file and returns a line each loop iteration. Very handy.
4. <cffile action="info">
Very often you need to know the dimensions of images. Therefore you can use some java CFX or other Java code. With Railo you have the ability to read this information with the help of the tag cffile. The following example shows the usage:
<cffile action="info" file="railo.jpg" variable="info">
<cfdump eval="info">
The result is quite interesting:
| Contents of the variable "info": | |
| info.img.width: | Image width |
| info.img.height: | Image height |
| info.attributes: | File attributes |
| info.datelastmodified: | Date of last modification |
| info.name: | Filename |
| info.size: | Filesize in bytes |
5. <cfadmin>
In order to access the Railo environment, the settings for a global and a local web you normally use one of the administrators. This is good but not enough, if you would like an installation routine to add a mapping, a datasource or something else. Therefore other engines use kind of undocumented features, partly useable without even having to know the administrator password. I find this extremly risky. Since when I'm a hoster, I don't want anyone to mess around with the settings I made. Therefore we introduced the tag <cfadmin>.
This tag is the only connection Railo has to the user in order to allow him to change settings within Railo (Ok, you could change the corresponding XML files and restart the server, but this is not an issue). So if a user wants to change the behaviour of Railo at runtime, he has to do it with the help of the tag <cfadmin>. The tag allways requires the password for the corresponding administrator.
Since the tag is so powerful and has so many attributes and actions, I will adress him an extra blog entry in one of my future posts. To give you a taste of what the tag <cfadmin> is capable of doing here is a list of all supported actions:
| Possible actions for the tag CFADMIN | |||
| compileMapping | getLocales | removeMapping | updateDefaultSecurityManager |
| Connect | getMailServers | removeSecurityManager | updateJavaCFX |
| createSecurityManager | getMailSetting | removeUpdate | updateMailServer |
| defaultSecurityManager | getMappings | resetPassword | updateMailSetting |
| getComponent | getRegional | Restart | updateMapping |
| getContextes | getScope | runUpdate | updatePassword |
| getCustomTagMappings | getSecurityManager | securityManager | updatePSQ |
| getDatasource | getSerial | storageGet | updateRegional |
| getDatasources | getTimeZones | storageSet | updateScope |
| getDatasourceSetting | getTLDs | updateComponent | updateSecurityManager |
| getDebug | getUpdate | updateCustomTag | updateSerial |
| getDefaultPassword | hasPassword | updateDatasource | UpdateUpdate |
| getDefaultSecurityManager | removeCFX | updateDebug | verifyDatasource |
| getFLDs | removeCustomTag | updateDefaultPassword | verifyMailServer |
| getJavaCFXTags | removeDatasource | updateDefaultSecurity | |
BTW: The complete Railo Web and Server Administrators are written entirely with the help of the tag <cfadmin>. Well of course and with the help of HTML and other stuff. But there is no trick, no undocumented function used in these Administrators.



The blog post you were talking about for the cfadmin tag, will you ever write it? I can't find any documentation about railo's code; am I missing something?
Specifically, I want to use the 'enable/disable debug output' setting, and don't know where to start.
Could you help me out here?
Much appreciated!
In your blog entry you mention that you can use the CFADMIN tag to create a datasource. I see a getDatasource and a updateDatasource, but I do not see a setDatasource. How do I accomplish this?
Kind regards,
Erik-Jan
In the meanwhile, I found it out, blogged about it, and even wrote a component to enable/disable debug output in both Railo and Adobe CF: http://www.coldfusiondeveloper.nl/post.cfm/enable-...
But great to get your reply; you are everywhere :-)