Broken comments

If you’ve attempted to leave comments recently, you probably ended up here – I apologize for that. It wasn’t an editorial comment, honest.

I’m using two anti-comment-spam plugins – Kitten’s Spam Words and Three Strikes SPAM. I marked the first piece of spam I received with Kitten’s Spam Words, and it incorrectly identified the local gateway IP as the source of the post and added it to the list of common spam words… Oops!

The two filters are not at fault, it is not easy to identify the source IP of a post (especially when the request comes from the maze of routers that is my upstream provider). It’s my fault for not recognizing the IP for what it was.

Canadian iTunes Music Store

Coming in November!

SAN JOSE, California—October 26, 2004—Apple® today launched a European Union version of its revolutionary iTunes® Music Store, giving music fans in Austria, Belgium, Finland, Greece, Italy, Luxembourg, Netherlands, Portugal and Spain the same innovative features and breakthrough price of €0.99 per song that have made iTunes the number one online music service in the world. With Apple’s legendary ease of use, pioneering features such as iMix playlist sharing, seamless integration with iPod® and groundbreaking personal use rights, the iTunes Music Store is the best way for PC and Mac® users to legally discover, purchase and download music online. Apple today also announced it will launch the iTunes Music Store in Canada in November.

Time to pay down the credit cards…

Surfin’ no more.

RSS has had a profound affect on the way I use the web. I check my subscriptions using PulpFiction a couple of times a day, occasionally adding new feeds that I find there, but I rarely surf any more. Safari’s running pretty much all the time – I develop web based applications after all – but It’s not getting the workout it used to.

Using WebObjects DirectActions – pt. 2

At the conclusion of part one of this mini-series we had successfully configured a WebObjects application to accept DirectActions, had written a simple DirectAction method, and created a WOHyperlink to trigger it. Now it’s time to look at some of the common additional requirements you might encounter. As I mentioned last time they are:

  1. Passing parameters to our action
  2. Accessing a database with our action
  3. Invoking or using a Session with our action

Each of these will take a little work to get through, so I’m going to tackle them in several separate posts. Today we will look at passing parameters to our actions. We are going to extend the examples we used last time so fire up your IDE (Eclipse I hope) and lets get started.

Passing parameters to a DirectAction

Being able to trigger an action based on the URL is fun and all, but often we will want to do more. More? what could we possibly want that is more? Well submitting a form to a direct action URL might be nice, or passing a value to the next page for display or to modify its behaviour would be cool too.

To get this to work we have a number of issues to cover:

  1. Handling parameters in our action
  2. Passing a single parameter to our action
  3. Passing multiple parameters to our action

1. Handling parameters in our action

The first thing we are going to tackle is to get our DirectAction to handle parameters attached to our URL. Our DirectAction class has access to a WORequest object through the request() method. The WORequest contains a bunch of information about the current request, including any form values – which is how we will be passing values into our DA’s. These can be accessed through the following methods:

  • formValues()
  • formValuesForKey(String aKey)
  • formValueForKey(String aKey)

I suggest you take a look at the documentation for WORequest for more information but here is a brief summary of what they do:

  • formValues – returns an NSDictionary with all of the form values. The names are represented as the NSDictionary keys each with an NSArray containing its value(s).
  • formValuesForKey – returns an NSArray of the form value(s) that match a given name (key).
  • formValueForKey – returns an Object that is one of the value(s) that matches a given name (key).

Note: formValues() and formValuesForKey(String aKey) will return NSArray’s of values. This is because multiple form values can be associated with any given name (key). The NSArrays returned are sorted in no particular order – be warned.

Similarly, the Object returned by formValueForKey(String aKey) will be arbitrarily chosen from the NSArray of returned values – only use this method if you can be assured that there is only one value for each key (or don’t care which value you receive).

Lets extend the helloWorld example from last time to see how this works. Open your project and modify the helloWorld method in the DirectAction.class so it looks like this:

public WOActionResults helloWorldAction() {
	// Using formValues()
	NSDictionary dict = this.request().formValues();
	System.out.println("Form Values for request: " + dict);
	WOComponent page = pageWithName("Main");
	page.takeValueForKey("Hello World", "myDisplayString");
	return page;

Granted, this is not awe inspiring code, but it will help us to explore the next section.

2. Passing a single parameter to our action

Build the application and run it. If you are working on the project we built last time your web browser should open a new page with a single link. Click on the link to get to the Hello World page. You should see something like this in your console:

Form Values for request: {}

Which is understandable, as we haven’t supplied any values. Let’s change that. Append the following to the current URL "?=thisIsATest" so it looks like this:


The STD_WEBO_URL will look something like: "localhost:55555/cgi-bin/WebObjects/" it’s abbreviated for brevity… and to make it shorter too.

Hit return to submit the modified URL and you should see this in the console:

Form Values for request: { = ("thisIsATest"); }

Because we did not append a key-value pair to the URL, our resulting dictionary is missing the key. This is fine if we don’t need to uniquely identify our values. If we are just passing one value, we can retrieve it using formValueForKey("").

3. Passing multiple parameters to our action

Having one value is rare, in my experience, so lets look at identifying our value with a key. Appending a key to the URL is easy, the resulting URL will look like this:


Submitting this URL to our application should give us this in the console:

Form Values for request: {aKey = ("thisIsATest"); }

We can explicitly retrieve this value using formValueForKey("aKey").

Finally, lets look at sending multiple key-value pairs. Simply append additional pairs (key1=value1) separated by an & symbol:


This URL should give us the following in the console:

Form Values for request: {key1 = ("value1"); key2 = ("value2"); }

Again, using formValueForKey("keyN") will allow us to get each of these values from the request.

You should now have a pretty good idea of how a simple DirectAction works, and how values are encoded into the URL. However, it would be nice if we could get the URLs without having to enter them by hand. So, next time we’ll look at generating the DirectAction URLs by using the bindings on WebObjects WODynamicElements.