ColdFusion UI The Right Way - HTML version

This post is more than 2 years old.

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: https://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.
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),

		clean: ['./output/'],

		copy: {

			main: {

				files: [

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

				]
			}

		},
		
		markdown:{
			all: {
				files: [
					{
						expand: true,
						src:'./chapters/**/*.md',
						dest:'output/',
						ext:'.html'
					}
				],
				options: {
					template:'template.html',
					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: {
						highlight:'auto'
					}
				}
			}
		}
	});

	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] = {
				cwd:dir,
				src:dir, 
				dest:outputZip
			};
			grunt.config.set('zip', zipConfig);

		});
	});

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

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

};

As always, any comments are welcome.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Dave White posted on 6/19/2014 at 10:24 PM

Hey that's cool Ray.
I thought the demo's would be runnable though.
I presume your "S3 Bucket" doesn't have a CF server.
I think runnable demo's would be good for people to see what the code actually does.
Or maybe your working on it and I have jumped the gun here.

Anyway the site is great and the cod much more readable.

Thanks Dude. :-)

Comment 2 by Raymond Camden posted on 6/20/2014 at 6:17 AM

Nope, S3 is *just* file storage - no code.

Comment 3 by Enrico Rosso posted on 6/20/2014 at 3:02 PM

Well Done!!!

Comment 4 by mark Fllewellen posted on 7/10/2014 at 12:10 PM

You can use s3 for hosting straight html, css and js....google it

Comment 5 by Raymond Camden posted on 7/10/2014 at 2:32 PM

Mark, I am using it.

Comment 6 by dawesi posted on 7/22/2014 at 1:17 AM

If you want any Sencha (ExtJS/touch) samples for it let me know.

Comment 7 by Raymond Camden posted on 7/22/2014 at 1:27 AM

Basically, whoever writes a section gets to do the sample. I didn't push one framework over another as I wanted folks to see a variety.

Comment 8 by Edward Beckett posted on 9/1/2014 at 6:35 AM

@Ray ...

Cool Stuff ... nitpick ... be careful with the greedy quantifiers... they can come back and bite ya in some cases... pluses are better alternatives than asterisks ...

/<h1.+?>?(.+?)<\/h1>/

Comment 9 by Edward Beckett posted on 9/1/2014 at 6:55 AM

Oops... stray '?'

/<h1.+?>(.+?)<\/h1>/

Comment 10 by Raymond Camden posted on 9/1/2014 at 10:20 PM

My concern was that there wouldn't always be something after the 1. I think Markdown is applying a class, but, wouldn't mine be safer if it didn't and the tag was *just* h1?