Mach-ii for newbies - part1 Getting started
Mach-ii for newbies - part1
Getting started
Written by Trond Ulseth

1. Introduction

Back in the good old days of my programming career, about 5 years ago, life was easy. Coming from a html/designer background (I actually started my learning with a web site on GeoCities and a copy of Paint Shop Pro) the path to learning ColdFusion was pretty easy going. The amount of online tutorials and paperback books being eager to teach me this fantastic way of programming my homepages almost moved me to my tears. It was just days before I had my own ColdFusion driven guestbook up and running.

I’ve been working as a web developer for about 4 years now, with more spaghetti code on my consciousness than any sane mind can bear to think about. But with ColdFusion MX came cfc’s, and even though it took a while before I discovered them, thanks to them I now find my code extremely tidier and easier to maintain, and I must say that to some degree my style of coding has evolved into some kind of framework which is pretty neat.

But, and there’s a big but, I have come to realize that there are far better ways of organizing code than I can ever hope of mixing together by my self. And after a lot of sniffing around (Google and Fullasagoog) and chatting for advice on IRC, I decided that I would dip my toes into the waters of the mach-ii framework (http://www.mach-ii.com).

However, being spoiled with mountains of books and terabytes of tutorials, I found the available documentation for mach-ii disappointingly lacking. This is not to say that there’s no documentation at all, but what I found I did not find very pedagogical for a total newbie to it. So after months of not quite getting started I decided. I will just dive into it and make a simple application, my good old guestbook, and write a tutorial as I go along. And hopefully other newbie’s, like me, will find this useful as well.

I must underline, I am learning as I’m writing, or writing as I’m learning. I can therefore not give any guaranty that what I am doing is totally best practices, or that I have so much understanding of what I’m doing that I explain it as clear as could be possible. I’ll try though to write in an easy to understand and slightly entertaining way.

I’m going to presume that you have a pretty good grasp of ColdFusion from before. I’m not going to explain ColdFusion tags and functions, variables and properties, what cfc’s are etc. This stuff is well covered from before in the before mentioned amount of books and existing tutorials.

2. Getting prepared

First go to the mach-ii code page (http://www.mach-ii.com/code.cfm) and download the latest version of the Framework Code (version 1.0.10 as I’m writing), and the Application Code Skeleton. Extract them into the home directory of your web server. On my machine they are placed like this:

C:\Inetpub\wwwroot\MachII
C:\Inetpub\wwwroot\MachAppSkeleton

This placement is what I’ll assume during the tutorial. It should not be hard to configure it to work in another set up, but I’m not going to cover that here (maybe in a later tutorial when I have to do it my self).

Now rename the MachAppSkeleton directory to MyGuestbook.

Open the Application.cfm file in the newly renamed MyGuestbook folder, and edit the name attribute of the cfapplication tag to “My Guestbook”.

<cfapplication name="My Guestbook" sessionmanagement="yes" />

Open the mach-ii.xml file in the config directory under MyGuestbook. Under properties change the application root value to /MyGuestbook

<properties>
   <property name="applicationRoot" value="/MyGuestbook" />
   <property name="defaultEvent" value="DEFAULT_EVENT" />
   <property name="eventParameter" value="event" />
   <property name="parameterPrecedence" value="form" />
   <property name="maxEvents" value="10" />
   <property name="exceptionEvent" value="exceptionEvent" />
</properties>

(There’s a closer explanation of these properties at the end of chapter 3)

Now if you open http://localhost/MyGuestbook you should get a blank page, with no errors.

However, blank pages can be rather boring after a while, and can under no circumstance be called a guestbook, so even if you hear the call of the sofa, you need to stay with me a while longer.

Everything in mach-ii is controlled by events. Or at least so I think. It might be that later on in the process we might find this to be wrong. But for now I will pretend it is so. So in order to show some content we need to specify the defaultEvent in the mach-ii.xml file (the mach-ii.xml file is pretty much the heart of the mach-ii framework – so don’t bother closing it. We will do pretty some stuff in here). Let us set the default event value to “showMain”.

<properties>
   <property name="applicationRoot" value="/MyGuestbook" />
   <property name="defaultEvent" value="showMain" />
   <property name="eventParameter" value="event" />
   <property name="parameterPrecedence" value="form" />
   <property name="maxEvents" value="10" />
   <property name="exceptionEvent" value="exceptionEvent" />
</properties>

Now we need to specify what the showMain event will do. Further down the mach-ii.xml file you’ll find the event handlers:

<!-- EVENT-HANDLERS -->
<event-handlers>
   <event-handler event=
"DEFAULT_EVENT" access="public">
   
<!-- any legal elements -->
</event-handler>

Let’s make some changes. We change the event to showMain (because that is the event we declared as default event just now) and put in an element called view-page:

<!-- EVENT-HANDLERS -->
<event-handlers>
   <event-handler event=
"showMain" access="public">
   <view-page name=
"mainTemplate" />
</event-handler>

As you probably can guess (at least I did, and I’m not among the sharpest knifes in the drawer), view-page tell the application what should be shown in the browser window.

There’s one little thing more we have to do in the mach-ii.xml file (I told you we were going to do pretty some stuff in here). Let’s go even further down to find the page views:

<!-- PAGE-VIEWS -->
<page-views>
   <page-view name=
"NEW_VIEW_NAME" page="/views/NEW_VIEW_FILE.cfm" />
   <page-view name=
"exception" page="/views/exception.cfm" />
</page-views>

Now let’s edit the name of the first page view to reflect the view we called from our showMain event, and make it call something more intuitive than NEW_VIEW_FILE.cfm:

<!-- PAGE-VIEWS -->
<page-views>
   <page-view name=
"mainTemplate" page="/views/mainTemplate.cfm" />
   <page-view name=
"exception" page="/views/exception.cfm" />
</page-views>

(We see that there’s another page view called exception there – let’s not bother about that. It’s probably there for a reason, and maybe we’ll stumble across it later)

Now the last thing we need to do in order to get something on the screen is to create the mainTemplate.cfm file and put it in the views folder. For now let’s make it simple:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>
My Guestbook</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body>
<h2>
Welcome to my Guestbook!</h2>
</body>
</html>

Now let’s open http://localhost/MyGuestbook and see if there’s some change. Voila! Not exactly rocket science though. Actually we would have accomplished the same just with the mainTemplate.cfm file. Oh well – we’ll just have to trust that there will be some payoff for the extra work further down the road.

Now let’s try to put some meat on the skeleton.

3. Getting started with mach-ii development

Now it’s time to start shuffling some data into our application. The first thing we’ll do is to give visitors the opportunity to add their messages to the guestbook.

Bellow the header in mainTemplate.cfm adds the following basic form:

<form method="post" name="msgForm">
   <fieldset>
      <legend>
Add your message</legend>
      Name:<br>
      <input name="name" type="text"><br>
      Email:<br>
      <input name="email" type="text"><br>
      Message:<br>
      <textarea name="message" cols="40" rows="5" wrap="virtual"></textarea><br>
      <input type="submit" name="Submit" value="Post message">
   </fieldset>
</form>

Before moving on to how we can make mach-ii aware of the data that is entered (notice we did not add any action attribute to the form yet), we need to have somewhere to store the data. In our case we’ll chose a database (an xml file would be another good option).

In my case I’ll make a MyGuestbook database in MySQL, for now with the following single table.

guestbook
id int(11) auto_increment, primary key
date datetime
name varchar(50)
email varchar(50)
message longtext

Here’s a table creation script:

CREATE TABLE 'guestbook' (
      'id' int(11) NOT NULL auto_increment,
      'date' datetime NOT NULL default '0000-00-00 00:00:00',
      'name' varchar(50) NOT NULL default '',
      'email' varchar(50) NOT NULL default '',
      'message' longtext NOT NULL,
      PRIMARY KEY ('id')
) TYPE=MyISAM AUTO_INCREMENT=1 ;

 

Have you created the database? Ok – then you must define the data source in the ColdFusion administrator. Let’s call it…. MyGuestbook (ok, I’m predictable here. I’ll let the mach-ii framework itself provide the excitement).

If you’re anything like me you are probably used to defining your dsn in the application.cfm file (something like <cfset db = “MyGuestbook”>). Not so in mach-ii. Here we’ll go back to the trusted old mach-ii.xml file (I think we have come pretty some way when we can refer to it as the trusted old...). Up in the properties section well add a property:

<properties>
    <property name=
"applicationRoot" value="/MyGuestbook" />
    <property name=
"defaultEvent" value="showMain" />
    <property name=
"eventParameter" value="event" />
    <property name=
"parameterPrecedence" value="form" />
    <property name=
"maxEvents" value="10" />
    <property name=
"exceptionEvent" value="exceptionEvent" />
    <!-- Application variables -->
    <property name=
"dns" value="MyGuestbook" />
</properties>

Now we’re ready to maneuver submitted messages into that database. We’ll start with the beginning. We need an action parameter for that form. Remember earlier I said that I think everything in mach-ii is controlled by events? We’ll remember that as we set the action parameter like this:

<form action="index.cfm?event=message.create" method="post" name="msgForm">

Also remember that events had associated event handlers. We now need to add an event handler for the message.create event.

<event-handler event="message.create" access="public">
    <event-bean name="message" type="MyGuestbook.model.message.message" />
    <notify listener="messageListener" method="createMessage" />
</event-handler>

Whoa – what’s happening here? In the event handler we worked with earlier we had a view-page method. That one we could understand without invoking too many of the little grey ones. Now we introduce two new ones which by first look are not that self explanatory. We are heading for slightly deeper waters.

The bean

The first new method in the event handler is “event-bean”. A bean is a cfc which models a single instance of an object. In our case the bean creates a message object from the info passed from the form. A bean consist of an init() method as well as so called getters and setters for each of the object attributes.

Let’s take a look at the code for our bean before I try to explain anything else (key word being try).

<cfcomponent displayname="message" hint="I model a single message">

    <cffunction name="init" access="public" returntype="message" output="false" displayname="Message Constructor" hint="I initialize a message.">
            <cfargument name="id" type="numeric" required="false" default="0" displayname="" hint="" />
            <cfargument name="date" type="date" required="false" default="#Now()#" displayname="" hint="" />
            <cfargument name="name" type="string" required="false" default="" displayname="" hint="" />
            <cfargument name="email" type="string" required="false" default="" displayname="" hint="" />
            <cfargument name="message" type="string" required="false" default="" displayname="" hint="" />

            <cfscript>
                variables.instance = structNew();
                setID(arguments.id);
                setDate(arguments.date);
                setName(arguments.name);
                setEmail(arguments.email);
                setMessage(arguments.message);

            </cfscript>

            <cfreturn this />
    </cffunction>

    <!--- GETTERS/SETTERS --->

    <cffunction name="getID" access="package" returntype="numeric" output="false" displayname="" hint="I return ID">
        <cfreturn variables.instance.id />
    </cffunction>

    <cffunction name="setID" access="package" returntype="void" output="false" displayname="" hint="I set ID">
        <cfargument name="id" type="numeric" required="true" />
        <cfset variables.instance.id = arguments.id />
    </cffunction>

    <cffunction name="getDate" access="package" returntype="date" output="false" displayname="" hint="I return date">
        <cfreturn variables.instance.date />
    </cffunction>

    <cffunction name="setDate" access="package" returntype="void" output="false" displayname="" hint="I set date">
        <cfargument name="date" type="date" required="true" />
        <cfset variables.instance.date = arguments.date />
    </cffunction>

    <cffunction name="getName" access="package" returntype="string" output="false" displayname="" hint="I return name">
        <cfreturn variables.instance.name />
    </cffunction>

    <cffunction name="setName" access="package" returntype="void" output="false" displayname="" hint="I set name">
        <cfargument name="name" type="string" required="true" />
        <cfset variables.instance.name = arguments.name />
    </cffunction>

    <cffunction name="getEmail" access="package" returntype="string" output="false" displayname="" hint="I return email">
        <cfreturn variables.instance.email />
    </cffunction>

    <cffunction name="setEmail" access="package" returntype="void" output="false" displayname="" hint="I set email">
        <cfargument name="email" type="string" required="true" />
        <cfset variables.instance.email = arguments.email />
    </cffunction>

    <cffunction name="getMessage" access="package" returntype="string" output="false" displayname=""

All ColdFusion Tutorials By Author: Trond Ulseth
  • Mach-ii for newbies - part1 Getting started
    The first in a series of tutorials explaining how to develop applications with the mach-ii framework. Written by a mach-ii newbie himself, this tutorials take on kind of a collaborative learning aproach.
    Author: Trond Ulseth
    Views: 31,760
    Posted Date: Saturday, January 15, 2005