I have created a function within a format.cfc
component that returns a string without any HTML code in it:
<cffunction name="RemoveHTML" access="public" returntype="string" output="false" hint="Returns a string without any html">
<cfargument name="UserString" required="yes">
<cfset var result = "#REReplaceNoCase(Canonicalize(ARGUMENTS.UserString,false,true),'<[^>]*(?:>|$)', '', 'ALL')#">
<cfreturn result>
</cffunction>
I now want to split the string at each space and convert it into a list. So I tried using ValueList() and ListToArray() but they don't like the value returned from the function.
Using ValueList() I get an error saying:
Complex constructs are not supported with function ValueList
Or I get this error when using ListToArray:
Complex object types cannot be converted to simple values
I'm basically just doing this:
<!--- ValueList() --->
<title>#ValueList(Application.Format.RemoveHTML(UserString = rsProduct.Title), ' ')#</title>
<!--- ListToArray() --->
<title>#ListToArray(Application.Format.RemoveHTML(UserString = rsProduct.Title), ' ')#</title>
If I remove the ListToArray() or ValueList() function then I get back what I expect - a product title string with no HTML in it.
So why is the function not returning a string even though it looks like one? Or am I missing something completely obvious?
As others have noted in the comments, ValueList
is designed to return a list of values that are contained in a column of a query object. It won't work with a string value.
ListToArray
converts a list to an array. You can't then output an array in your HTML. So ListToArray
is working fine, it's when you try to display it in a cfoutput
that the error occurs.
It's a good idea to use the in-built encoding functions in CF, for example encodeForHTML
. So you can do something like:
<title>#encodeForHTML(Application.Format.RemoveHTML(UserString = rsProduct.Title))#</title>
encodeForHTML
, can accept an optional boolean 2nd argument (which is false by default), to indicate if you want to canonicalize the string. So you may want to do that instead of calling Canonicalize
in your custom RemoveHTML
function. After all your function is called RemoveHTML
not RemoveHTMLAndCanonicalize
:)
In response to OP's comment.
To get a comma delimited list from your 'space delimited' string, then you can use the replace
function. Something like:
<title>#encodeForHTML(replace(RemoveHTML(rsProduct.Title), " ", ",", "all"))#</title>
You can of course, put the replace
inside your custom function, I'm just demonstrating how it works.
You'll need to be aware, that it'll replace all spaces with a comma, so if you have 2 or more spaces in a row then it'll show ,,
(depending on how many spaces). To get around that you can use a regular expression like so:
<title>#encodeForHTML(reReplace(RemoveHTML(rsProduct.Title), " +", ",", "all"))#</title>
You can also use listChangeDelims
intead of reReplace
as it ignores empty elements.
<title>#encodeForHTML(listChangeDelims(RemoveHTML(rsProduct.Title), ",", " "))#</title>
Personally I'd go with the regular expression version as it's more powerful, you'll want to wrap it up in a function though to keep the view nice and clean.