Searching CFDocs

A friend of mine recently pinged me with a question about the ColdFusion docs. She noticed that in version 8, the search capability was removed. Now while you can obviously search the PDF, that can be a bit slow, and if you aren’t online and can use cfQuickDocs, you have to use your local docs. CFEclipse includes the CF docs and also provides a searchable interface. I don’t use Dreamweaver but I’m sure it supports it as well. Another option is to use Verity. Since the docs are all HTML based, you could quickly index the docs and build a simple search interface to the collection. The benefit to this is you get the power of Verity’s search engine, and can do things like offer suggestions in case you misspell a CF tag. I wrote up a quick script that does all of this in one hit. It both looks for and creates a cfdocs collection if it doesn’t exist, and then has a simple search interface. You could drop this right in your web root and run it. The only line you would need to modify is the very first line of code. I can’t sniff where you install the cfdocs so I hard coded the line. (Technically I could make some guesses, like under CF’s webroot, but if you have CF tied to Apache or IIS, it may be under your main web root instead.)

The code itself isn’t too interesting. I will point out that there is still an old bug with file based Verity collections and the URL property. If you specify a value like I have:

<cfindex collection="cfdocs" action="update" type="path" key="#docpath#" recurse="true" urlpath="/cfdocs/htmldocs/" status="s">

The result query from a search will be broken. Instead of getting something like this:

/cfdocs/htmldocs/raymond.html

You always get one letter removed:

/cfdocs/htmldocs/aymond.html

So I hacked around this by using the KEY value, which was the full path to the file. Anyway, the file is included below. Enjoy. And if you have any questions about what I did, ask away.

<!--- physical location of docs ---> <cfset docpath = "c:/coldfusion8/wwwroot/cfdocs/htmldocs/">

<!— Set up collection if we need too —> <cfcollection action=”list” name=”collections”> <cfif not listFindNoCase(valueList(collections.name), “cfdocs”)>

&lt;!--- makes the collection ---&gt;
&lt;cfset cdir = server.coldfusion.rootdir & "/verity/collections/"&gt;
&lt;cfcollection action="create" collection="cfdocs" path="#cdir#"&gt;
&lt;!--- populate it. ---&gt;
&lt;cfoutput&gt;
#repeatString(" ", 250)# &lt;!--- IE Hack ---&gt;
&lt;p&gt;
I'm indexing the cfdocs directory. Please stand by...
&lt;/p&gt;
&lt;/cfoutput&gt;
&lt;cfflush&gt;

&lt;cfindex collection="cfdocs" action="update" type="path" key="#docpath#" recurse="true" urlpath="/cfdocs/htmldocs/" status="s"&gt;

</cfif>

<cfparam name=”url.search” default=”“> <cfparam name=”form.search” default=”#url.search#”> <cfparam name=”url.startrow” default=”1”> <cfset perpage = 10>

<cfoutput> <form action=”#cgi.script_name#” method=”post”> <input type=”text” name=”search” value=”#form.search#”> <input type=”submit” value=”Search”> </form> </cfoutput>

<cfif len(trim(form.search))> <cfsearch collection=”cfdocs” name=”results” contextPassages=”3” maxRows=”#perpage#” startrow=”#url.startrow#” status=”r” suggestions=”always” contextHighlightBegin=”999” contextHighlightEnd=”000” criteria=”#trim(form.search)#”>

&lt;cfif results.recordCount&gt;
	&lt;cfoutput&gt;
	Your search for '#form.search#' returned #r.found# result(s) out of #r.searched# entries.&lt;br /&gt;
	&lt;cfif structKeyExists(r, "suggestedquery") and len(r.suggestedquery)&gt;
	You may also want to search for &lt;a href="#cgi.script_name#?search=#urlencodedformat(r.suggestedquery)#"&gt;#r.suggestedquery#&lt;/a&gt;.&lt;br /&gt;
	&lt;/cfif&gt;
	&lt;/cfoutput&gt;

	&lt;cfoutput query="results"&gt;
		&lt;!--- fix url ---&gt;
		&lt;cfset newurl = listLast(key, "/\")&gt;
		&lt;p&gt;
		&lt;b&gt;#rank#) &lt;a href="/cfdocs/htmldocs/#newurl#"&gt;#title#&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
		&lt;!--- fix context ---&gt;
		&lt;cfset newcontext = htmlEditFormat(context)&gt;
		&lt;cfset newcontext = replace(newcontext, "___999___", "&lt;span style='background-color:yellow'&gt;", "all")&gt;
		&lt;cfset newcontext = replace(newcontext, "___000___", "&lt;/span&gt;", "all")&gt;
		#newcontext#
		&lt;/p&gt;
	&lt;/cfoutput&gt;

	&lt;cfif url.startrow gt 1&gt;
		&lt;cfoutput&gt;&lt;a href="#cgi.script_name#?search=#urlencodedformat(form.search)#&startrow=#max(1,url.startrow-perpage)#"&gt;Previous&lt;/a&gt;&lt;/cfoutput&gt;
	&lt;/cfif&gt;
			
	&lt;cfif r.found gt url.startrow + perpage&gt;
		&lt;cfoutput&gt;&lt;a href="#cgi.script_name#?search=#urlencodedformat(form.search)#&startrow=#url.startrow+perpage#"&gt;Next&lt;/a&gt;&lt;/cfoutput&gt;
	&lt;/cfif&gt;
	
&lt;cfelse&gt;

	&lt;cfoutput&gt;
	Your search for '#form.search#' returned no results out of #r.searched# entries.&lt;br /&gt;
	&lt;cfif structKeyExists(r, "suggestedquery") and len(r.suggestedquery)&gt;
	You may want to search for &lt;a href="#cgi.script_name#?search=#urlencodedformat(r.suggestedquery)#"&gt;#r.suggestedquery#&lt;/a&gt; instead.&lt;br /&gt;
	&lt;/cfif&gt;
	&lt;/cfoutput&gt;
	

&lt;/cfif&gt;	 &lt;/cfif&gt; </code>
Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Comments