| By Isaac Dealey | Article Rating: |
|
| February 1, 2006 02:15 PM EST | Reads: |
23,869 |
You might notice the string "/index/" in the path of the images used in the home page, and you'd be correct if you guessed this string matched the name of the base template (index.cfm). In this way, I can loosely couple the branding of images for different pages without needing to add any logic to the display or layout templates to handle the variance. This way I eliminated all image logic from the layout template.
Then there's the issue of layout in general. As a developer I tend to think about every application in terms of portability. Call me stubborn; I refuse to make assumptions about an application's operating environment. This is one of the many weaknesses of the original Pet Market application, which required that you either add a custom tag path in the ColdFusion administrator or put tags in the default custom tags directory, neither of which are solutions I'm willing to accept for an application I've written.
In the case of layout, the application uses a custom tag to create the bulk of the HTML on each page. The custom tag is used with an end-tag to wrap the content of each page. For my application, this custom tag wouldn't be necessary, although much of the same structure can be reused. I copied the /extensions/customtags/wrapper.cfm template from the original application to /_components/petmarket/_layout.cfm and changed the logic for the tag internally to use the variable variables.tap.layout (which has a value of "header" or "footer") instead of using the ColdFusion native variable thistag.executionmode. Once this was done I removed the custom tag references from all the other templates in the /_components/petmarket/ directory. I also removed the head, body. and HTML tags from the layout template, since these are generated by the framework, and moved the content of the embedded CSS style tags to the template /_components/petmarket/_htmlhead/100_petmarket.css (which is included by the framework automatically in the resultant HTML).
In all honesty this isn't the way I'd normally handle layout. There's nothing wrong with it per se, although the onTap framework includes an HTML library - a set of functions for generating modular displays in HTML format with much greater flexibility - and normally I'd use this library via an XHTML custom-tag to create and cache the layout and then insert the content for each page into the generated display structures. Although this technique is more extensible, I simply didn't have time to implement it for this article (and Simon requested that I use the original application's view layer).
The original Pet Market application also puts its ColdFusion Components (CFC) in a directory not below the web root, requiring the creation of a ColdFusion mapping to target these CFCs. The onTap framework has a central repository for CFCs and a custom function for targeting these components that allows the application to be moved to any environment and configured quickly and easily (no need to change the extends attributes of the various CFCs).
For this I copied the original application's /extensions/components/petmarket/ directory to /ontap/_components/_cfc/petmarket/ then located all references to the ColdFusion native CreateObject() function and replaced them with request.tapi.getObject() (the arguments did not change). I also would have changed any references to the cfobject tag or cfinvoke tags that might use cfc paths instead of instantiated objects (and replaced their paths with request.tapi.getCFC()), although these aren't used in the original Pet Market application, making such changes unnecessary.
Finally, the Pet Market application included an Application.cfm template in its root directory (above the web root) to execute code at the beginning of each request. Although the onTap framework has its own Application.cfc for handling the various application events (onApplicationStart, onApplicationEnd, onSessionStart, onSessionEnd, etc.), the structure of this template lets us easily migrate code from other applications used in their Application.cfc or Application.cfm templates by copying the code into an appropriate subdirectory. In the case of my Pet Market migration, I copied the contents of the original Pet Market Application.cfm template to the file /ontap/_components/petmarket/_application/100_petmarket.cfm. This template will execute at the beginning of each request when the base template is in the /ontap/petmarket/ directory.
By the time this template executes, however, the framework has already instantiated the application and so the cfapplication tag is no longer necessary and I deleted it. If I wanted to change the name of the application or its timeouts or session management settings, I'd make those changes by setting variables in the structure request.tap.cf.app (i.e., request.tap.cf.app.sessionmanagement = true) using code in the template /ontap/_components/_appsettings.cfm. (This template doesn't exist in the core components archive to safeguard against overwriting your project settings when upgrading to the latest framework core version.)
At this point, I could have left the files as they were and the application should work. I prefer, however, to have the /_components/ templates a little further segregated, so I renamed each of the templates in the /_components/petmarket/ directory to _process.cfm and put them in another subdirectory with the name of the original template, i.e., /cart.cfm is renamed to /cart/_process.cfm.
Now I have my desired file structure:
Object-Relational Mapping (ORM) and Data Access Objects (DAO)
ontap/
_components/
_cfc/
petmarket/
petmarket/
_application/
_htmlhead/
_images/
_layout.cfm
about/_process.cfm
cart/_process.cfm
index/
_images/
_process.cfm
etc/_process.cfm
petmarket/
about.cfm
cart.cfm
index.cfm
etc.cfm
The next task I tackled after moving and renaming all the original Pet Market files was to reinvent the manner in which the application accesses data. To be fair this wasn't entirely necessary. I could simply have left all the ad hoc SQL queries in place and claimed the application complete, although since I'm something of a perfectionist I wouldn't be happy with the application's existing structure for data access. The authors created a request variable (request.petmarketdb) for targeting the database with cfquery tags, which is a good start and where most applications end their encapsulation of datasources (not to be confused with encapsulation of SQL queries), although I'm personally unsatisfied with this minimalist approach. Instead, I created a Datasource Name (DSN) structure in the onTap framework for holding information about multiple databases, where I registered my Pet Market DSN (request.tap.dsn.petmarket).
I registered this structure in the request scope using the /ontap/_components/_appsettings.cfm template for general application configuration and then set about the task of replacing all the application's ad-hoc SQL queries with the onTap framework SQL-abstraction tools. By default these tools use the "primary" DSN (request.tap.dsn.primary) so if I want my SQL-abstraction code to access my new Pet Market DSN I have to include the DSN attribute or argument in each of the custom tags or function calls used to access this abstraction layer.
One way to reduce the amount of code needed to accomplish this task is to use a datasource.cfc provided by the framework and instantiate it with the name of the DSN I want it to use. Because I don't want to recreate this CFC on each request where I might need it, I create it in the application scope (application.petmerket.datasource) when the application starts by putting the object instantiation in the template /ontap/_components/_appstart/100_petmarket.cfm.
Once I started looking more deeply into the data access used in the Pet Market application, I realized that most of it could be replaced with standardized Object Relational Mapping (ORM) techniques. For this I used the onTap framework's dynamic inheritance tool in the soft constructor for most of the existing CFCs to extend the framework's Data Access Object (DAO) component (request.tapi.cfcExtend(this,"dao")) and eliminated a large amount of code from the CFCs that simply put data returned from ad hoc SQL queries into the "this" scope or a structure in the "this" scope.
Published February 1, 2006 Reads 23,869
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
- ColdFusion Developer's Journal Special Focus Issue: Frameworks
- "Frameworks" Focus Issue: TheHUB
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: Model-Glue
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: Mach-II
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: ColdSpring
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: Fusebox
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: SAM
More Stories By Isaac Dealey
Isaac Dealey has worked with ColdFusion since 1997 (version 3) for clients from small businesses to large enterprises, including MCI and AT&T Wireless. He evangelizes ColdFusion as a volunteer member of Team Macromedia, is working toward becoming a technical instructor, and is available for speaking engagements.
![]() |
SYS-CON Brazil News Desk 02/01/06 03:38:19 PM EST | |||
I must admit to having been excited at the prospect of the Pet Market frameworks project when Simon proposed it to us at the Fusebox & Frameworks Conference in September. I once tried to do something similar by creating a small blog application using the three popular frameworks that I was aware of at the time (Fusebox 3-4 and Mach-II) and the onTap framework. |
||||
![]() |
SYS-CON India News Desk 02/01/06 02:49:28 PM EST | |||
I must admit to having been excited at the prospect of the Pet Market frameworks project when Simon proposed it to us at the Fusebox & Frameworks Conference in September. I once tried to do something similar by creating a small blog application using the three popular frameworks that I was aware of at the time (Fusebox 3-4 and Mach-II) and the onTap framework. |
||||
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Betas Target RIAs and Cloud Computing
- Adobe Cans Another 9% of its Workforce
- Moyea DVD4Web Converter V2.0 Converts DVD to FLV Fast and Synchronously with Watermarks
- Adobe & Salesforce Cut Cloud Deal
- Adobe Fiddles with its Web Apps
- Hosting.com Launches ColdFusion 9 in the Cloud
- The Real Time Infrastructure Ultimatum
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Is Microsoft as Free as Open Source?
- Adobe Reader Sued
- The Planet Named “Bronze Sponsor” of Cloud Computing Expo
- Microsoft Expression Web Has Got Game
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Bruce Chizen Joins Voyager Capital as Venture Partner
- My Top Seven Wishes From Adobe MAX 2009
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- Constructing an Application with Flash Forms from the Ground Up
- AJAX World RIA Conference & Expo Kicks Off in New York City
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Personal Branding Checklist
- Adobe Flex 2: Advanced DataGrid
- Has the Technology Bounceback Begun?
- Building a Zip Code Proximity Search with ColdFusion
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- The Asynchronous CFML Gateway
- Web Services Using ColdFusion and Apache CXF























