At InVision, we use FrameworkOne (FW/1) as our ColdFusion / CFML web application framework. With FW/1, you can define a Controller, a collection of Views, and a Layout for a given feature-set. The Views get rendered and then "rolled up" into the Layout (optionally) at which point they are served to the client. Yesterday, I came up with a fun use-case for Layouts - I had to generate a View that had a lot of data on it (it was a report). So, in an effort to minimize the number of bytes that I was sending over the network, and to minimize the client-side DOM (Document Object Model) structure, I used the FW/1 Layout to strip out whitespace from the response. I had never used FW/1 in this way before; so, I thought it might make for an interesting demo in Lucee CFML 22.214.171.124.
With FW/1, each "subsystem" - which is a macro-organizational unit within the framework - has a directory structure that looks like this:
FW/1 is a convention-based framework, which means that the names of the various files and directories are used to auto-wire the response composition. In this case, the
my_feature.cfc is the Controller whose default method is
defult(). This method is automatically wired into the
default.cfm View, which is in turn, automatically rolled-up into the
When a View is being merged into a Layout, it is exposed to the Layout template as the
body variable. This allows the Layout to provide the overall HTML structure and then just interpolate the View(s) using
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title> A Simple FW/1 Layout Template </title> </head> <body> <!--- Embed the current View output into the Layout. ---> <cfoutput> #body# </cfoutput> </body> </html>
Yesterday, in my case, the report that I was generating didn't really have a Layout. Or, rather, the layout HTML was embedded directly within the View and I didn't need to have an additional Layout template to wrap the View. With FW/1 you can tell the request processing to skip the Layout by setting
<!--- DO NOT WRAP THIS VIEW IN A LAYOUT. ---> <cfset request.layout = false /> <cfoutput> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title> A FW/1 View That Does Not Need A Layout </title> </head> <body> <!--- Lots of REPORT GENERATION LOGIC. ---> <!--- Lots of REPORT GENERATION LOGIC. ---> <!--- Lots of REPORT GENERATION LOGIC. ---> <!--- Lots of REPORT GENERATION LOGIC. ---> <!--- Lots of REPORT GENERATION LOGIC. ---> </body> </html> </cfoutput>
The reporting View that I was generating was several megabytes in size. As such, I figured that any whitespace that I could remove as part of the request processing might be a win. Yes, GZIP should handle some compression; but, with the size of the View being so large, I figured that every little improvement might help the transfer and subsequent rendering time.
So, instead of having the View be "self contained", I removed the
request.layout flag and, instead, wired it into a Layout that looked like this:
<!--- This is a stand-alone layout (even layouts can be nested in FW/1). ---> <cfset request.layout = false /> <!--- Reset the output buffer. ---> <cfcontent type="text/html; charset=utf-8" /> <!--- Since this layout is going to produce a LARGE HTML payload, let's strip out as much leading whitespace as possible. This should reduce both the transfer time over the wire and the size of the subsequent DOM structure that is parsed by the browser. ---> <cfoutput> <!--- Using a multi-line Regular Expression to strip any "space characters" from the beginning of each line. ---> #body.reReplace( "(?m)^\s+", "", "all" )# </cfoutput>
Remember, within a FW/1 Layout, the
body variable contains the rendered View markup. And, in this case, we're not just embedding the View within the Layout - we're modifying the View as part of the interpolation. Specifically, we're using Regular Expressions (RegEx), in multi-line pattern matching mode, to remove whitespace characters from the front of every newline in the View markup before we nested it within the Layout markup.
Now, if I render a FW/1 View with the given Layout, I get the following HTML response:
As you can see, all leading whitespace characters have been stripped from every line in the document. You gotta love Regular Expressions, baby!
I am sure there are other ways to accomplish this with FrameworkOne (FW/1). To be honest, I know only enough about the framework to get my work done; I am - by no stretch of the imagination - an expert on FW/1 application development. That said, I thought this a fun little "hack".
Want to use code from this post? Check out the license.