Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created August 2, 2023 12:19
My ColdFusion "Controller" Layer Is Just A Bunch Of Switch Statements And CFIncludes
component
output = false
hint = "I define the application settings and event handlers."
{
// Define the application settings.
this.name = "DigDeepFitnessApp";
this.applicationTimeout = createTimeSpan( 1, 0, 0, 0 );
this.sessionManagement = false;
this.setClientCookies = false;
// ... truncated code ....
/**
* I get called once to initialize the request.
*/
public void function onRequestStart() {
// Create a unified container for all of the data submitted by the user. This will
// make it easier to access data when a workflow might deliver the data initially
// in the URL scope and then subsequently in the FORM scope.
request.context = structNew()
.append( url )
.append( form )
;
// Param the action variable. This will be a dot-delimited action string of what
// to process.
param name="request.context.event" type="string" default="";
request.event = request.context.event.listToArray( "." );
request.ioc = application.ioc;
}
}
<cfscript>
// ... truncated code ...
request.template = {
type: "internal",
statusCode: 200,
statusText: "OK",
title: "Dig Deep Fitness",
assetVersion: "2023.07.22.09.54", // Making the input borders more intense.
bugsnagApiKey: config.bugsnag.client.apiKey
};
try {
// ... truncated code ...
// ... truncated code ...
// ... truncated code ...
// Now that we have executed the page, let's include the appropriate rendering
// template.
switch ( request.template.type ) {
case "auth":
include "./layouts/auth.cfm";
break;
case "blank":
include "./layouts/blank.cfm";
break;
case "internal":
include "./layouts/internal.cfm";
break;
case "system":
include "./layouts/system.cfm";
break;
}
// NOTE: Since this try/catch is happening in the index file, we know that the
// application has, at the very least, successfully bootstrapped and that we have
// access to all the application-scoped services.
} catch ( any error ) {
// ... truncated code ...
}
</cfscript>
<cfscript>
// In the root controller, we care about the FIRST index.
param name="request.event[ 1 ]" type="string" default="home";
</cfscript>
<cfscript>
switch ( request.event[ 1 ] ) {
case "auth":
include "./views/auth/index.cfm";
break;
case "exercises":
include "./views/exercises/index.cfm";
break;
// ... truncated code ...
case "workoutStreak":
include "./views/workout_streak/index.cfm";
break;
default:
throw(
type = "App.Routing.InvalidEvent",
message = "Unknown routing event: root."
);
break;
}
</cfscript>
<cfscript>
config = request.ioc.get( "config" );
errorService = request.ioc.get( "lib.ErrorService" );
logger = request.ioc.get( "lib.logger.Logger" );
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
request.template = {
type: "internal",
statusCode: 200,
statusText: "OK",
title: "Dig Deep Fitness",
assetVersion: "2023.07.22.09.54", // Making the input borders more intense.
bugsnagApiKey: config.bugsnag.client.apiKey
};
try {
param name="request.event[ 1 ]" type="string" default="home";
switch ( request.event[ 1 ] ) {
case "auth":
include "./views/auth/index.cfm";
break;
case "exercises":
include "./views/exercises/index.cfm";
break;
case "home":
include "./views/home/index.cfm";
break;
case "jointBalance":
include "./views/joint_balance/index.cfm";
break;
case "journal":
include "./views/journal/index.cfm";
break;
case "security":
include "./views/security/index.cfm";
break;
case "system":
include "./views/system/index.cfm";
break;
case "workout":
include "./views/workout/index.cfm";
break;
case "workoutStreak":
include "./views/workout_streak/index.cfm";
break;
default:
throw(
type = "App.Routing.InvalidEvent",
message = "Unknown routing event: root."
);
break;
}
// Now that we have executed the page, let's include the appropriate rendering
// template.
switch ( request.template.type ) {
case "auth":
include "./layouts/auth.cfm";
break;
case "blank":
include "./layouts/blank.cfm";
break;
case "internal":
include "./layouts/internal.cfm";
break;
case "system":
include "./layouts/system.cfm";
break;
}
// NOTE: Since this try/catch is happening in the index file, we know that the
// application has, at the very least, successfully bootstrapped and that we have
// access to all the application-scoped services.
} catch ( any error ) {
logger.logException( error );
errorResponse = errorService.getResponse( error );
request.template.type = "error";
request.template.statusCode = errorResponse.statusCode;
request.template.statusText = errorResponse.statusText;
request.template.title = errorResponse.title;
request.template.message = errorResponse.message;
include "./layouts/error.cfm";
if ( ! config.isLive ) {
writeDump( error );
abort;
}
}
</cfscript>
<cfscript>
param name="request.template.statusCode" type="numeric" default=200;
param name="request.template.statusText" type="string" default="OK";
param name="request.template.title" type="string" default="";
param name="request.template.primaryContent" type="string" default="";
param name="request.template.assetVersion" type="string" default="";
// Use the correct HTTP status code.
cfheader(
statusCode = request.template.statusCode,
statusText = request.template.statusText
);
// Reset the output buffer.
cfcontent( type = "text/html; charset=utf-8" );
include "./auth.view.cfm";
</cfscript>
<cfoutput>
<!doctype html>
<html lang="en">
<head>
<cfinclude template="./shared/meta.cfm" />
<cfinclude template="./shared/title.cfm" />
<cfinclude template="./shared/favicon.cfm" />
<link rel="stylesheet" type="text/css" href="/css/temp.css?version=#request.template.assetVersion#" />
<cfinclude template="./shared/bugsnag.cfm" />
</head>
<body>
#request.template.primaryContent#
</body>
</html>
</cfoutput>
<cfscript>
// Every page in the auth subsystem will use the auth template. This is exclusively a
// non-logged-in part of the application and will have a simplified UI.
request.template.type = "auth";
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
param name="request.event[ 2 ]" type="string" default="requestLogin";
switch ( request.event[ 2 ] ) {
case "loginRequested":
include "./login_requested.cfm";
break;
case "logout":
include "./logout.cfm";
break;
case "requestLogin":
include "./request_login.cfm";
break;
case "verifyLogin":
include "./verify_login.cfm";
break;
default:
throw(
type = "App.Routing.Auth.InvalidEvent",
message = "Unknown routing event: auth."
);
break;
}
</cfscript>
<cfscript>
authWorkflow = request.ioc.get( "lib.workflow.AuthWorkflow" );
errorService = request.ioc.get( "lib.ErrorService" );
oneTimeTokenService = request.ioc.get( "lib.OneTimeTokenService" );
logger = request.ioc.get( "lib.logger.Logger" );
requestHelper = request.ioc.get( "lib.RequestHelper" );
requestMetadata = request.ioc.get( "lib.RequestMetadata" );
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
request.user = authWorkflow.getRequestUser();
// If the user is already logged-in, redirect them to the app.
if ( request.user.id ) {
location( url = "/", addToken = false );
}
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
param name="form.submitted" type="boolean" default=false;
param name="form.formToken" type="string" default="";
param name="form.email" type="string" default="";
errorMessage = "";
if ( form.submitted && form.email.trim().len() ) {
try {
oneTimeTokenService.testToken( form.formToken, requestMetadata.getIpAddress() );
authWorkflow.requestLogin( form.email.trim() );
location(
url = "/index.cfm?event=auth.loginRequested",
addToken = false
);
} catch ( any error ) {
errorMessage = requestHelper.processError( error );
// Special overrides to create a better affordance for the user.
switch ( error.type ) {
case "App.Model.User.Email.Empty":
case "App.Model.User.Email.InvalidFormat":
case "App.Model.User.Email.SuspiciousEncoding":
case "App.Model.User.Email.TooLong":
errorMessage = "Please enter a valid email address.";
break;
case "App.OneTimeToken.Invalid":
errorMessage = "Your login form has expired. Please try submitting your request again.";
break;
}
}
}
request.template.title = "Request Login / Sign-Up";
formToken = oneTimeTokenService.createToken( 5, requestMetadata.getIpAddress() );
include "./request_login.view.cfm";
</cfscript>
<cfsavecontent variable="request.template.primaryContent">
<cfoutput>
<h1>
Dig Deep Fitness
</h1>
<p>
Welcome to my fitness tracking application. It is currently a <strong>work in progress</strong>; but, you are welcome to try it out if you are curious.
</p>
<h2>
Login / Sign-Up
</h2>
<cfif errorMessage.len()>
<p>
#encodeForHtml( errorMessage )#
</p>
</cfif>
<form method="post" action="/index.cfm">
<input type="hidden" name="event" value="#encodeForHtmlAttribute( request.context.event )#" />
<input type="hidden" name="submitted" value="true" />
<input type="hidden" name="formToken" value="#encodeForHtmlAttribute( formToken )#" />
<input
type="text"
name="email"
value="#encodeForHtmlAttribute( form.email )#"
placeholder="ben@example.com"
inputmode="email"
autocapitalize="off"
size="30"
class="input"
/>
<button type="submit">
Login or Sign-Up
</button>
</form>
</cfoutput>
</cfsavecontent>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment