1

FW/1 seems to be oriented to returning complete web pages what if JSON data is needed? A typical layout looks like:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
   <title>User Manager</title>
   <link rel="stylesheet" type="text/css" href="assets/css/styles.css" />
</head>
<body>


<h1>User Manager</h1>

<ul class="nav horizontal clear">
<li><a href="index.cfm">Home</a></li>
<li><a href="index.cfm?action=user.list" title="View the list of users">Users</a></li>
<li><a href="index.cfm?action=user.form" title="Fill out form to add new user">Add User</a></li>
<li><a href="index.cfm?reload=true" title="Resets framework cache">Reload</a></li>
</ul>

<br />

<div id="primary">
    <cfoutput>#body#</cfoutput>
</div>

</div>

</body>
</html>
James A Mohler
  • 11,060
  • 15
  • 46
  • 72

3 Answers3

9

As of FW/1 2.2, you can call:

variables.fw.renderData( "json", result );

in your controller and it will do what you want.

Sean Corfield
  • 6,297
  • 22
  • 31
4

I have used code that overrides the onMissingView() method of Framework.cfc.

I wrap my response up in a variable named rc.json then use code similar to this in my Application.cfc.

function onMissingView( rc ){
    if( structKeyExists( rc, 'json' ){
        var response = getPageContext().getresponse()
        response.setContentType( 'application/json' );
        return serializeJSON( rc.json );
    }
    else{
        //we need this to fire off valid onMissignView error.
        raiseException( "FW1.viewNotFound", "Unable to find a view for '#request.action#' action.", " '#request.missingView#' does not exist.");
    }
}

I use other logic to do a cfdump of rc.json when request is not an AJAX request. But this is scaled down to bare minimum.

Scott Stroz
  • 7,510
  • 2
  • 21
  • 25
  • I like that you done need a file in the views directory. My approach requires a blank file view file and a layout. I can see that yours doesn't. – James A Mohler Aug 26 '13 at 16:57
  • I was not a fan of having an empty file in views either, that is what lead me to this solution. I have another method that checks if request is an AJAX request by checking header info and if we are in the 'dev' environment, and if so, do a cfdump of rc.json, other wise, it just returns the JSON. – Scott Stroz Aug 26 '13 at 16:59
  • How do you stop the layout from running? – James A Mohler Aug 26 '13 at 22:34
  • 1
    I typically route all requests that will return JSON through a single controller, and in that controller's `before()` method, I do `request.layout=false;` – Scott Stroz Aug 27 '13 at 02:46
1

This will do it

<!--- Load all variables into response rather than just rc --->
<cfparam name="rc.response" default="#structNew()#">
<cfparam name="rc.response.status" default="OK">

<!--- Stop layouts from cascading --->
<cfset request.layout = false>

<cfsetting showDebugOutput="No">
<cfheader name="Content-Type" value="application/json" />

<cfoutput>#SerializeJSON(rc.response)#</cfoutput>
rrk
  • 15,677
  • 4
  • 29
  • 45
James A Mohler
  • 11,060
  • 15
  • 46
  • 72