battletagoneCof5#1879

02 August 2012

Your Very Own Blogger Achievement Feed

I've been struggling with Blogger to display a feed of recent achievements for my main character. There is a gadget available that other WoW Bloggers are successfully using, but no matter what I tried it just wasn't working for me.

Maybe I could make one up? Some Google searches led me to Blizzard's Website and Mobile Feedback forums. There are some great examples of tricks which are mostly PHP solutions to retrieve from the Blizzard APIs.  However, without my own server, PHP is not an option. I needed a JavaScript option to stick into a HTML / JavaScript Gadget. A post by Brawrz outlined a method for realms. Now we're cookin'!

After some trial and error, I'm happy to have an achievement feed over on the sidebar for my main character, a Worgen Hunter.

The Achievement Feed Source
Should you wish to recreate this for your own Blogger site, here's what I did.

Update the Template

First and foremost, we need to add an external script to the template. In Design mode, select the Template option. Then, Edit HTML. You'll be cautioned against this route, but go ahead and proceed!
Search for the ending of the <head> element in your template.  Just before that </head> element, insert these lines:
  1. <!-- JQuery Script -->
  2. <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.2.min.js"></script>

Create the Gadget

Back in Design mode, now we need to go to the Layout option and add a new gadget: HTML/JavaScript. Give this a title and then in the Content section, place the following code (replacing your realm and character name in lines 7 and 8):
  1. <div id="charProfile"></div>
  2. <script type="text/javascript">
  3. var intMax = 10; // define maximum number of achievements to display
  4. // assemble the JSON URL
  5. var bnetRegion = "us";
  6. var bnetUrl = "http://" + bnetRegion + ".battle.net";
  7. var bnetRealm = "REALM_NAME"; // borean-tundra or velen for example
  8. var bnetChar = "CHARACTER_NAME";
  9. var url = bnetUrl + "/api/wow/character/" + bnetRealm + "/" + bnetChar + "?fields=feed&jsonp=?";
  10. $.getJSON( url, function( data ) {
  11. // format the base character profile data
  12. var strCharProfile = "<div><h4>Total Points: " + data.achievementPoints + "</h4></div>";
  13. // write the string to the div
  14. $(strCharProfile).appendTo("#charProfile");
  15. // initialize counter at zero
  16. var intCount = 0;
  17. // loop through each feed entry in the JSON source
  18. $.each(data.feed,function(f,feed){
  19. // only output the feed entries that match the ACHIEVEMENT type and
  20. // ignore the loot drops and boss kill entries.
  21. if (feed.type=='ACHIEVEMENT') {
  22. if (intCount < intMax) { // this is an achievement, so ensure we haven't exceeded our max
  23. // assemble the icon image source url
  24. var blizzIcon = "http://us.media.blizzard.com/wow/icons/18/" + feed.achievement.icon + ".jpg";
  25. // assemble the wowhead.com tooltip lookup
  26. var wowheadUrl = "http://www.wowhead.com/achievement=" + feed.achievement.id;
  27. // format the achievement entry string - icon and link
  28. var strFeed = "<div class=\"charProfile\">" + "<img src=" + blizzIcon + "></img>" + " " + "<a href=" + wowheadUrl + ">" + feed.achievement.title + "</a></div>";
  29. // write the achievement entry to the div
  30. $(strFeed).appendTo("#charProfile");
  31. intCount++; // update our good count
  32. }
  33. else { // we hit more than counter so terminate the .each loop
  34. return false;
  35. } // end counter if
  36. } // end ACHIEVEMENT match if
  37. }); // end $.each
  38. }); // end $getJSON
  39. </script>

Define the Output

First, we define a container in our gadget to contain text. Line 1 creates a <div> and assigns a unique ID to that <div> called "charProfile".  Later, after we've created a string of text and formatted that string with HTML markup, we add that string to the existing <div> with the ID of "charProfile in Line 14.
By the same token, we format another string with the actual achievement feed data and add that string to the existing <div> in line 30.

Get the Data

Next, we're lookup up a character's profile using the Blizzard Community Platform API. Years back, you used to be able to retrive character data from an XML / RSS feed.  No longer! It's all good, though. The forums have some great examples on how to use JQuery to grab the JSON data from the API.

In this case, I wanted the summary of total achievement points and the ten most recent achievements completed.  So let's get cracking.

The URL for my character and region is created in lines 5 to 8, and then line 9 retrieves that data from BattleNet and saves it in an object named 'data'. Great, we have data! Uh, we've got a lot of data. Let's pick out what we want.

Rinse and Repeat

Line 18 starts looping over the results; specifically the 'feed' entries in the results.  For each 'feed' entry contained within the source 'data', we have a function that does something with that selected feed (and it's children). This is where you get the achievement's ID, icon reference, timestamp and other bits.

Validate Selection

However, the 'feed' contains a combination of achievements, boss kills and loot drops. We don't want all that, so how do we skip the unwanted result entries? I'm sure there are more elegant ways, but we're going with the if ... else construct. Line 21 checks if the current 'feed' entry selected above in line 18 is for an achievement. It it is, let's handle it. If not, don't do anything and loop back up to select the next 'feed' element.

But wait, there's more! Not only do we only want achievements, but we only want up to a maximum of ten to show. Otherwise, the entire side bar is achievements!  Line 22 checks that we have not already selected more than our maximum value.  If we are over our max, we don't continue looping through each remaining 'feed'. Nope! Line 34 terminates the loop as soon as we've successfully read our maximum entries.

Display the Goodies

For the output, a sub-heading is written to the gadget first, and then we'll write each selected achievement read during the each loop. Furthermore, with the graciousness of Wowhead's tooltip script, we can link the achievements in a nice pretty tooltip. We're borrowing Blizzard's media by using the reference to the icon within. That's the function of lines 23 - 30.

All in all, I'm happy to have an achievement feed in Blogger. I'm sure that there are more refined ways of accomplishing this, and I may give an actual Google Gadget a go, but for the moment I'm happy.
Thanks for stopping by!

2 comments:

  1. OH MY! I hope this works! I have been struggling to get one that works for my site and if it works Chris I'm gonna be thrilled to bits!

    ReplyDelete
    Replies
    1. If you get stuck on any portion, I'm more than happy to help. I realized that by styling the code to be pretty, when you copy you also get all the line numbers. Bad! Hoping it works for you!
      This is definitely a fun side project for me as I can envision a page with all the updated information on my alt stable! :)

      Delete