Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Introducing FW/1 – Framework One

Why FW/1? Read the introductory blog post about the framework.

Once you’ve read this Getting Started guide, you’ll want to move on to the Developing Applications Manual and when you need to look things up, use the Reference Manual. You may also want to learn about Using Subsystems which allows FW/1 applications to be combined as modules of a larger FW/1 application.

You probably also want to join the FW/1 mailing list on Google Groups or follow the #FW1 twitter stream; you may also find help and inspiration in the FW/1 Site Showcase, a directory of sites created with FW/1. To read about what’s coming in the future, take a look at the Roadmap.

Getting Started

Requirements

  • v2.x supports:
    • ColdFusion 9.0.1 or later
    • Railo 3.2.2 or later (Railo 3.3 or later is recommended)
  • v1.2.1 supports:
    • ColdFusion 8.0.1 / 9.0.
    • Railo 3.1.x
    • OpenBD 1.2 nightly build 11/30 or later! * note: user manager example will not run on OpenBD *

Overview

FW/1 consists of a single CFC: org.corfield.framework

If you check out FW/1 from git, it’s a complete web application. The org folder should be in your webroot (or accessible via a mapping).

Note: do not install FW/1 into a subfolder that contains . in the name as this will prevent CFC resolution from working!

The simplest FW/1 application comprises:

  • Application.cfc which extends org.corfield.framework
  • Empty index.cfm
  • views folder containing a main subfolder containing default.cfm – your initial application view

Pages are accessed using ?action=section.item in the URL which will display the views/section/item.cfm file. The default action is main.default, as you might have guessed from the simplest FW/1 example above! If you specify just the section name – ?action=section then the item has the default of default, in other words, ?action=section is equivalent to ?action=section.default.

If your application server supports it, so-called SES URLs can be used with FW/1:

  • index.cfm/section – equivalent to ?action=section
  • index.cfm/section/item – equivalent to ?action=section.item
  • index.cfm/section/item/name/value – equivalent to ?action=section.item&name=value

To use name/value pairs in SES URLs, you must specify both the section and item parts of the action. A trailing name with no value is treated as &name= in a normal URL.

Create Application.cfc containing:

<cfcomponent extends="org.corfield.framework">
</cfcomponent>

Create an empty index.cfm file.

Create views/main/default.cfm containing:

Hello FW/1!

When you access the application, it should say Hello FW/1!

Adding a Controller

When you ask for action=section.item FW/1 looks for section.cfc in a controllers folder and, if present, invokes the item() method on it (and then displays the matching view). Since the default action is main.default, here’s what we need to do to add our default controller:

Change views/main/default.cfm to contain:

<cfoutput>Hello #rc.name#!</cfoutput>

Add controllers/main.cfc with a method, default(), that takes a single struct argument called rc (for request context) and then add:

<cfparam name="rc.name" default="anonymous">

to that function. Note that controller CFC names must be all lowercase.

When you access the application now, it should say Hello anonymous! but if you put ?name=Sean on the URL, it should say Hello Sean! The request context passed to the controller contains all the URL and form variables from the browser and is also made available to the view directly.

Controllers are cached. Add ?reload=true to the URL to reload your controllers.

Adding a Service

Whilst you can keep adding functionality to your controllers, a well-structured MVC application tries to keep the controllers lightweight and delegate all the business logic to the “Model” of your application. The Model is generally exposed to your controllers through a service layer. FW/1 has a convention for services: CFCs in a folder called services which can be invoked through a method in the framework. In order to do that, your controller needs a constructor which takes FW/1 as an argument and stores it in variables scope, like this:

function init( fw ) {
    variables.fw = fw;
}

Now, inside your default() controller method, remove the cfparam and put in a call to a service:

variables.fw.service( "name.default", "name" );

This tells FW/1 to queue up a call to the default() method in the name.cfc service. When FW/1 calls the service, after the controller method has completed, it will put the result in rc.name. FW/1 passes the request context to the service as a set of named arguments (so the service accessing named elements of the request, not the request context itself). Now we’ll add that service. Create a services folder and put a name.cfc file in it containing this:

component {
    function default( string name = "anonymous" ) {
        return "so-called " & name;
    }
}

Your views/main/default.cfm file should already contain this:

<cfoutput>Hello #rc.name#!</cfoutput>

When you access the application now with ?name=Sean on the URL, it should say Hello so-called Sean!

Services are cached. Add ?reload=true to the URL to reload your services.

Prior to FW/1 2.0, a service method was automatically called, with a name that matched the action and the result was placed in rc.data. FW/1 1.2 introduced a configuration variable to control this behavior and that variable is still present in 2.0, but the default behavior has changed so that service methods are not called automatically.

Adding a Layout

When you ask for action=section.item FW/1 looks for layouts/section/item.cfm to find a specific layout (it also knows how to look for default layouts for sections and for applications, I’ll cover that later). The basic view is passed in as a variable called body. Let’s try this for our default action, main.default:

Create layouts/main/default.cfm containing:

<h1>Welcome to FW/1!</h1>
<cfoutput>#body#</cfoutput>

Layout filenames, like view filenames, must be all lowercase.

When you access the application now, it should have Welcome to FW/1! as a heading above the previous output.

Next Steps

Read the Developing Applications with FW/1 and Using Subsystems with FW/1 sections below. The Reference Manual is a work in progress.

Developing Applications with FW/1

For an example-based approach to building applications with FW/1, read the Developing Applications Manual.

Using Subsystems with FW/1

FW/1 allows you to combine applications in a modular fashion to create a larger application. This feature was primarily contributed by Ryan Cogswell with documentation by Dutch Rapley. Read about Using Subsystems to combine your FW/1 applications.

Reference Manual

For a detailed description of the framework’s API, read the Reference Manual.

Something went wrong with that request. Please try again.