Articles

streamFindnocase UDF

Searches the output buffer to determine if a string exists; Used for lazy dependency injection

Image about streamFindnocase UDF
April 19, 2025

The streamFindNoCase user-defined function (UDF) searches the currently accumulated output buffer for the presence of a given string, performing a case-insensitive comparison. It utilizes different methods for accessing and searching the output buffer depending on whether the ColdFusion server is Railo/Lucee or another version. It returns true if the string is found and false otherwise, without adding any output to the buffer itself.

In one of our projects about 10 years ago, we were fetching HTML fragments from a trusted third-party for inclusion on the website.  Instead of using an iFrame or incorporating ajax, which could negatively impact our SEO, we would occasionally fetch the content in the background and update the webpage. While this approach worked fine, there were times when the fragments would contain some inline JavaScript, but wouldn't work because the JavaScript library wasn't loaded... or if loaded within the HTML fragment would cause a problem because now the JS library is being loaded more than once.

To work around this, we wrote some code that checks the existing java output buffer to determine if a string exists or not.  For example, if the HTML fragment used jQuery, we'd use `streamFind("jquery-")` to identify whether the jQuery JS library was already included in the output stream. The UDF returns a boolean response and we'd include script tags to load the jQuery JavaScript library if it returned `false`.

We've used this UDF for many years, haven't encountered any issues and it's been extremely useful. It's compatible with Adobe ColdFusion, Railo and Lucee CFML.

Our framework currently performs this injection at the end and:

  • Uses jsoup to "tidy" the HTML (fix invalid web code, beautify the layout and formatting of the incorrect markup)
  • Update elements to add missing WCAG-complinant text (for accessibilty)
  • Move JS/CSS to the HTML Head (or to the footer if element contains data-footer="1")

Source Code

<cfscript>
/* 6/9/2015 https://groups.google.com/d/msg/railo/Q4KV0yT7oGk/hgLXXMOWtBgJ by Michael Offner (Railo 2012)
			https://dev.to/gamesover/searching-the-cfml-output-buffer-for-a-string-1b5f */
boolean function streamFindNoCase(required string str) output=false hint="I search the current output buffer to determine if a string exists" {
	return (listfindnocase("railo,lucee", server.ColdFusion.ProductName)) ? getPageContext().getOut().getString().toLowerCase().indexOf(lcase(arguments.str)) neq -1 : getPageContext().getCFOutput().getBuffer().findStringNoCase(arguments.str) neq -1;
}
</cfscript>

Demo

<!--- place at end of CFML generation within special modules --->
<cfif streamFindNoCase("$(") && !streamFindNoCase("jquery/global")>
	<script src="/scripts/jquery/jquery-3.7.1.js">
</cfif>
<cfif streamFindNoCase("Date.parse(") && !streamFindNoCase("scripts/date.js")>
	<script src=""/scripts/date.js"></script>
</cfif>
<cfif !streamFindNoCase("scripts/styles.css")>
	<link href="/scripts/styles.css" rel="stylesheet">
</cfif>
<cfif streamFindNoCase("button-") && !streamFindNoCase("buttons/css/buttons")>
	<link rel="stylesheet" href="/scripts/buttons/css/buttons.min.css">
</cfif>