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.

6 comments:

  1. Weird, version 1.0.22 LessEngine errors but I can load the severlet jar fine through javaloader on CF8.

    Object Instantiation Exception.

    An exception occurred when instantiating a Java object. The class must not be an interface or an abstract class. Error: ''.

    The error occurred in C:\JRun4\servers\cfwheels\cfusion.ear\cfusion.war\plugins\javaloader\javaLoader\JavaLoader.cfc:

    ReplyDelete
  2. Figured it out. CF8 doesn't have the rino js.jar

    ReplyDelete
  3. Maybe this can be turned into a CFBuilder plugin??

    ReplyDelete
  4. Nice work! Thanks for sharing your ideas. Looking forward to reading more.

    ReplyDelete
  5. i think amazing work you r done..!

    ReplyDelete