Skip to content
seancorfield edited this page Aug 15, 2010 · 14 revisions

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.

Getting Started

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).

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

When you ask for action=section.item FW/1 also looks for section.cfc in a services folder and, if present, invokes the item() method on it, assigning the return value to rc.data. Whereas the controller method is passed a single argument (the request context), the service method is passed the elements of the request context as named arguments. The idea is that services are supposed to be independent of the framework and should be designed as a series of methods that take specific named arguments and return a calculated (or retrieved) value.

Since the default action is main.default, we add services/main.cfc with a method, default(), that takes a single string argument called name and then add:

<cfreturn "so-called " & name>

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

Change views/main/default.cfm to contain:

<cfoutput>Hello #rc.data#!</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.

In 1.2 you can suppress this convention by setting variables.framework.suppressImplicitService = true. In 2.0, this setting will be true by default and services will not be implicitly invoked unless you set it back to false.

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.