A Guide to Druid Forms

Over my time off and on World of Warcraft, I’ve seen a number of questions regarding Druid Forms. Well, the other day while reading a random WoW forum, I stumbled on an animated signature image that detailed some of the key forms a Druid character can become. Here are the words of wisdom:

druid_bear
druid_cat
druid_travel
druid_seal

Amazing descriptions to live by. Thank you. That is all.

Remote JavaScripting Example – Part I

[[innerindex]]At Plymouth State we work in a multi-server environment and often wish to display dynamic content from one server in an Ajax-like fashion on another server’s website. My co-worker, Zach Tirrell, and I have drummed up a solution that works to keep our layout and logic separate, while still serving our end users in a smooth, seamless, non-iFramed manner.

I’ll walk through the creation of a simple search ‘widget’ that relies on dynamic data to populate a drop-down box.

The Tools

- PHP
- JavaScript
- XTemplate
- RemoteJSOutput: a simple script by Matthew Batchelder (me) and Zach Tirrell

Step 1: create your template

This widget is fairly simple and thus has a simple template. The template syntax is simply XTemplate syntax.

I’ll name it widget.tpl and store it in a templates directory.

<!-- BEGIN: main -->
<div id="sweet_borkweb_widget" style="background:#eee;border:1px solid #ccc;text-align:center;">
  <div style="color:#000;">A Couple JavaScript Posts at BorkWeb</div>
  <select id="borkweb_posts">
    <option value=""></option>
  <!-- BEGIN: post -->
    <option value="{post.url}">{post.title}</option>
  <!-- END: post -->
  </select>
</div>
<!-- END: main -->

Step 2: simple template output

First we’ll just spit out the template. Lets create a PHP file to do this. We’ll call it widget.php

< ?php
include('includes/xtemplate.php');
$xtpl = new XTemplate('templates/widget.tpl');

$xtpl->parse('main');
$xtpl->out('main');
?>

Check out your widget so far. Its plain. Lets change that.

Step 3: add dynamic content

We want the drop down list to hold BorkWeb articles. We’ll add that in now.

Note: this is where you would normally pull from a database, an RSS feed, or some other source. For simplicty, we’ll be using a simple PHP array. Whoop-de-doo. Here it is:

< ?php
include('includes/xtemplate.php');
$xtpl = new XTemplate('templates/widget.tpl');

//get list of articles
$articles=array(
  array('title'=>'Ajax, More Than A Buzz Word','url'=>'http://borkweb.com/story/ajax-more-than-a-buzz-word'),
  array('title'=>'Ajax; Templating; and the Separation of Layout and Logic','url'=>'http://borkweb.com/story/ajax-templating-and-the-separation-of-layout-and-logic'),
  array('title'=>'Deleting the Internet','url'=>'http://borkweb.com/story/deleting-the-internet'),
  array('title'=>'Node Manipulation in the DOM','url'=>'http://borkweb.com/story/node-manipulation-in-the-dom'),
  array('title'=>'Prototype Cheat Sheets','url'=>'http://borkweb.com/story/prototype-cheat-sheets'),
  array('title'=>'Script.aculo.us Is My New Best Friend','url'=>'http://borkweb.com/story/scriptaculous-is-my-new-best-friend'),
  array('title'=>'The Case For JSON: What Is It and Why Use It?','url'=>'http://borkweb.com/story/the-case-for-json-what-is-it-and-why-use-it')
);

//loop over articles and place in template
foreach($articles as $article)
{
  $xtpl->assign('post',$article);
  $xtpl->parse('main.post');
}//end foreach

$xtpl->parse('main');
$xtpl->out('main');
?>

Check out your widget now. It has been populated with some data! w00t! Now to make it work, we return to our beloved widget.tpl template file.

Step 4: make the template work

We’re going to add in some javascript. Lets make the dropdown list redirect the user to the selected article when the drop-down box changes.

I’m going to add this on our select box:

 onchange="if(document.getElementById('borkweb_posts').value!='') document.location=document.getElementById('borkweb_posts').value;"

The template should now look like this:

<!-- BEGIN: main -->
<div id="sweet_borkweb_widget" style="background:#eee;border:1px solid #ccc;text-align:center;">
  <div style="color:#000;">A Couple JavaScript Posts at BorkWeb</div>
  <select id="borkweb_posts" onchange="if(document.getElementById('borkweb_posts').value!='') document.location=document.getElementById('borkweb_posts').value;">
    <option value=""></option>
  <!-- BEGIN: post -->
    <option value="{post.url}">{post.title}</option>
  <!-- END: post -->
  </select>
</div>
<!-- END: main -->

Step 5: prepare script for remoting

Now that our lovely widget is functioning, lets prepare it for inclusion in other locations. This is simple using RemoteJSOutput (a simple script written by Zach Tirrell and myself).

We’ll include that PHP class and use it as follows:

< ?php
include('includes/RemoteJSOutput.class.php');
$remoteOutput=new RemoteJSOutput();

//start output buffering via 
$remoteOutput->start();

include('includes/xtemplate.php');
$xtpl = new XTemplate('templates/widget.tpl');

//get list of articles
$articles=array(
  array('title'=>'Ajax, More Than A Buzz Word','url'=>'http://borkweb.com/story/ajax-more-than-a-buzz-word'),
  array('title'=>'Ajax; Templating; and the Separation of Layout and Logic','url'=>'http://borkweb.com/story/ajax-templating-and-the-separation-of-layout-and-logic'),
  array('title'=>'Deleting the Internet','url'=>'http://borkweb.com/story/deleting-the-internet'),
  array('title'=>'Node Manipulation in the DOM','url'=>'http://borkweb.com/story/node-manipulation-in-the-dom'),
  array('title'=>'Prototype Cheat Sheets','url'=>'http://borkweb.com/story/prototype-cheat-sheets'),
  array('title'=>'Script.aculo.us Is My New Best Friend','url'=>'http://borkweb.com/story/scriptaculous-is-my-new-best-friend'),
  array('title'=>'The Case For JSON: What Is It and Why Use It?','url'=>'http://borkweb.com/story/the-case-for-json-what-is-it-and-why-use-it')
);

//loop over articles and place in template
foreach($articles as $article)
{
  $xtpl->assign('post',$article);
  $xtpl->parse('main.post');
}//end foreach

$xtpl->parse('main');
$xtpl->out('main');

//spit out script encased in JS
$remoteOutput->puke();
?>

Now check out your widget. Ugly, huh? Well, don’t worry, thats the way its supposed to look for now.

Step 6: place your widget somewhere

Now that we have that beautiful chunk of code in operation, place it on a webpage somewhere.

Put this:

<script type="text/javascript" src="http://url.to/your/widget.php"></script>

on any page you wish to test your widget!

Optional Step 7: create a wrapper

If, like me, you aren’t a fan of including RemoteJSOutput.class.php all over hell’s half acre, you can create a wrapper. This not only allows you to minimize the code you have to repeatedly place everywhere, but it also keeps your widget.php script functional on its own!

Here’s an example wrapper I’ll call get_script.php which will display wrapper_widget.php (step 3′s PHP file, renamed):

< ?php
include('includes/RemoteJSOutput.class.php');
$remoteOutput=new RemoteJSOutput();

//start output buffering via 
$remoteOutput->start();

//create a list of allowable widgets/scripts/yadda yadda
$allow=array('wrapper_widget');

//does the passed variable exist in the allowable widgets?
if(in_array($_GET['script'],$allow))
{
  //include the wrapper
  include($_GET['script'].'.php');
}//end if

//spit out script encased in JS
$remoteOutput->puke();
?>

So rather than using the script tag that Step 6 suggests, we’d use:

<script type="text/javascript" src="http://url.to/your/get_script.php?script=wrapper_widget"></script>

Conclusion

This method is simplistic and is simply touching on the topic of widgetization. I will be following up with dynamic user interactions in Part II, and finally discuss an open-standard widget library with xml definitions. Stay tuned :)

Download

Oh, and here’s the code used in this tutorial all zipped up.

The Case For JSON: What Is It and Why Use It?

[[innerindex]]

A Little Background

After my post titled Look Ma, Cross Domain Scripting! a while back, I received a comment that was seeking more information. The commenter posts:

I’m looking at your code and it doesn’t explain exactly how this works, it just provides us with code to use. I’m curious as to what makes JSON work and what differences JSON has from XML. Is there any draw-backs or negative effects of using your solution? Is it a hack that will be fixed in the future?

If you know all about JSON and are wondering why to use it…I’ll tell you right now. Speed. But…if you are curious, I’ll attempt to answer the above questions, show some examples and then I’ll re-iterate Cross-Domain Scripting.

What is JSON?

JSON (or JavaScript Object Notation) is a highly portable data interchange format. While its structure is recognized natively by Javascript (as it is Javascript), its formatting conventions are easily recognized by other C-like languages. JSON.org has an excellent description:

JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangable with programming languages also be based on these structures.

In JSON, they take on these forms:

  • An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).
  • An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).
  • A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.
  • A string is a collection of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string.

Excepting a few encoding details, that completely describes the language.

JSON Structure

Here is a graphical representation of the formatting structure (image from JSON.org):


oav

Why JSON over XML?

Alright…I can already see the hordes of people wanting to wrench my head from my neck and drive lollipop sticks up my nose. But take a step back, put down the weapons and hear me out.

XML is versatile. You can create tags to your hearts content and endlessly nest data in seemingly sensible ways. XML is well known and most savvy developers can manipulate it in all sorts of ways. So what isn’t there to like about it? It just so happens that XML is like a fat tick after a good meal…bloated. Despite its ease of creation, the amount of busy tags makes it difficult to read with the human eye. Ok…don’t get me wrong, its easier to read than a Comma Separated file, but when compared to JSON, XML makes my head hurt.

JSON is simple and can represent the exact same data with fewer characters. How? Well, there are no tags. You give a member a name and then a value. Lets compare some examples…

JSON Examples

Lets say I want to expose two quotes from my friends at Uber-Geeks in some way…lets compare them in XML and JSON.

<quotes>
  <quote>"50 degrees all week today." - Ironmule</quote>
  <quote>"He wasn't naked...he had sneakers on." -Jon Emmons</quote>
</quotes>
{quotes:[
    "\"50 degrees all week today.\" - Ironmule",
    "\"He wasn't naked...he had sneakers on.\" -Jon Emmons"
  ]
}

That doesn’t seem too different…lets try something a little more complex. How about a Konfabulator Widget?

<widget>
    <debug>on</debug>
    <window title="Sample Konfabulator Widget">
        <name>main_window</name>
        <width>500</width>
        <height>500</height>
    </window>
    <image src="Images/Sun.png" name="sun1">
        <hoffset>250</hoffset>
        <voffset>250</voffset>
        <alignment>center</alignment>
    </image>
    <text data="Click Here" size="36" style="bold">
        <name>text1</name>
        <hoffset>250</hoffset>
        <voffset>100</voffset>
        <alignment>center</alignment>
        <onmouseup>
            sun1.opacity = (sun1.opacity / 100) * 90;
        </onmouseup>
    </text>
</widget>
{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    },
    "text": {
        "data": "Click Here",
        "size": 36,
        "style": "bold",
        "name": "text1",
        "hOffset": 250,
        "vOffset": 100,
        "alignment": "center",
        "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
    }
}}  

The more complex the data you are trying to represent, the sexier JSON looks in comparison. Check here for some more examples…one is really long and looks quite sexy and readable in JSON and not so much in XML.

JSON and the Ajax Buzz

Ok, so if JSON and XML are pretty much peas in a pod when it comes to what they can represent, why make the switch (or at least…provide JSON). Ajax is our reason! You see, in an Ajax environment where we make calls to web services we expect to get some data back in some form. Well, if we receive XML back as a direct result of an Ajax call, we have to send that data through an XML parser before we can even begin to manipulate the data to be useful to JavaScript. If we receive the data in JSON…we don’t have to do anything but assign the results to a variable because JSON is already JavaScript. From there, we can manipulate the data as normal.

As Ajax methodologies (and even Cross Domain Scripting) become more commonplace, data format becomes vital to the efficiency of our applications. The Zimbra folks seem to have realized this and subsequently re-architected their entire application. Oh, and Script.aculo.us creator Thomas Fuchs seems to agree and states his opinion on XML in Ajax communication: Its dog slow…don’t do it.

JSON and Cross Domain Scripting

In my article Look Ma, Cross Domain Scripting, I discuss a method for doing Ajax-like calls to remote domains. As many of you may or may not know, XMLHttpRequest is restricted from making requests to remote domains.

The way it works is this: Somewhere out there exists a server side script that you wish to access in an Asynchronous fashion. Rather than attempting an XMLHttpRequest (which we know won’t work), all you do is dynamically create a <script> tag with its src set to the URL of the off-site page. When a script tag is inserted, browsers immediately execute the src! As long as the off-site page returns valid JSON, the JSON is executed locally.

For dynamically adding script tags, I use this library found over at Dan Theurer’s Blog. Its pretty simple and prevents duplicate script tags (which is a necessity).

Yahoo! sets a good example. They allow you to pass in two parameters to any of their web services (which return XML by default) and get the results in JSON.

Get JSON Output with output=json

By default the Yahoo! Web Services return output in XML format. To get output in JSON format, use the output=json parameter in the request:

http://api.search.yahoo.com/ ImageSearchService/V1/ imageSearch?appid=YahooDemo &query=Madonna&results=2 &output=json

Add a Callback with callback=function

The callback parameter (callback=function) wraps the JSON output text in parentheses and a function name of your choosing. For example:

http://api.search.yahoo.com/ ImageSearchService/V1/ imageSearch?appid=YahooDemo &query=Madonna&results=2 &output=json&callback=ws_results

This request results in this output:

ws_results( …json output… );

What is the drawback of this cross-domain solution? Well, I am relying on browsers to automatically execute the JavaScript in any dynamically created script tags. I have yet to find a mainstream browser that doesn’t…but the same goes for XMLHttpRequest. This method is used within Plymouth State University‘s live portal for Savable State Channels and we have yet to receive a support call regarding problems :)

JSON Resources

  • JSON.org: This site is the JSON site. It provides a description of what JSON is, provides some examples, and provides a list of JSON parsers for various languages.
  • Wikipedia: Enough said.
  • JSON Discussion Group
  • Yahoo’s JSON Web Services: Provides examples and suggestions on formatting your REST calls to return JSON as an option

Summary

XML works nicely. JSON works just as nicely and faster. This is why I’m a JSON fan. Speed is just as important as the data itself. Without speed…well, you’ve got crap.