– Common Function Library Project

highlightAndCrop(string, term[, size][, wrap])

Last updated March 24, 2010


Raymond Camden

Version: 2 | Requires: CF6 | Library: StrLib

This UDF will search a string for keywords and return them highlighted. It also crops the string "around" the matched term. Useful on search results pages. This UDF requires ColdFusion 9 only because of the use of var after the beginning of the UDF. It could easily be modified to work in CFMX.

Return Values:
Returns a string.




Name Description Required
string String to scan/crop. Yes
term Search term to find/highlight. Can be a list. Yes
size Size of the cropped string. Defaults to total size of the string. No
wrap The HTML to use to wrap the term. No

Full UDF Source:

 Crops a string and highlights keywords.
 v2 mods by Tuyen (
 @param string      String to scan/crop. (Required)
 @param term      Search term to find/highlight. Can be a list. (Required)
 @param size      Size of the cropped string. Defaults to total size of the string. (Optional)
 @param wrap      The HTML to use to wrap the term. (Optional)
 @return Returns a string. 
 @author Raymond Camden ( 
 @version 2, March 24, 2010 
<cffunction name="highlightAndCrop" access="public" output="false" hint="Given an arbitrary string and a search term, find it, and return a 'cropped' set of text around the match.">
    <cfargument name="string" type="string" required="true" hint="Main blob of text">
    <cfargument name="term" type="string" required="true" hint="Keyword to look for.">
    <cfargument name="size" type="numeric" required="false" hint="Size of result string. Defaults to total size of string. Note this is a bit fuzzy - we split it in two and return that amount before and after the match. The size of term and wrap will therefore impact total string length.">
    <cfargument name="wrap" type="string" required="false" default="<b></b>" hint="HTML to wrap the match. MUST be one pair of HTML tags.">

    <cfset var excerpt = "">
    <cfset var pad = "">
    <cfset var match = "">
    <cfset var thisKeyword = "">
    <cfset var end = "">
    <cfset var endInitialTag = "">
    <cfset var beginTag = "">
    <cfset var endTag = "">
    <!--- clean the string --->
    <cfset arguments.string = trim(rereplace(arguments.string, "<.*?>", "", "all"))>

    <!--- pad is half our total --->
    <cfif not structKeyExists(arguments, "size")>
        <cfset arguments.size = len(arguments.string)>
    <cfset pad = ceiling(arguments.size/2)>

    <cfloop list="#arguments.term#" index="thisKeyword">
        <cfif match is 0>
            <cfset match = findNoCase(thisKeyword, arguments.string)>
        <cfelseif findNoCase(thisKeyword, arguments.string) lt match>
            <cfset match = findNoCase(thisKeyword, arguments.string)>
    <cfif match lte pad>
        <cfset match = 1>
    <cfset end = match + len(arguments.term) + arguments.size>

    <!--- now create the main string around the match --->
    <cfif len(arguments.string) gt arguments.size>
        <cfif match gt 1>
            <cfset excerpt = "..." & mid(arguments.string, match-pad, end-match)>
            <cfset excerpt = left(arguments.string,end)>
        <cfif len(arguments.string) gt end>
            <cfset excerpt = excerpt & "...">
        <cfset excerpt = arguments.string>

    <!--- split up my wrap - I bet this can be done better... --->
    <cfset endInitialTag = find(">",arguments.wrap)>
    <cfset beginTag = left(arguments.wrap, endInitialTag)>
    <cfset endTag = mid(arguments.wrap, endInitialTag+1, len(arguments.wrap))>

    <cfloop list="#arguments.term#" index="thisKeyword">
        <cfset excerpt = reReplaceNoCase(excerpt, "(#thisKeyword#)", "#beginTag#\1#endTag#","all")>
    <cfreturn excerpt>


Latest Additions

Raymond Camden added
November 04, 2017

Leigh added
May 11, 2016

Raymond Camden added
May 10, 2016

Kevin Cotton added
May 05, 2016

Raymond Camden added
April 25, 2016

Created by Raymond Camden / Design by Justin Johnson