<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BarneyBlog &#187; fusebox</title>
	<atom:link href="http://www.barneyb.com/barneyblog/category/fusebox/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.barneyb.com/barneyblog</link>
	<description>Thoughts, rants, and even some code from the mind of Barney Boisvert.</description>
	<lastBuildDate>Mon, 02 Mar 2020 13:20:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CF9 Compatibility for FB3Lite</title>
		<link>https://www.barneyb.com/barneyblog/2010/03/30/cf9-compatibility-for-fb3lite/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/03/30/cf9-compatibility-for-fb3lite/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 22:26:57 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[fusebox]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1407</guid>
		<description><![CDATA[I just made another minor tweak to FB3Lite to fix out-of-the-box ColdFusion 9 compatibility.Â  CF9 added a 'location' built-in function, which means that the function of the same name that FB3Lite provides now generates a compiler error.Â  Fortunately, since functions are real data within CFML, a simple realiasing gets around the issue.Â  This creates a [...]]]></description>
			<content:encoded><![CDATA[<p>I just made another minor tweak to <a href="http://www.barneyb.com/barneyblog/projects/fb3lite/">FB3Lite</a> to fix out-of-the-box ColdFusion 9 compatibility.Â  CF9 added a 'location' built-in function, which means that the function of the same name that FB3Lite provides now generates a compiler error.Â  Fortunately, since functions are real data within CFML, a simple realiasing gets around the issue.Â  This creates a subtle compatibility issue, but better than having to delete the UDF manually.</p>
<p>If your CFML engine does not provide a location function, FB3Lite will ensure one is available for you (simply wrapping CFLOCATION).Â  This has been the behaviour since the beginning.Â  Now, if your CFML engine <strong>does</strong> provide a location function, FB3Lite will still provide one in the variables scope (in case you're doing dynamic evaluation of it), but the engine-provided one will be used for static references (the typical case).</p>
<p>In general, this shouldn't matter to anyone; it's still just download and go.Â  The issue I alluded to above has to do with the optional parameters that CF9 provides (addToken and statusCode).Â  Since static invocations will use the built-in function, those optional params <strong>will</strong> be available on CF9, but <strong>will not</strong> on platforms that rely on FB3Lite's version.Â  Eventually I'd expect all CFML engines to provide a location function in which case there will no longer be a discrepancy, but for the meantime, if you're using multiple platforms, you'll need to ensure you're not using the optional parameters with the location function.</p>
<p>And before you say it, adding the parameters to the FB3Lite-provided function isn't an option, because CFLOCATION doesn't support statusCode until ColdFusion 8, which means you'd get compiler errors on CF7.</p>
<p>As always, the <a href="https://ssl.barneyb.com/svn/barneyb/fb3lite/trunk/index.cfm">source is available</a>, or you can check the <a href="http://www.barneyb.com/barneyblog/projects/fb3lite/">project page</a> for the latest info and updates.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/03/30/cf9-compatibility-for-fb3lite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FB3Lite appSearchPath Supports Mappings</title>
		<link>https://www.barneyb.com/barneyblog/2010/03/30/fb3lite-appsearchpath-supports-mappings/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/03/30/fb3lite-appsearchpath-supports-mappings/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 21:41:30 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[fusebox]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1402</guid>
		<description><![CDATA[Piggybacking on the change to allow mappings in do/include, you can now use mapping-relative paths in the appSearchPath initialization variable as well.Â  Before you had to use a relative path, which got a little hairy when you had a deeply nested structure:
&#60;cfset appSearchPath = "../../../myApp" /&#62;
&#60;cfinclude template="../com/barneyb/fb3lite/index.cfm" /&#62;

But now with mappings, you can simplify things, [...]]]></description>
			<content:encoded><![CDATA[<p>Piggybacking on the <a href="http://www.barneyb.com/barneyblog/2010/03/16/minor-fb3lite-feature/">change to allow mappings in do/include</a>, you can now use mapping-relative paths in the appSearchPath initialization variable as well.Â  Before you had to use a relative path, which got a little hairy when you had a deeply nested structure:</p>
<pre>&lt;cfset appSearchPath = "../../../myApp" /&gt;
&lt;cfinclude template="../com/barneyb/fb3lite/index.cfm" /&gt;
</pre>
<p>But now with mappings, you can simplify things, even if you're just using the webroot:</p>
<pre>&lt;cfset appSearchPath = "/myApp" /&gt;
&lt;cfinclude template="/com/barneyb/fb3lite/index.cfm" /&gt;
</pre>
<p>This is exactly the same functionality I added to do/include.Â  The difference is that the top-level fuseaction is invoked via an internal call to do() which is based on appSearchPath instead of a circuit prefix.Â  But now both are equivalent again.</p>
<p>As always, <a href="https://ssl.barneyb.com/svn/barneyb/fb3lite/trunk/index.cfm">source is available</a>, along with the <a href="http://www.barneyb.com/barneyblog/projects/fb3lite/">project page</a> with current information and downloads.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/03/30/fb3lite-appsearchpath-supports-mappings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fusebox&#039;s Noose</title>
		<link>https://www.barneyb.com/barneyblog/2010/02/02/fusebox-and-its-noose/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/02/02/fusebox-and-its-noose/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 04:40:44 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[fusebox]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1202</guid>
		<description><![CDATA[From an email Sean Corfield sent to the Fusebox5 mailing list (http://tech.groups.yahoo.com/group/fusebox5/message/4566):
I just wanted to provide a brief update on [Fusebox and 4CFF]. 4CFF discussed Fusebox with TeraTech (specifically John Zhu of 4CFF and Michael Smith of TeraTech) and were unable to reach an agreement on Fusebox joining 4CFF. One particular sticking point was that [...]]]></description>
			<content:encoded><![CDATA[<p>From an email Sean Corfield sent to the Fusebox5 mailing list (<a href="http://tech.groups.yahoo.com/group/fusebox5/message/4566">http://tech.groups.yahoo.com/group/fusebox5/message/4566</a>):</p>
<blockquote><p>I just wanted to provide a brief update on [Fusebox and 4CFF]. <a href="http://4cff.org/">4CFF</a> discussed <a href="http://fusebox.org/">Fusebox</a> with TeraTech (specifically John Zhu of 4CFF and Michael Smith of TeraTech) and were unable to reach an agreement on Fusebox joining 4CFF. One particular sticking point was that Michael wanted TeraTech to be paid for the Fusebox copyright and name.</p></blockquote>
<p>This is exceptionally disappointing news.Â  Fusebox is an ancient web framework, regardless of what language you use, and has been under TeraTech's control for only a brief portion of that lifespan.Â  The vast majority of development and building of community happened before TeraTech took the reins, and even under TeraTech's "management", most contributions have come from outside their company.</p>
<p>Hal Helms (who helped shepherd Fusebox for many years) and John Quarto-von Tivadar (who provided both the architecture and initial implementation of Fusebox's current compiled model) held the rights to the Fusebox name and IP (via The Fusebox Corporation) for many years, and turned it over to TeraTech in 2006.Â  Since that time, Sean has developed and released Fusebox 5.5 and 5.5.1, and little else has happened.Â  This is not an exemplary track record for TeraTech.</p>
<p>In the past month I have made some significant optimizations inside the 5.5.1 cores to reduce memory consumption and speed the compiler.Â  These efforts were partially sponsored by a third party, have been donated to TeraTech on behalf of myself and the sponsor, and are slated to be released as Fusebox 5.6 sometime this year.Â  I also helped John with the 4.0 architecture, wrote a significant portion of the 4.5 release, and contributed much of the 'cf' lexicon, along with various smaller bits and pieces along the way.Â  In addition to the core files themselves, I have been a member of Team Fusebox for a number of years, and an active member in the community for much longer.Â  To my knowledge, I have not received official credit for these contributions aside from source comments within the 'cf' lexicon verbs and being listed on the Team Fusebox web page.</p>
<p>As someone who has invested <em>significantly</em> in Fusebox over the years, this refusal of TeraTech to contribute the name and IP to 4CFF over the issue of money is a slap in the face.Â  I know Fusebox has helped innumerable developers over the year (myself included), and that is more than compensation enough for the contributions I've made, but to see TeraTech have the gall to demand payment for what I (and many others) have freely donated is very disappointing.</p>
<p>I sincerely hope that Michael and TeraTech will reconsider their position on the issue.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/02/02/fusebox-and-its-noose/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Implicit  Blocks in Fusebox 5.5.1</title>
		<link>https://www.barneyb.com/barneyblog/2010/01/07/implicit-blocks-in-fusebox-551/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/01/07/implicit-blocks-in-fusebox-551/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 17:45:08 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[fusebox]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1170</guid>
		<description><![CDATA[The XML syntax used by Fusebox since the 4.0 version allows for conditional expressions like these:


  


  





  


In the latter case, the
 tags are basically irrelevant, because they provide the same containership and semantic as the  tag itself.  Fusebox 5.0 and older allowed you to omit the
 tags in this [...]]]></description>
			<content:encoded><![CDATA[<p>The XML syntax used by Fusebox since the 4.0 version allows for conditional expressions like these:</p>
<pre><if condition="x GT 4">
<true>
  <set name="y" value="7" />
</true>
<false>
  <set name="y" value="3" />
</false>
</if>

<if condition="name EQ 'barney'">
<true>
  <set name="session.isSuperUser" value="true" />
</true>
</if></pre>
<p>In the latter case, the<br />
<true> tags are basically irrelevant, because they provide the same containership and semantic as the <if> tag itself.  Fusebox 5.0 and older allowed you to omit the<br />
<true> tags in this case:</p>
<pre><if condition="name EQ 'barney'">
  <set name="session.isSuperUser" value="true" />
</if></pre>
<p>This only makes sense if you don't have a <false> block, because if you have both blocks, then the <if> tag doesn't provide the correct containership.</p>
<p>Fusebox 5.5, however, made the<br />
<true> tag required even for the simple case.  This is unfortunate, I think, because it adds needless verbosity, and from digging around in the code, I suspect that it was primarily driven by implementation limitations, rather than user requests.</p>
<p>As part of migrating an app from 5.0 to 5.5.1, I really didn't want to have to go back and add all those extra tags, nor deal with the extra verbosity when maintaining the application down the road.  So I wrote a small patch for the core files that will allow an implicit<br />
<true> tag in the 5.0 style when using the 5.5.1 cores:</p>
<pre>Index: fuseboxVerb.cfc
===================================================================
--- fuseboxVerb.cfc	(revision 778)
+++ fuseboxVerb.cfc	(working copy)
@@ -33,20 +33,26 @@

 		<cfset variables.action = arguments.action />
 		<cfset variables.attributes = arguments.attributes />
+		<cfset variables.factory = factory />
 		<!--- we will create our children below --->
 		<cfset variables.verb = listLast(arguments.customVerb,".:") />
-		<cfset variables.children = structNew() />
-
-		<cfset variables.factory = factory />
-		<cfset variables.nChildren = arrayLen(arguments.children) />
-
-		<cfloop from="1" to="#variables.nChildren#" index="i">
-			<cfset verb = arguments.children[i].xmlName />
-			<cfset variables.children[i] = factory.create(verb,
-						variables.action,
-							arguments.children[i].xmlAttributes,
-								arguments.children[i].xmlChildren) />
-		</cfloop>
+
+		<cfif isStruct(arguments.children)>
+			<!--- This is an IR manipulation so we already have domain objects for children, rather than XML nodes. --->
+			<cfset variables.children = arguments.children />
+			<cfset variables.nChildren = structCount(variables.children) />
+		<cfelse>
+			<cfset variables.children = structNew() />
+			<cfset variables.nChildren = arrayLen(arguments.children) />
+
+			<cfloop from="1" to="#variables.nChildren#" index="i">
+				<cfset verb = arguments.children[i].xmlName />
+				<cfset variables.children[i] = factory.create(verb,
+							variables.action,
+								arguments.children[i].xmlAttributes,
+									arguments.children[i].xmlChildren) />
+			</cfloop>
+		</cfif>

 		<cfset variables.fb41style = listLen(arguments.customVerb,".") eq 2 />
 		<cfif variables.fb41style>
Index: verbs/if.cfm
===================================================================
--- verbs/if.cfm	(revision 778)
+++ verbs/if.cfm	(working copy)
@@ -35,13 +35,9 @@
 		// at most one
<true>, at most one <false>, nothing else:
 		fb_.hasTrue = false;
 		fb_.hasFalse = false;
+		fb_.verbInfo.hasOther = false;
 		for (fb_.i = 1; fb_.i lte fb_.verbInfo.nChildren; fb_.i = fb_.i + 1) {
-			if (fb_.verbInfo.children[fb_.i].getNamespace() is not "") {
-				fb_throw("fusebox.badGrammar.illegalVerb",
-						"Illegal verb",
-						"An 'if' may contain only 'true' and 'false' verbs in fuseaction #fb_.verbInfo.circuit#.#fb_.verbInfo.fuseaction#.");
-			}
-			switch (fb_.verbInfo.children[fb_.i].getVerb()) {
+			switch (fb_.verbInfo.children[fb_.i].getNamespace() &#038; fb_.verbInfo.children[fb_.i].getVerb()) {
 			case "true":
 				if (fb_.hasTrue) {
 					fb_throw("fusebox.badGrammar.illegalVerb",
@@ -61,10 +57,41 @@
 				}
 				break;
 			default:
+				fb_.verbInfo.hasOther = true;
+				break;
+			}
+		}
+		if (fb_.verbInfo.hasOther) {
+			if (fb_.hasTrue OR fb_.hasFalse OR fb_.verbInfo.action.getCircuit().getApplication().strictMode) {
 				fb_throw("fusebox.badGrammar.illegalVerb",
 						"Illegal verb",
 						"An 'if' may contain only 'true' and 'false' verbs in fuseaction #fb_.verbInfo.circuit#.#fb_.verbInfo.fuseaction#.");
-				break;
+			} else {
+				// only non-true/false and not strict mode, so wrap an implicit true around the children
+				// we have to do some acrobatics around the 'children' references
+				fb_.children = structNew();
+				for (fb_.i = 1; fb_.i lte fb_.verbInfo.nChildren; fb_.i = fb_.i + 1) {
+					fb_.children[fb_.i] = fb_.verbInfo.children[fb_.i];
+				}
+				structClear(fb_.verbInfo.children);
+				fb_.factory = fb_.verbInfo.action.getCircuit().getApplication().getFuseactionFactory();
+				fb_.implicitTrue = fb_.factory.create(
+						"true",
+						fb_.verbInfo.action,
+						structNew(),
+						fb_.children
+					);
+				fb_.verbInfo.children[1] = fb_.implicitTrue;
+				// now null out the remaining children
+				for (fb_.i = 2; fb_.i lte fb_.verbInfo.nChildren; fb_.i = fb_.i + 1) {
+					fb_.verbInfo.children[fb_.i] = fb_.factory.create(
+						"noop",
+						fb_.verbInfo.action,
+						structNew(),
+						arrayNew(1)
+					);
+				}
+				fb_.hasTrue = true;
 			}
 		}

Index: verbs/noop.cfm
===================================================================
--- verbs/noop.cfm	(revision 0)
+++ verbs/noop.cfm	(revision 0)
@@ -0,0 +1 @@
+<cfset fb_appendLine('<!--- no op: #fb_.verbInfo.executionMode# --->') /></pre>
<p>The implementation is kind of hacky because the XML compiler lacks a IR transformation step, so I had to fake one.  And that was further complicated by the parallelism in the internal datastructures, necessitating the creation of a "noop" verb to use as a placeholder in certain situation. <a href="https://australiacasinoonline.com/5-dollars-minimum-deposit-casinos-australia/">5 minimum deposit casino</a>  More specifically, there isn't a way to add or remove verbs from the parse tree, only to <em>change</em> verbs, and implementing the functionality within that constraint required some "creative" programming.  ;)</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/01/07/implicit-blocks-in-fusebox-551/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fusebox XML Flowchart Generator</title>
		<link>https://www.barneyb.com/barneyblog/2009/11/17/fusebox-xml-flowchart-generator/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/11/17/fusebox-xml-flowchart-generator/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 01:41:43 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[fusebox]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1136</guid>
		<description><![CDATA[About a week ago someone posted on the Fusebox mailing list looking for a way to generate flowcharts from his Fusebox XML files.Â  Adalon was suggested, but it didn't do quite what he was looking for.Â  So I sunk some of my spare time into building such a tool, and even managed to refrain from [...]]]></description>
			<content:encoded><![CDATA[<p>About a week ago someone posted on the Fusebox mailing list looking for a way to generate flowcharts from his Fusebox XML files.Â  Adalon was suggested, but it didn't do quite what he was looking for.Â  So I sunk some of my spare time into building such a tool, and even managed to refrain from using Groovy and kept it all CFML.Â  All the layout stuff is custom, and the drawing is all via the CF8 image functions.Â  The imageTranslateDrawingAxis function, in particular, was of great utility, allowing me to do all my drawing in local space, rather than absolute space.Â  This means that every box starts at (0, 0), regardless of where it eventually ends up on the chart, so the drawing of each element is totally encapsulated on it's own coordinate space.</p>
<p>It's easiest to show with an example, so consider this contrived circuit.xml:</p>
<pre><a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2009/11/chome.png" target="_blank"><img class="alignright size-full wp-image-1137" title="chome" src="http://www.barneyb.com/barneyblog/wp-content/uploads/2009/11/chome.png" alt="chome" width="149" /></a>&lt;circuit&gt;

  &lt;fuseaction name="home"&gt;
    &lt;xfa name="page" value="page" /&gt;
    &lt;if condition="structKeyExists(attributes, 'name')"&gt;
      &lt;true&gt;
        &lt;loop collection="attributes" item="i"&gt;
          &lt;set name="m" value="#i#" /&gt;
        &lt;/loop&gt;
        &lt;set name="message" value="Hello, strange unknown person!" /&gt;
      &lt;/true&gt;
      &lt;false&gt;
        &lt;set name="message" value="Hello, #name#!" /&gt;
        &lt;relocate /&gt;
        &lt;xfa name="exit" /&gt;
      &lt;/false&gt;
    &lt;/if&gt;
    &lt;include template="dsp_home" contentvariable="bodyContent" /&gt;
    &lt;do action="lay_default" /&gt;
  &lt;/fuseaction&gt;

  &lt;fuseaction name="page"&gt;
    &lt;include template="dsp_page" contentvariable="bodyContent" /&gt;
    &lt;do action="lay_default" /&gt;
  &lt;/fuseaction&gt;

  &lt;fuseaction name="lay_default"&gt;
    &lt;if condition="structKeyExists(attributes, 'showNav')"&gt;
      &lt;true&gt;
        &lt;do action="nav" contentvariable="nav" /&gt;
      &lt;/true&gt;
      &lt;false&gt;
        &lt;loop&gt;
          &lt;set name="message" value="Hello, strange unknown person!" /&gt;
          &lt;do action="nav" contentvariable="nav" /&gt;
        &lt;/loop&gt;
      &lt;/false&gt;
    &lt;/if&gt;
    &lt;include template="lay_default" /&gt;
  &lt;/fuseaction&gt;

  &lt;fuseaction name="nav"&gt;
    &lt;xfa name="home" value="home" /&gt;
    &lt;xfa name="page" value="page" /&gt;
    &lt;include template="dsp_nav" /&gt;
  &lt;/fuseaction&gt;

&lt;/circuit&gt;</pre>
<p><img class="alignright size-full wp-image-1138" title="cnav" src="http://www.barneyb.com/barneyblog/wp-content/uploads/2009/11/cnav.png" alt="cnav" width="149" height="365" />Yes, I understand that it wouldn't actually execute in real life (there are a number of missing attributes), but that's not the point.Â  The generated flowcharts for the 'home' and 'nav' fuseactions are floating to the right.  You can click the 'home' one to view it full size.</p>
<p>The UI is pretty simple, you enter the path to either a single circuit.xml file (as above), or your fusebox.xml file and hit 'Go'.Â  Then you can pick from the list of available fuseactions to act as your entry point, choose whether you'd like to include global pre/postprocess actions and pre/postfuseaction on the flowchart, and it'll draw it all out for you as a nice little PNG.</p>
<p>If you turn on the implicit fuseactions the charts can get pretty large pretty fast, but even generating some pretty gnarly charts for a sizeable app we have at Mentor didn't take more than a second or two.</p>
<p>If you'd just like to render a single circuit's stuff, you can point it directly at the circuit file, and you'll get an error box for any &lt;do&gt; verbs that point outside the circuit, so you'll still get a full chart, with the external dependencies called out explicitly.</p>
<p>I've made the code available in a <a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2009/11/fuseboxflowchart.zip">zip archive</a> if you'd like to run it yourself (or just poke around).Â  Just unzip it somewhere, and hit index.cfm in the browser.Â  The example circuit.xml above is included, so you can regenerate the demo charts I've shown here, or point it at your own Fusebox app and get a look at what you're doing.</p>
<p>The code itself is hardly an example of eloquent design, since this was just a little "screwing around" project.Â  The drawing stuff is pretty devoid of magic numbers, but I made no attempt to fully/properly decompose my types or to really enforce DRY throughout.Â  It is what it is: something to keep me from getting bored that I though might be of interest to others.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/11/17/fusebox-xml-flowchart-generator/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>FB3lite as a Custom Tag</title>
		<link>https://www.barneyb.com/barneyblog/2009/05/22/fb3lite-as-a-custom-tag/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/05/22/fb3lite-as-a-custom-tag/#comments</comments>
		<pubDate>Fri, 22 May 2009 17:48:43 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[fusebox]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=981</guid>
		<description><![CDATA[Last night at work Koen uncovered an issue with using FB3lite as a custom tag.Â  Inside the tag it does "formUrl2Attributes" to merge the two scopes into the attributes scope.Â  What I'd done incorrectly was omit the "don't override" parameter to the structAppend calls, so the URL and FORM scopes would supercede any existing attributes [...]]]></description>
			<content:encoded><![CDATA[<p>Last night at work <a href="http://koencidence.com/">Koen</a> uncovered an issue with using <a href="http://www.barneyb.com/barneyblog/projects/fb3-lite/">FB3lite</a> as a custom tag.Â  Inside the tag it does "formUrl2Attributes" to merge the two scopes into the attributes scope.Â  What I'd done incorrectly was omit the "don't override" parameter to the structAppend calls, so the URL and FORM scopes would supercede any existing attributes for the invocation.</p>
<p>During normal execution this is irrelevant.Â  It's similarly irrelevant if you don't have a collision between FORM/URL parameters and custom tag attributes.Â  However, if you do have a collision, the FORM/URL parameter wins, which is clearly incorrect.</p>
<p>To fix this, I added the missing third parameter to structAppend, as well as reversing the lines (so FORM still overrides URL as it always has).Â  You can grab the <a href="https://ssl.barneyb.com/svn/barneyb/fb3lite/trunk/index.cfm">source</a> directly, or pull from <a href="https://ssl.barneyb.com/svn/barneyb/fb3lite/trunk/">Subversion</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/05/22/fb3lite-as-a-custom-tag/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Minor FB3lite Update (and a Weird CF Bug)</title>
		<link>https://www.barneyb.com/barneyblog/2009/05/19/minor-fb3lite-update-and-a-weird-cf-bug/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/05/19/minor-fb3lite-update-and-a-weird-cf-bug/#comments</comments>
		<pubDate>Tue, 19 May 2009 07:22:01 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[fusebox]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=961</guid>
		<description><![CDATA[This evening while adding some reporting to PotD (NSFW, OMM) to help nail down some performance issues that I think are Apache's fault, I noticed a strange issue with FB3lite.Â  If you've used it, you know the core of the "framework" are the do() and include() UDFs.Â  Both contain a CFINCLUDE tag, and a weird [...]]]></description>
			<content:encoded><![CDATA[<p>This evening while adding some reporting to <a href="http://potd.barneyb.com/">PotD</a> (NSFW, OMM) to help nail down some performance issues that I think are Apache's fault, I noticed a strange issue with <a href="http://www.barneyb.com/barneyblog/projects/fb3-lite/">FB3lite</a>.Â  If you've used it, you know the core of the "framework" are the do() and include() UDFs.Â  Both contain a CFINCLUDE tag, and a weird situation arises with scoping.</p>
<p>CFML has implicit scope traversal, so if you have an unscoped variable, it will automatically traverse across a bunch of scopes until it finds one with the right name.Â  Further, you get an implicit local scope within UDFs, and you get a magic psuedo-scope within query-based CFOUTPUT and CFLOOP tags.</p>
<p>What I noticed was that looping over a query with a column named "template" always displayed the currently executing template, instead of the value from the query.Â Â  No worries, I thought, since prefixing it with the query name solved the issue.Â  "template" isn't a common query name for me, so while it surprised me I'd never noticed or heard about this magic "template" variable before, I didn't think too much of it.</p>
<p>Then a while later I realized it was my own fault, because of the include() UDF in FB3lite.Â  The argument to the UDF is named "template", and CFML places the implcit local scope at the top of the heap, including above the magic query-loop scope.Â  That argument was shadowing my query variable.</p>
<p>I've fixed FB3lite to use a prefix on all it's UDF arguments, so this problem cannot manifest itself anymore.Â  Well, I suppose it could, but you'd have to have a weird-ass variable name (e.g., "_fb3lite_template").Â  You can <a href="https://ssl.barneyb.com/svn/barneyb/fb3lite/trunk/index.cfm">download the latest version</a>, or pull it <a href="https://ssl.barneyb.com/svn/barneyb/fb3lite/trunk/">from Subversion</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/05/19/minor-fb3lite-update-and-a-weird-cf-bug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calling FB3Lite as a Custom Tag</title>
		<link>https://www.barneyb.com/barneyblog/2009/01/26/calling-fb3lite-as-a-custom-tag/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/01/26/calling-fb3lite-as-a-custom-tag/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 20:58:08 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[fusebox]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=666</guid>
		<description><![CDATA[Today at work, Joshua wanted to invoke one of our FB3Lite apps from within an external CFM file (a CMS template) to reuse some code.Â  So I added a little snippet to the top of index.cfm to detect if it's being called as a custom tag and only execute during the start phase.Â  So you [...]]]></description>
			<content:encoded><![CDATA[<p>Today at work, <a href="http://joshuafrankamp.com/">Joshua</a> wanted to invoke one of our FB3Lite apps from within an external CFM file (a CMS template) to reuse some code.Â  So I added a little snippet to the top of index.cfm to detect if it's being called as a custom tag and only execute during the start phase.Â  So you can do this:</p>
<pre>&lt;cfimport prefix="myapp" taglib="/path/to/fb3lite/app" /&gt;
&lt;myapp:index do="myFuseaction" /&gt;</pre>
<p>and you'll only get a single execution of the app, instead of one for each half of the custom tag.Â  This is a piece of functionality that real <a href="http://fuseboxframework.org/">Fusebox</a> has always had, but which I'd never used and so hadn't incorporated.</p>
<p>As always, the latest is available in Subversion at <a href="https://ssl.barneyb.com/svn/barneyb/fb3lite/trunk">https://ssl.barneyb.com/svn/barneyb/fb3lite/trunk</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/01/26/calling-fb3lite-as-a-custom-tag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adventures in Monkey Code</title>
		<link>https://www.barneyb.com/barneyblog/2008/12/28/adventures-in-monkey-code/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/12/28/adventures-in-monkey-code/#comments</comments>
		<pubDate>Sun, 28 Dec 2008 08:01:19 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[fusebox]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=586</guid>
		<description><![CDATA[I did a little experiment this weekend.Â  I needed (well, wanted) to build a really simple little photo viewer application.Â  Create a gallery, add some photos, view the photos as a slideshow.Â  Really basic.Â  The catch is that I build it using no framework at all, aside from Application.cfm.Â  Note the 'm'.Â  And no IDE: [...]]]></description>
			<content:encoded><![CDATA[<p>I did a little experiment this weekend.Â  I needed (well, wanted) to build a really simple little photo viewer application.Â  Create a gallery, add some photos, view the photos as a slideshow.Â  Really basic.Â  The catch is that I build it using no framework at all, aside from Application.cfm.Â  Note the 'm'.Â  And no IDE: everything was done with text-mode Emacs and the MySQL command line client.</p>
<p>Each "page" of the app was actually a real page (a CFM).Â  Data access at the top, then a CFOUTPUT block below for the "view" pages, and just simple processing with a CFLOCATION for the action pages.Â  I built the forms so the same page would accept both create and edit requests, switching on the presence of an ID in the request parameters, so I got a little reuse that way, but nothing else.</p>
<p>For initial development, this worked swimmingly.Â  Each page was totally separate, pick a page, build it, move on to the next.Â Â  In a couple hours I was done, and most of that was spent on getting all the JS interactions tuned for inline editing, sorting, the slideshow, etc.Â  The app was simple enough that I didn't even do much copy and paste.Â  Maybe five or six blocks total, and two of those were form skeletons so I didn't have to start from scratch (i.e. not candidates for "real" reuse).</p>
<p>So then I wanted to add zip upload to streamline a bit.Â  Make a zip, upload it, and have individual items created for all the contained jpegs.Â  Sounds simple, right?Â  Except that all the logic was inside savePhoto.cfm.Â  I briefly considered setting up the attributes scope for each photo and then CFINCLUDEing that file for each jpeg in the zip, but it wouldn't have worked with the CFFILE ACTION="UPLOAD" in there, so that was out.Â  Time to refactor.</p>
<p>Still wanting to avoid any sort of framework-ish-ness, I opted for a UDF library instead of a CFC.Â  Mostly to resist the temptation to slap ColdSpring on it so I could stop thinking about those fu$@*ng CFTRANSACTION tags.Â  I split the logic from savePhoto.cfm into four UDFs, sliced appropriately for either "uploading" with CFFILE or sourcing from the local filesystem.Â  This actually worked pretty well, and I didn't have to duplicate any logic anywhere to support zip upload, create new photo, and replace existing photo.</p>
<p>So here I am at the end of my journey.Â  I actually had a pretty good time not thinking about the infrastructure and just diving right into the code.Â  No messing with getting ColdSpring and FB3Lite into the project, setting up mappings for them, etc.Â  That said, I do NOT recommend the shortcut to anyone unless they have a similar experimental interest.</p>
<p>As of right now, I'm probably slightly ahead in terms of time expended compared to doing the FB3Lite-on-ColdSpring way, but only slightly.Â  And I have manually managed transactions, no good way to apply security, layouts managed with Application.cfm and OnRequestEnd.cfm, no ability to reuse view code other than more UDFs, and a fair amount of duplicated SQL and error handling.Â  In short, a mess.</p>
<p>I'd imagine that the next enhancement made will push me over the brink to reduced productivity from the initial decision to monkey-code it, and it's downhill from there.Â  Fortunately the app is small enough that doing a wholesale conversion won't be too much work (and yes, that was one of the considerations for undertaking the experiment).Â Â  So that'll probably happen at the same time for the cost of an hour or so.</p>
<p>All in all, a good experiement, I'd say.Â  Completely confirmed my beliefs that spending half an hour setting up a good project framework is worth every second, and the "lost" time is made up within the first few hours of development.Â Â  And this was a very small project with a single developer, the rewards only get more significant as projects grow in size.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/12/28/adventures-in-monkey-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Stream Layouts</title>
		<link>https://www.barneyb.com/barneyblog/2008/09/05/stream-layouts/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/09/05/stream-layouts/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 23:19:17 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[fusebox]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=497</guid>
		<description><![CDATA[No, I'm not talking about those things full of water running down the mountainside, I'm talking about how you assemble a full HTML (or whatever) page from a webapp.Â  Being a Trac user, I've done a bit with Genshi, and then with Grails used SiteMesh, both of which are stream-based engines.Â  I'd always though the [...]]]></description>
			<content:encoded><![CDATA[<p>No, I'm not talking about those things full of water running down the mountainside, I'm talking about how you assemble a full HTML (or whatever) page from a webapp.Â  Being a Trac user, I've done a bit with Genshi, and then with Grails used SiteMesh, both of which are stream-based engines.Â  I'd always though the paradigm was a bit odd, and kind of inside-out, but today I realized they're exactly the right way to do things.</p>
<p>The basic idea is that your app generates the page body, as a full HTML document, and then it gets passed down the stream and manipulated.Â  Maybe it gets some LINK and SCRIPT tags added to the HEAD, or a footer to the end of the BODY.Â  Contrast this with the "content variable" assembly process, where your app generates a bodyContent variable which is handed to a layout to render into a full page.</p>
<p>What invariable ends up happening with the latter approach is a whole pile of variable along with bodyContent (headContent, pageTitle, footerContent, aboveFooterContent, belowFooterContent, etc.).Â  A huge mess, especially if you're using Fusebox or something like it, where you typically put your HTML in a dsp_ file and include it into a content variable, because you end up with a massive number of one-line includes, most of which are all bound to rendering a single page (i.e. aren't reused).</p>
<p>Contrast that with SiteMesh or Genshi, where you can package all those separate pieces up in a single packet, and let them stream out of your app to the layout engine that takes care of everything.Â  It might be combining your content with another app (think a portal), might be wraping it with header/nav/footer, might be restructuring it for an iPhone vs. a PC.</p>
<p>This doesn't come without a downside, of course.Â  For example your navigation isn't controlled by your application anymore, so if you're addicted to XFAs (as I am), you're kind of stuck.Â  For websites it's not as big a deal because you don't want your URL-space changing, but for applications it's a bit more troublesome.Â  This is straightforward to deal with in the opposite direction, however.Â  There are also some performance implications, though they're pretty trivial.</p>
<p>I'm trying to figure out a good way to integrate SiteMesh with CFML.Â  CF is just a huge burden to try and drag into the JEE way of doing things, but Railo should be far simpler.Â  I really don't want to use JSP for the layout engine, and while I like using Velocity, keeping to a single templating language is certainly beneficial.Â  Whether I'll actually have time to implement something remains to be seen, but it sure would be nice.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/09/05/stream-layouts/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
