320 likes | 474 Views
Fusebox 5, What’s new. Sandra Clark Sr. Software Developer The Constella Group sclark@constellagroup.com. Overview. Multiple Fusebox Applications in one ColdFusion Application Application Initialization New Verbs (includes Nesting) Implicit Circuits New Execution Modes
E N D
Fusebox 5, What’s new Sandra ClarkSr. Software DeveloperThe Constella Groupsclark@constellagroup.com
Overview • Multiple Fusebox Applications in one ColdFusion Application • Application Initialization • New Verbs (includes Nesting) • Implicit Circuits • New Execution Modes • Debug and Trace Modes • Extending the Framework with lexicons.
Multiple Fusebox Applications in one ColdFusion Application • Sometimes, you need to add in an existing Fusebox application into your ColdFusion Application • Prior to version 5, you could only have one FB application in a CF application
Single FB App in CF App • sampleapp/index.cfm <cfapplication name="sampleapp" sessionmanagement="Yes" sessiontimeout="#CreateTimeSpan(0, 4,0,0)#" > <cfset FUSEBOX_APPLICATION_KEY = "app2"> <cfset FUSEBOX_APPLICATION_PATH="../scripts/FBCore" > <cfinclude template="#fusebox_Application_Path#/fusebox5/fusebox5.cfm" >
Multiple FB Apps in single CF App • sampleapp1/index.cfm <cfapplication name="sampleapp" sessionmanagement="Yes" sessiontimeout="#CreateTimeSpan(0, 4,0,0)#" > <cfset FUSEBOX_APPLICATION_KEY = "app1"> <cfset FUSEBOX_APPLICATION_PATH=“/fusebox5" > <cfinclude template="#fusebox_Application_Path#/fusebox5.cfm" > • sampleapp2/index.cfm <cfapplication name="sampleapp" sessionmanagement="Yes" sessiontimeout="#CreateTimeSpan(0, 4,0,0)#" > <cfset FUSEBOX_APPLICATION_KEY = "app2"> <cfset FUSEBOX_APPLICATION_PATH=“/fusebox5" > <cfinclude template="#fusebox_Application_Path#/fusebox5.cfm" >
Retrieving FB Application Information • Mostly for Plugin Writers. • Instead of using Application.fusebox use myFusebox.getApplication() • myFusebox.getApplication() • returns the fuseboxApplication object that represents the application • myFusebox.getCurrentCircuit() • returns the fuseboxCircuit object that represents the currently executing circuit (if applicable) • myFusebox.getCurrentFuseaction() • returns the fuseboxAction object that represents the currently executing fuseaction
Application Initialization • In Fusebox 4.1, you can execute code at the beginning of each request • Through <globalfuseactions><preprocess> (fusebox.xml.cfm) or • fusebox.init.cfm • These items don’t provide any way to execute code when an application starts up. • Fusebox 5 provides 2 ways to execute code upon an application startup • <globalfuseactions><appinit> • fusebox.appinit.cfm
Application Initialization • With <globalfuseactions><appinit>, the information contained within (normally a call to a fuseaction), is only called on the first request after the framework is loaded and the execution is locked to ensure thread safety. • <appinit> executes conditionally as part of each request. • The fuseaction called within this is not part of the normal lifecycle execution. There are no plugins and items in this fuseaction cannot depend on any plugin behaviors. • fusebox.appinit.cfm is called immediately when the framework is first loaded, before the request is compiled and processed and is again within a lock. It is also locked with a different named lock from <appinit> • Fusebox.appinit.cfm executes as part of the framework load even before fusebox.init.cfm is loaded.
Application Initialization • Which one to use? • Don’t use both, choose one or the other • If you are sharing initialization between a fusebox 5 app and a non fusebox app, use fusebox.appnit.cfm since you can include that in a non fusebox application • If you are strictly using a Fusebox 5 application, use <appinit>
Application Initialization • Using fusebox.appinit.cfm with a non-fusebox application • Include the file in onApplicationStart() in Application.cfc • If you don’t use Application.cfc • Make sure you conditionally lock the execution of the file when you call it. • Make sure you use conditional logic (does a specific Application variable exist) before you actually call it.
New Verbs and Syntax • Nested Verbs • Nesting <if /> and <loop /> inside of <if /> and <loop /> is now allowed. <if condition=“query1.rowcount lte query1.recordcount”> <true> <loop query=“query2”> <do fuseaction=“v.showline” /> </loop> </true> </if>
New Verbs and Syntax • <loop> • Supports all 5 types of loops that CF supports • <loop query=“”>…</loop> • <loop condition=“”>…</loop> • <loop from=“1” to=“#numrows#” index=“row”>…</loop> • <loop collection="#someStruct#" item="someVariable">…</loop> • <loop list="#someList#" index="someVariable">…</loop>
New Syntax – Invoke • FB 4.1 style, also valid in Fusebox 5 <invoke object="myObj" methodcall="foo(one='arg1str',two=arg2)" /> • FB5 style (named arguments) <invoke object="myObj" method="foo"> <argument name="one" value="arg1str" /> <argument name="two" value="#arg2#" /> </invoke> • FB5 style (positional arguments) <invoke object="myObj" method="foo"> <argument value="arg1str" /> <argument value="#arg2#" /> </invoke>
New Syntax - Instantiate • FB 4.1 style, also valid in Fusebox 5 <instantiate class="MyObjectType" object="myObj" arguments="one='arg1str',two=arg2" /> • FB5 style (named arguments) <instantiate class="MyObjectType" object="myObj"> <argument name="one" value="arg1str"/> <argument name="two" value="#arg2#" /> </instantiate> • FB5 style (positional arguments) <instantiate class="MyObjectType" object="myObj"> <argument value="arg1str" /> <argument value="#arg2#" /> </instantiate>
Invoke and Instantiate Arguments • You can mix positional and named arguments • Positional arguments need to come first. • While the FB4.1 syntax is not deprecated yet, it may become so in future versions.
New Syntax – Parameter • In FB4, any variables introduced are always available to fuses and fuseactions after the introduction • Any changes to these variables are also available after. • Parameter attribute allows you to pass variables into fuses and fuseactions without changing or overwriting variables in the original scope. • Used within • <include /> • <do /> • <fuseaction />
New Syntax – Parameter • Parameters create variables that are available only for the life of the fuseaction or fuse. <do action="v.layout"> <parameter name="title" value="Layout Title" /> </do> <include template="dspLayout"> <parameter name="title" value="Layout Title" /> </include> <fuseaction action="model.initialize"> <parameter name="dataSourceName" value="devNotes" /> </fuseaction>
<include /> Official Support • <include template=“dsp_temp” circuit=“specificcircuit” /> • Was an undocumented feature of fB 4.1 • Useful in MVC apps that would commonly have a <do /> that simply has an include in it (like View Circuits) • Allows a controller to <include /> a fuse directly without having to reference it through a fuseaction.
Implicit Circuits • With the ability to specify circuit within an <include /> comes the ability to specify that circuits can be implicit. • In fusebox.xml within <parameters></parameters> • <parameter name="allowImplicitCircuits" value="true" /> • This way you don’t need a circuit.xml in each subdirectory that will only be called implicitly.
New Execution Modes • fB4.1 – 2 execution modes • Development – caused the framework to load the xml files if they had changed, and forced a parse for each public fuseaction • Production – caused the framework to load the xml files only on the first request and then only parse a fuseaction the first time it was requested. • Any changes to the xml files would not take affect until the framework was restarted or explicitly via the fusebox.load and fusebox.password url values.
New Execution Modes – URL Variables • fusebox.load • Reload the xml files • fusebox.parse • Parse a specific fuseaction • fusebox.execute • Execute a specified fuseaction • fusebox.loadclean • Similar to fusebox.load, but also deletes all parsed files. • fusebox.parseall • Causes every public fuseaction to be reparsed and all parsed files to be re/generated. (precompilation)
FB5 Execution Modes - mode • development-full-load • Any xml files changed? • fusebox.load=true&fusebox.parse=true&fusebox.execute=true • No xml files changed? • fusebox.load=false&fusebox.parse=true&fusebox.execute=true • Is equal to FB4.1 “development” mode which is deprecated. • development-circuit-load • Does not load the fusebox.xml file, doesn’t reinitialize the framework, but does reload any circuit.xml files that are required by the current request (if they have changed) and re-parses the current fuseaction. • Removes the performance hit with reinitializing the framework during development and is thread safe • production • fusebox.load=false&fusebox.parse=false&fusebox.execute=true
Debug and Trace Modes • Adds a timed debug/trace mode so you can see what takes up time in your requests. • In fusebox.xml within <parameters></parameters> • <parameter name=“debug" value="true" />
Debug and Trace Modes • Trace information by using • myFusebox.trace(type,message) • Fusebox already uses the following types: • Fusebox – lifecycle related tracing • Runtime - <do>, <fuseaction> and <include> • Compiler – fusebox.xml and circuit.xml loaded during compilation. • Create your own type and then add specific messages.
Extending the Framework with lexicons. • A lexicon is basically a list of words with word specific information. • In Fusebox 5, a lexicon is a way of extending the Fusebox XML language via namespaces. • It is a collection of new verbs that can be added. • Lexicons write to the parsed file at compile time, not at run time.
Declaring a lexicon • Lexicons are declared in the circuit.xml.cfm or the fusebox.xml.cfm by declaring an xmlns (xml namespace) • Circuit.xml • <circuit xmlns:shayna="/path/to/cf/lexicon“/> • Fusebox.xml • <fusebox xmlns:shayna=“/path/to/cf/lexicon”/>
Using a lexicon • A lexicon consists of a directory (which is where you point your xmlns to.) which contains the verbs. • Each verb is one file with the name of the verb being the name of the file. • A variety of cf verbs come with the skeleton available at http://www.fuseboxframework.org/downloads/downloadablefiles/fusebox500.skeleton.cfmx.zip
Using a lexicon • Switch/Case • Contained in the skeleton application <cf:switch expression="#attributes.switchme#"> <cf:case value="1"> <include template="dsp_1“ contentvariable="content.main“ append="true" circuit="v_sampleapp"/> </cf:case> </cf:switch>
Creating a lexicon • Create the lexicon directory under “lexicon”. • Each verb is a file with the name of the verb being the name of the file. • Debug.cfm contains the code for the verb “debug”
Creating a lexicon verb • Lexicon verbs have specific information available to it through the fb_.verbInfo structure • The structure • lexicon - the prefix for the namespace • lexiconVerb - the actual verb being invoked • attributes - the struct containing attributes provided in the verb invocation • circuit - the alias of the circuit in which this verb is being invoked • fuseaction - the name of the fuseaction in which this verb is being invoked • action - the object that represents the current fuseaction • hasChildren - true if there is are other verbs nested within this invocation • skipBody - if the verb sets this to true in start mode, no nested (child) verbs are executed (but this verb will still execute in end mode) • executionMode - "start" / "end" / "inactive" • parent - present if this verb is nested inside another verb (parent is a • reference to the verbInfo structure of that enclosing verb, therefore parent.executionMode will be "inactive")
Creating a lexicon verb • Lexicon verbs are written in usually written in cfscript and follow the form. • <cfscript> • if (fb_.verbInfo.executionMode is "start") { • // validate fb_.verbInfo.attributes contents • // compile start tag CFML code • } else { • // compile end tag CFML code • } • </cfscript> • See the documentation at fusebox.org (“What’s new in Fusebox 5) for more specific information.
Questions? Sandy Clark slclark@shayna.com http://www.shayna.com