Tuesday, December 21, 2010

My Mini Library

Tuesday, November 16, 2010

Link Dump (11-16-2010)

Facebook's New Real-time Messaging System: HBase to Store 135+ Billion Messages a Month
"Keeping with their small teams doing amazing things approach, 20 new infrastructures services are being released by 15 engineers in one year." Also, very interesting that Facebook chose HBase over their own Cassandra.

Instant Previews: Under the hood
Google uses base64 encoded data URIs to display the instant preview images rather than static images to reduce the number of web requests. "...even though base64 encoding adds about 33% to the size of the image, our tests showed that gzip-compressed data URIs are comparable in size to the original JPEGs."

10 Random CSS Tricks You Might Want to Know About
Target IE6 and IE7 without conditional comments: add a * before the property for IE7 and below, add a _ before the property for IE6 and below.

Yet Another Flavour of GORM: MongoDB
Very cool to see Grails support MongoDB, although it would be cooler if Hibernate had native support for more NoSQL databases.

Why Products Suck (And How To Make Them Suck Less)
"People only complain about things that matter to them; better to have complaints than disinterest. And not all complaints are equal: complaints that you don’t support feature X are far better than complaints about how feature Y sucks."

Monday, November 15, 2010

ColdMVC Plugins and Cells in Rails

I haven't posted in awhile because I haven't felt like I've had anything good to write about, but I've been reading Pragmatic Thinking and Learning: Refactor Your Wetware and one trick to getting over a writer's block is to just write for the sake of writing. So that's what I'm going to attempt to do in the coming weeks.

Lately I've been continuing to work on ColdMVC, my convention-based framework for ColdFusion inspired by Ruby on Rails and Grails. I've mainly been working on updating the plugin architecture for ColdMVC, with a focus on keeping things modular. I've also split out all of the plugins to their own repositories on GitHub to try to make things easier to manage. Right now they all follow a "ColdMVC-{Plugin}" naming convention and can be found here.

I'm also trying to get an official ColdMVC website up with some documentation and links to all the various plugins, but haven't quite got around to it yet.

On a final note, I've found a couple really good blog posts talking about cells in Ruby on Rails.



I quickly threw together a cells plugin for ColdMVC. I'm not sure how I feel about it yet, but at the very least it's an interesting concept.

Monday, August 23, 2010

Creating a LESS CSS Plugin for ColdMVC

One of the coolest things I've seen in awhile is LESS CSS, which "extends CSS with variables, mixins, operations, and nested rules". Barney Boisvert has blogged about using LESS with ColdFusion already, but I wanted to show an even simpler integration using my ColdMVC framework with a little help from around the web.

Assuming you already have ColdMVC up and running, your next steps will be to download JavaLoader and the LESS jar file. Next, we'll create a new ColdFusion project called ColdCSS, which contains the LESS jar file and a single component, ColdCSS.cfc.



Next, open your application's /config/plugins.cfm template and register the ColdCSS plugin. The path to your plugin might be different, but here's what it looks like if the ColdCSS project is in the same directory as your application.


<cfset add("coldcss", "../../coldcss/") />


Here's the content of the new component, ColdCSS.cfc:


/**
* @accessors true
* @singleton
*/
component {

property pluginManager;

/**
* @events applicationStart
*/
public void function generateFiles() {

var jars = [ getDirectoryFromPath(getCurrentTemplatePath()) & "lesscss-engine-1.0.22.jar" ];
var javaLoader = new javaloader.JavaLoader(jars, true);
var lessEngine = javaLoader.create("com.asual.lesscss.LessEngine").init();
var directories = pluginManager.getPluginPaths();
var i = "";

arrayAppend(directories, expandPath("/public/css/"));

for (var directory in directories) {

var files = directoryList(directory, true, "query", "*.less");

for (i = 1; i <= files.recordCount; i++) {

var source = files.directory[i] & "/" & files.name[i];
var destination = files.directory[i] & "/" & replaceNoCase(files.name[i], ".less", ".css");
var content = fileRead(source);

fileWrite(destination, lessEngine.compile(content));

}

}

}

}


Without going over the component line by line, here's how it works. When your application starts, ColdMVC will execute ColdCSS.generateFiles(), which will scan your application and all other registered plugins and find any files ending with a .less file extension, compile them to CSS using the LESS engine, and write them back to disk in the same folder as the original .less file, all in less than 50 lines of code.

Monday, August 16, 2010

Thoughts on Property Getters/Setters in ColdFusion

In ColdFusion 9, you can have ColdFusion automatically generate getters and setters for your properties by adding @accessors true to the component metadata. For example, the following two code snippets are practically identical.


component {
public string function getFirstName() {
return variables.firstName;
}

public void function setFirstName(required string firstName) {
variables.firstName = arguments.firstName;
}
}



/**
* @accessors true
*/
component {
property firstName;
}


Nice. That's a lot less code. Now what happens if you have a business rule where you always need the first name to be capitalized. I know it's not the best real world example, but it's straightforward. Simple enough, just override the generated getter by defining your own getFirstName method.


/**
* @accessors true
*/
component {
property firstName;

public string function getFirstName() {
return ucase(variables.firstName);
}
}


Done. While that works and is the correct way of overriding the getter, it doesn't quite feel cohesive enough to me since the getter isn't visually tied directly to the property. I think it would be better if we were able to define the getters and setters as part of the property, similar to how other languages do it.


/**
* @accessors true
*/
component {

property firstName {
get: function() {
return ucase(variables.firstName);
}
}

}


Obviously this is just hypothetical syntax, but I think it reads a lot better.