WoW Macro explanation

Overview

To flesh out the example macros, and to learn a bit about the process myself, I wrote a macro to insert World of Warcraft item links into any Confluence page. If you're not familiar with World of Warcraft (or WoW for those in-the-know) it's a MMORPG with millions of players world wide. What better way to show of some CSS and JavaScript integration with Confluence!

First a quick overview of what the macro is trying to do. If you've ever played the game or read any of the many WoW community web sites you would be familiar with item links. Each item in WoW has several properties that describe its use, its impossible to memorize the thousands of different items, so these web sites use javascript to add a popup to display item's details. When you move the mouse over the link the popup appears, showing you the details of the item. This example shows a link to the Skullsplitter Helm.

The macro works by asking the battlenet rest api for details on the item, then uses a velocity template to generate a small snippet of HTML.  Add some jQuery JavaScript wizardry a popup is produced to show the item details to the user.

The Plugin

The World of Warcraft plugin consists of two parts: The Macro, and The Web Resources.

The Macro

The heart of any macro is the execute method. This method is responsible for returning the result of the macro's function, either in HTML or in WikiMarkup.

This macro goes through a very predictable process:

  1. Validate and interpret the parameters
  2. Use the battlenet remote api to get the item details
  3. Use velocity to render the output

For the complete source take a look here.

Validate The Input

Although there is only one parameter for this macro, it may contain an item id (numerical) or the item name (string), so our macro needs to be able to handle either.

This code shows the process to check for the named and unnamed parameters (using the unnamed as preference). The string value is then validated by trying to convert to an integer.

Now that we have valid input, we use our itemMapper component to call to battlenet and return an item for us.  The internals on how this component connects to battlenet can be found in the source.

String witemString = params.containsKey("witem") ? params.get("witem") : params.get("0");

ItemMapping mapping = null;
try {
    mapping = itemMapper.getMappingById(Integer.parseInt(witemString));
} catch (NumberFormatException e) {
    mapping = itemMapper.getMappingByName(witemString);
}

Render the Output

This macro uses velocity to render the output. This is helped using the VelocityUtils class which provides easy to use methods for accessing the Velocity subsystem.

VelocityContext contextMap = new VelocityContext(MacroUtils.defaultVelocityContext());
contextMap.put("mapping", mapping);
return VelocityUtils.getRenderedTemplate("/com/atlassian/confluence/plugins/wowplugin/wow-item.vm", contextMap);

We first create a context map by calling MacroUtils.defaultVelocityContext()). This creates a Map of some useful components for our template rendering. Creating a context like this is important if you want to access macro's and other components supplied by Confluence. This example then places this map into a VeloctyContext object to provide type safety on the put methods.

The template used by this macro is extremely simple.

<!--#requireResource("com.atlassian.confluence.plugins.wow-plugin:resources")-->
<a class="wowlink q${mapping.quality}" href="http://www.wowhead.com/item=${mapping.id}">${mapping.name}</a>

The variable references to are resolved by Velocity as the template is processed. They are looked up in the context we supplied in the macro.  The references to the mapping object resolve to the object we passed in when we rendered the template.

The #requireResource call tell Confluence to include the required resources in the page.

These resources are configured in the atlassian-plugin.xml file inside the plugin.

<web-resource key="resources" name="WoW Resources"
              i18n-name-key="com.atlassian.confluence.plugins.wow-plugin.resources">
    <resource type="download" name="wow.css" location="wow.css"/>
    <resource type="download" name="wowhead.js" location="wowhead.js"/>
    <resource type="download" name="wow.js" location="wow.js"/>
    <resource type="download" name="json2.js" location="json2min.js"/>
    <transformation extension="soy">
        <transformer key="soyTransformer"/>
    </transformation>
    <resource type="download" name="wow-soy.js" location="/com/atlassian/confluence/plugins/wowplugin/soy/wow.soy"/>
</web-resource>

This snippet of the configuration shows the definition of the resources this macro uses. Confluence will use the extension of the name attribute to work out how to link in the resource (ie: link or script tag).

We have two resources, one for the CSS and one for our JavaScript.

Resources

The web resources configured in the previous section contain the CSS formating and JavaScript behavior of the macro.

The Result

You can download this plugin from here and install it through the Administration section of your Confluence instance.

The source is available here.

Compiling the Source

The general details of compiling a plugin applies to this plugin, so follow the instructions there.

For the impatient:

  1. Install JDK 1.5 or later
  2. Install Maven 3 or configure the Atlassian SDK to use maven 3.
  3. Create a settings.xml file (a good start is this one)
  4. Checkout the trunk or a tag of the source
  5. use maven to compile it: mvn clean package
Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport