Category Archives: ColdFusion

Introducing the C.R.A.P. Framework for ColdFusion

The CRUD Access Protocol framework enables you to quickly and easily make your ColdFusion data available to web services securely.

It’s a framework for people who hate frameworks.

Let’s say, for instance, that you have 20 data tables in ORACLE that you want to be able to create new records, edit existing records, logically delete records, and read records (with pagination) through a javascript-based GUI and common interface. It also enables you to alias database column names in the event that an angry DBA decides to start renaming columns on you!

My framework can make this back-end process simple!

You simply need to generate a CFC that extends an AbstractGateway class and has the following properties:

  • tableName – the name of the table in the database
  • pkField – describes the primary key field, and whether it’s an autonumber/identity/sequence
  • relationships – (optional), describes the join conditions (supports inner and outer)
  • permissions – (optional), describes which user roles will be granted access to the create/read/update/delete methods.
  • columnmappings – describes each column, it’s data type, whether it’s writeable, and whether it should be encrypted in the database

A typical piece of CRAP would resemble the following:

<cfcomponent  output="false" 
              extends="components.components.gateway.AbstractGateway">

    <cfset this.tableName = "USA_CLAS">
    
    <cfset this.pkField = {
	 "columnName" = "#this.tableName#.CLASS_CODE",
	 "fieldName" = "code",
	 "type" = "VARCHAR"
    }>

    <cfset this.relationships = [
      {
	field1 = "#this.tableName#.CLASS_GROUP",
	field2 = "USA_CLAS_GROUP.GROUP_ID"
      }
     ]>

     <cfset this.permissions = {
  	"create" = "admin",
  	"read"   = "authenticated",
  	"update" = "admin",
  	"delete" = "admin"
     }>

    <cfsavecontent variable="this.columnMappings">
	 <cfoutput>
	 {
	   "code": {
		  "columnName": "#this.tableName#.CLASS_CODE",
		  "type": "VARCHAR",
		  "persist": true
	   },
	   "type": {
		  "columnName": "#this.tableName#.CLASS_TYPE",
		  "type": "VARCHAR",
		  "persist": true
	   },
	   "description": {
		  "columnName": "#this.tableName#.CLASS_DESC",
		  "type": "VARCHAR",
		  "persist": true
	   }
	   "group": {
		  "columnName": "#this.tableName#.CLASS_GROUP",
		  "type": "NUMERIC",
		  "persist": true
	   },
	   "createdBy": {
		  "columnName": "#this.tableName#.CREATED_BY",
		  "type": "VARCHAR",
		  "persist": true
	   },
	   "createdDate": {
		  "columnName": "#this.tableName#.CREATED_DATE",
		  "type": "TIMESTAMP",
		  "persist": true
	   },
	   "lastModifiedDate": {
		  "columnName": "#this.tableName#.LAST_MODIFIED_DATE",
		  "type": "TIMESTAMP",
		  "persist": true
	   },
	   "lastModifiedBy": {
		  "columnName": "#this.tableName#.LAST_MODIFIED_BY",
		  "type": "VARCHAR",
		  "persist": true
	   },
	   "active": {
		  "columnName": "#this.tableName#.ACTIVE_FLAG",
		  "type": "VARCHAR",
		  "persist": true
	   },
	   "groupName" : {
	      "columnName": "USA_CLAS_GROUP.GROUP_DESC",
	      "type": "VARCHAR",
	      "persist": false
	   }
    }
	</cfoutput>
    </cfsavecontent>

    <cfset this.columnMappings = deserializeJson(this.columnMappings)>

</cfcomponent>

After dropping your CRAP onto the server, you can make advanced data requests like the following:

 <cfset local.results = mycrap.read(
    start = 0,
    limit = 5,
    filters = [
      { property = "active", value="Y" },
      { property = "description", value="test", operator="like"}
    ],
    sorters = [
      { property = "code", direction="ASC" }
    ]
)>

Of course, you can also easily perform inserts, updates, and deletes…

  <cfset local.rec = mycrap.create("code" = "hey", type="example")>

Note that you only have to pass data to the create/update functions that has changed.

So keep an eye out for my C.R.A.P. — I’ll be posting it to Github within the next week after I, uh… clean it up just a little bit and enhance it with field-level and row-level security!

Developing Skills for Amazon Alexa with Adobe ColdFusion.

Topics include:

  • Creating Skills for Amazon Alexa
  • Using the Amazon Skills Kit (ASK)
  • Supporting Skill Cards
  • Developing Custom Skills
  • Developing Custom Intents
  • Defining Slots
  • Defining Utterances
  • Using Built-In Intents
  • Choosing the Invocation Name for a Custom Skill
  • Creating the ColdFusion Web Service to Handle Alexa Requests
  • Registering your Skill in the Developer Portal
  • Configuring your Endpoint
  • Testing the Skill

ss1

See the recorded presentation here:
http://experts.adobeconnect.com/p8zcgm583fx/

Download the source code here:
https://github.com/sdruckerfig/CF-Alexa

If you’d like to have an Alexa skill designed and developed by Fig Leaf Software, please mail us at info@figleaf.com.

ColdFusion and Node.JS – two great tastes that taste great together!

Fig Leaf Software recently delivered a hybrid ColdFusion – Node.js solution to one of our customers.

We decided to use a hybrid architecture for the following reasons:

  1. The customer expressed a preference for using ColdFusion to drive their CMS-based website.
  2. The website has several embedded, small AJAX applications that leverage data from an XML-based API that sits behind the customer’s firewall.
  3. Java-based app servers (ColdFusion) are particularly well-suited for dynamically assembling and serving web pages.
  4. Node.js servers are particularly good at implementing REST APIs and handling large volume, asynchronous data requests for non-cacheable dynamic data.
  5. The website/web apps do not require user authentication, therefore session sharing between different app server technologies was not an issue.
  6. Sharing the workload between CF and Node gives us more flexibility for scaling up the infrastructure in a more cost-effective manner with options for  potentially off-loading the Node service to cloud platforms such as Heroku.

wmata

 

CommonSpot Custom Field Crazyness!

We were recently tasked by the University of Wisconsin, Eau-Claire to produce a series of advanced custom elements to help their content contributors generate a Pinterest-style image grid.

There are three major components to the element:

  1. An image editor that allows contributors to upload an image and then pan/zoom/crop to a specific image size.
  2. An editor that allows contributors to overlay caption on top of the cropped image.
  3. Output of multiple cropped & captioned images into a responsive, pinterest-style display

Creating the Image Editor Custom Field

Starting from a codebase with limited pan/zoom cropping functionality (http://danielhellier.com/imagecrop/), we refactored the jQuery component to support fixed-sized crop areas as well as implement a bounding box and also tied in a slider component to enable easy-to-use zooming. We also added in the capability to transmit the scaling/cropping coordinates to an application server for server-side processing.

[Click here to play around with the proof-of-concept]

Adding Text Captioning by using a Draggable, Editable <h3> Element

For this project, we needed to give contributors the ability to place a text overlay on the image. The word “and” would need to be automatically converted to uppercase and have a style applied via CSS. To enable the users to choose a color, we used the spectrum plugin for jQuery which generally worked as advertised.

You can make editable <div> segments by simply adding a contenteditable attribute to a block element as illustrated below. The cropped image was simply placed behind the <h3> in the container

<div id="#fqfieldname#-container" style="width: #adjustedWidth#px; height: #adjustedHeight#px">
  <div id="#fqfieldname#-preview" style="border: 1px solid black">

	<h3 class="POAeditablelabel"
            id="edittext-#fqFieldName#" contenteditable
            onFocus="stripAnd(this)">#poaAttribs.text#</h3>

	<img id="#fqfieldname#-image"
	  style="width:#stParams.nWidth#px;
	  height: #stParams.nHeight#px;"
 	 <cfif poaAttribs.src is not ""> src="#poaAttribs.src#"</cfif>
        >

  </div>
</div>

We then applied jQuery UI’s draggable plugin to enable the user to drag the editable heading within it’s container:

	jQuery('##edittext-#fqFieldName#').draggable({ containment: 'parent', axis: 'y' })
  	.click(function() {
	  jQuery(this).draggable({ disabled: false });
	}).dblclick(function() {
	  jQuery(this).draggable({ disabled: true });
	});

Creating a Pinterest-Style Render Handler

Leveraging the jQuery isotope and jQuery lazyload plugins, Fig Leaf’s developers were able to devise an algorithm that would automatically resize images into a “pinterest”-style image grid in order to minimize the right margin space that typically results from implementing these types of layouts as well as work with the dyanamic text overlays required by the customer.

Every time the browser is resized, we dynamically rewrite the image CSS classes and then reinvoke the isotope plugin. The key javascript function, executed on browser resize, is illustrated here:

 

function generateStyles() {
 
 // get pointer to stylesheet			
 var ss = $("#POADynamicStyles"); 
 var container = $("#POAcontainer");
 var width = container.width();
 
// set minimum width of images to 160, maximum width to 201
 var minWidth = 160, maxWidth = 201, iWidth = 0;
				
				
 // figure out the optimal number of cols, given the available space
 for (var numCols=2; numCols<15; numCols++) {
   iWidth = Math.ceil(width / numCols);
   // console.log('cols', numCols, 'width', iWidth);
   if (iWidth <= maxWidth && iWidth >= minWidth) {
	break;
   }
  }
				
  if (numCols == 15) {
    numCols = 3;
    console.log('auto sizing failed');
  }
			
  // 10px margin around images
  var w1 = Math.floor(width / numCols) - 10;

  var reducePercentage = w1/250;
  var fontSize = reducePercentage * 2.7125;
  var lineHeight = 1;
  var heightOffset = 0;

  heightOffset = (-0.13 * (100 - (reducePercentage * 100)));

				
  var styles = ''.concat(
	'.item.w2  {width : {1}px;} \n',
	'.item.h2 {height: {1}px;} \n',
	'.item {width : {0}px; height: {0}px;}\n',
	'.item h3 {font-size: {2}rem; line-height: {3}; transform : translate(0px,{4}px)}'
   ).format(w1,w1*2+10,fontSize,lineHeight,heightOffset);
				
				
   ss.html(styles);
   initIsotope(w1 + 10);
			
}

[You can view an early proof-of- concept by clicking here].

Would you like to know more?

Contact Fig Leaf Software’s Professional Services group at info@figleaf.com to discover how we can help you achieve your CMS implementation goals.

Node.JS 101: Querying a Database and Outputting a Dynamic HTML Table with Express and Jade

Last night I gave a presentation about “What’s New in ColdFusion 11” to our ColdFusion meetup in DC. What’s new, of course, is that Adobe has put a lot of effort into making ColdFusion a lot more like JavaScript by significantly enhancing CFScript- an alternative to the ColdFusion Markup Language (CFML) that has syntax similar to JavaScript.

Of course, CFScript isn’t JavaScript. It’s not even similar to Microsoft’s jScript (shudder). And switching between CFScript programming and JavaScript programming is a little like switching between playing ping pong and playing tennis. They’re kinda similar, but playing a lot of ping pong is likely to screw up your tennis game, and vice-versa.

The fact of the matter is that if a CF developer really wants to program in Javascript, then they should just learn to stop worrying and take a close look at Node.JS. Node.js is a platform built on Chrome’s JavaScript runtime. It’s ridiculously fast and pretty straightforward to learn – assuming that you’re already familiar with basic JavaScript concepts.

For example, let’s take a look at a bit of Node code that queries a MySQL database table and subsequently transmits the results to a JADE template:


// create the connection 
var connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: ''
});

var sql = 'SELECT firstName,lastName from NodeJSExamples.Person';
connection.connect();

connection.query(sql, function(err, rows, fields) {
  if (err) throw err;
  res.render('users', { title: 'Users', rows: rows });
});

connection.end();

Pretty straightforward, right?

Now let’s take a look at the code that dumps out the rows into an HTML table via the Jade templating engine:

extends layout

block content
  h1= title
  p #{title} Listing

  table
    thead
      tr
        th First Name
        th Last Name
    tbody
      - each item in rows
        tr
          td= item.firstName
          td= item.lastName

Is this syntax superior (and even less verbose) than CFScript? You be the judge. And if you find yourself intrigued by the possibilities of Node.js, check out our new, no-nonsense, one-day instructor led course – Node.JS Fundamentals!

Simple barebones CF10/CF11 WebSocket Example

Here’s a bare-bones example of setting up an HTML5 WebSockets chat service using ColdFusion 10/11:

<!--- application.cfc --->
<cfcomponent>
  <cfset this.name = "Cf11Examples">
  <cfset this.wschannels = [{name="chat"}]>
</cfcomponent>
<!--- index.cfm --->
<cfwebsocket name="webSocketObj"
             onMessage="messageHandler"
             onError="errorHandler"
             onOpen="openHandler"
             onClose="closeHandler"
             subscribeTo="chat"/>
             
<doctype html>
<head>
	<title>WebSocket Example</title>
	<script type="text/javascript">
		
		messageHandler =  function(aEvent,aToken) {
		 
		  if (aEvent.data) {
           var txt=document.getElementById("msgArea"); 
           txt.innerHTML += aEvent.data  +"<br />"; 
          }
		}
		
		openHandler = function() {
			alert("Connection is open");
		}
		
		closeHandler= function() {
			alert("Connection Closed");
		}
		
		errorHandler = function() {
			alert("Doh!");
			console.log(arguments);
		}
		
		sendMessage = function() {
			var text = window.prompt("Enter some text","");
			if (text) {
				webSocketObj.publish("chat", text);
			}
		}
	</script>
</head>
<body>
 	<div id="msgArea" />
 	<input type="button" value="Send Message" onClick="sendMessage()">
</body>
</html>