Over a million developers have joined DZone.

ColdFusion UI The Right Way: HTML version

DZone's Guide to

ColdFusion UI The Right Way: HTML version

· Java Zone ·
Free Resource

Verify, standardize, and correct the Big 4 + more– name, email, phone and global addresses – try our Data Quality APIs now at Melissa Developer Portal!

Back when Adam Cameron and I launched the ColdFusion UI - The Right Way project, I mentioned that initially we would accept submissions from the community to build out the content before releasing an actual readable version. Turns out I kind of forgot to get around to doing that. The content in the GitHub repo is in Markdown, which is pretty readable, but it isn't exactly in a nice form to hand out to a junior developer.

Earlier this week I got off my rear and actually built a process to make this happen. I decided to give Grunt a try for the process and it worked out rather well. I did run into a few stumbling blocks but I was able to get past them all and I'm very happy with the result. My Grunt script now does all the following with one simple command:

  • Clean out an output directory (to remove earlier versions)
  • Convert the Markdown files to HTML using a template
  • Find the demo folders and zip them
  • Attach a bit of HTML to the files so that folks have a link for the download

I decided to put the output up on a S3 bucket. You can now read the docs here: http://static.raymondcamden.com/cfuitherightway/. I'll update the GitHub readme in a few moments to add this link as well. I'm tempted to extend my Grunt script to also push updates to S3. Heck, I could also have it do the git pull action as well. Anyway, for folks who may be curious, here is the script I'm using.

module.exports = function(grunt) {

	// Project configuration.
		pkg: grunt.file.readJSON('package.json'),

		clean: ['./output/'],

		copy: {

			main: {

				files: [

					{expand:true, src:['./chapters/**','!./chapters/**/*.md'], dest: 'output/'} 


			all: {
				files: [
						expand: true,
				options: {
					preCompile:function(src, context) {
					postCompile:function(src, context) {
						Unfortunately we don't have access to the current path, 
						so no easy way to skip index.html and introduction.html
						//set title back to blank
						context.title = "";
						if(src.indexOf('<h1 id="introduction">Introduction</h1>') >= 0) {
							context.title = "Introduction";
							return src;
						if(src.indexOf('<h1 id="coldfusion-ui-the-right-way">ColdFusion UI - The Right Way</h1>') >= 0) {
							context.title = "ColdFusion UI - The Right Way";
							return src;

						var dl = '<p style="text-align:right"><a class="btn btn-info" href="demos.zip">Download Demo</a></p>';
						src = dl + src;

						var titleArr = src.match(/<h1.*?>(.*?)<\/h1>/);
						if(titleArr && titleArr.length >= 2) context.title=titleArr[1];

						return src;
					markdownOptions: {

	grunt.registerTask('zipDemos', "Zips demos appropriately.", function() {
		var sourceDirs = grunt.file.expand(['./chapters/**/demos','./chapters/**/demo']);
		var zipConfig = {};
		sourceDirs.forEach(function(dir) {
			var outputZip = dir.replace("chapters", "output/chapters");
			//use a uniform demos.zip, not demo
			if(outputZip.charAt(outputZip.length-1) === "o") outputZip += "s";
			outputZip += ".zip";
			dir += "/*";
			zipConfig[dir] = {
			grunt.config.set('zip', zipConfig);


	grunt.registerTask('zipCode', ['zipDemos','zip']);

	// Default task(s).
	grunt.registerTask('default', ['clean','markdown', 'copy', 'zipCode']);

As always, any comments are welcome.

Developers! Quickly and easily gain access to the tools and information you need! Explore, test and combine our data quality APIs at Melissa Developer Portal – home to tools that save time and boost revenue. Our APIs verify, standardize, and correct the Big 4 + more – name, email, phone and global addresses – to ensure accurate delivery, prevent blacklisting and identify risks in real-time.


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}