WoW Head popups in blogCFC

I'm not completely happy with my solution, but it works. It goes through Blizzard's armory to search for the item and get the item number, then uses wowhead.com to help make the popup.

Like yesterday's post, add a code block to blog.cfc to look for {item ...} code fragments. This is where I'm not happy, I wanted [wowitem ...] to work.

<!--- Check for wowitem blocks --->
<cfif findNoCase("{item ",arguments.string) and findNoCase("}",arguments.string)>
   <cfset armoryCFC=CreateObject("component","sandbox.wow.armory")>
   <cfset counter = findNoCase("{item ",arguments.string)>
   <cfloop condition="counter gte 1">
      <cfset codeblock = reFindNoCase("(?s)(.*)(\{item )(.*)(\})(.*)",arguments.string,1,1)>
      <cfif arrayLen(codeblock.len) gte 6>
         <cfset codeportion = mid(arguments.string, codeblock.pos[4], codeblock.len[4])>
         
         <cfset result = armoryCFC.getItemLinkFromName(codeportion)>
         <cfset newbody = mid(arguments.string, 1, codeblock.len[2]) & result & mid(arguments.string,codeblock.pos[6],codeblock.len[6])>

         <cfset arguments.string = newbody>
         <cfset counter = findNoCase("{item ",arguments.string,counter)>
      <cfelse>
         <cfset counter = 0>
      </cfif>
   </cfloop>
</cfif>

This references armory.cfc, so make it and add these two functions...

getItemLinkFromName

<cffunction name="getItemLinkFromName" access="remote" returntype="string">
   <cfargument name="itemName" default="War-Feathered Loop">
   <cfargument name="baseURL" required="false" default="http://armory.worldofwarcraft.com/">

   <cfset var url = arguments.baseURL
         & "search.xml?searchQuery=" & URLEncodedFormat(arguments.itemName)
         & "&searchType=Items">

   <cfset var itemsheet = makeHTTPCall(url)>
   <!--- initialize variables to be used --->
   <cfset var items = "">
   <cfset var ret = "">
            
   <cfif left(itemsheet.statuscode,3) neq "200">
      <cfreturn arguments.itemName/>
   </cfif>
   
   <cfset items = XMLParse(itemsheet.fileContent).page.armorySearch.searchResults.items>
   
   <cfif ArrayLen(items.XMLChildren) eq 0>
      <cfreturn arguments.itemName/>
   </cfif>
   
   <cfset ret = "<a href='http://www.wowhead.com/?item=#items.XMLChildren[1].XMLAttributes.id#'>#arguments.itemName#</a>">

   <cfreturn ret>   
</cffunction>

makeHTTPCall

<cffunction name="makeHTTPCall" returntype="struct">
   <cfargument name="url" required="true">
   <!---
   Store the user agent that I am using with my browser
   --->

   <cfset var strUserAgent = (
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; " &
            "rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"
            ) />

            
   <cfhttp
      url="#arguments.url#"
      method="GET"
      result="armoryXML"
      useragent="#strUserAgent#"
      />

   
   <cfreturn armoryXML>
</cffunction>

Then add somewhere in your page, a script block for WOW Head ...

The magic in that script will add the popup to all links to wowhead.com, woo! If the item isn't found in the armory, it will just print the name of the item. Problem though, is if more than one item is found, it'll make a link to the first item. This is needed though. Boots of the Crimson Hawk is made from Pattern: Boots of the Crimson Hawk. Doing a search for the boots returns the pattern as well. I'm guessing armory returns items in alphabetical order.

So what happened with making a [wowitem ...]? It was fine when there was only one in the post, but could wrap the first "[wowitem" with the final "]" if there was more than one. If someone with better regex knowledge than I can solve this, please share!

Related Blog Entries

Comments
I'm no RegEx master, but what you're using is considered a "greedy" expression, and you want a non-greedy expression. As I understand it, a greedy expression will match as much as possible (hence the first "[wowitem" with the last "]"), while a non-greedy expression will match the first, simplest (smallest?) substring it can find.

Check out this article for a pretty in-depth conversation on how it works in CF: http://www.bennadel.com/blog/302-Non-Greedy-Regula...
# Posted By Adam | 5/6/08 12:16 PM
Although I'm a CF developer, I am not well versed in CFCs or regex, and I'm having problems getting this to work with my blogCFC...I keep getting this:

<code>
Element STRING is undefined in ARGUMENTS.

The error occurred in org\camden\blog\blog.cfc: line 2448

2446 :
2447 : <!--- Check for wowitem blocks --->
2448 : <cfif findNoCase("{item ",arguments.string) and findNoCase("}",arguments.string)>
2449 : <cfset armoryCFC=CreateObject("component","sandbox.wow.armory")>
2450 : <cfset counter = findNoCase("{item ",arguments.string)>

</code>

This happens if I try to refresh the blog cache, but if I go straight to it, nothing happens, it just shows me
<code> {item Green Silken Shoulders}</code>
on the page.


This seems like an awesome addon for the blogCFC...any thoughts as to what I've done wrong? :)
# Posted By Stacy | 6/27/08 12:57 PM
@Stacy - You put the code in the renderEntry() function of blog.cfc, right? The function, out of the box, should have "string", "printformat", and "enclosure" arguments. What version of blogCFC are you running? Maybe Ray made changes to the renderEntry() function's input at some point?
# Posted By Murloc Oracle | 6/30/08 10:51 AM
I didn't have it inside the render function, I switched that and am no longer getting the error, however, now it is putting just the text of the item on the page

<code>
{item Green Silken Shoulders}
</code>

(ROFL...I really need to get up to speed on CFCs!)

Thanks for your help!!
# Posted By Stacy | 7/3/08 8:45 AM
I didn't have it inside the render function, I switched that and am no longer getting the error, however, now it is putting just the text of the item on the page

<code>
{item Green Silken Shoulders}
</code>

(ROFL...I really need to get up to speed on CFCs!)

Thanks for your help!!
# Posted By Stacy | 7/3/08 8:45 AM
You can see what I'm talking about here:

http://www.trentandstacy.com/tands/stacy/

(sorry for the double-post btw!) :D
# Posted By Stacy | 7/3/08 8:50 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.002. Contact Blog Owner