Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Saturday, October 03, 2009

Tapestry 5.1 and IE 8 -- Customizing Tapestry

Tapestry is nice enough to bundle the Prototype and Scriptaculous libraries its client-side support is wired against, which is very convenient ... until you find out the the packaged version is not compatible with your shiny new browser, such as Internet Explorer 8.

Tapestry IoC to the rescue: you can override where Tapestry looks for the Prototype & Scriptaculous files (alas, it currently looks in the exact same place for them). Where these files are stored, and how they are exposed to the client is controlled by two contributions inside TapestryModule:

    public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
    {
        . . .

        configuration.add("tapestry.scriptaculous", "classpath:${tapestry.scriptaculous.path}");
        configuration.add("tapestry.scriptaculous.path", "org/apache/tapestry5/scriptaculous_1_8_2");

        . . .
    } 

    public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration,

      @Symbol(SymbolConstants.TAPESTRY_VERSION)
      String tapestryVersion,
      @Symbol("tapestry.scriptaculous.path")
      String scriptaculousPath)
    {
       . . .

       configuration.add("scriptaculous/" + tapestryVersion, scriptaculousPath);

       . . .
     }

The first contributions set where, on the classpath, the Prototype & Scriptaculous files are located, defining symbols that can be referenced in various servers. The second uses some of those symbols (and a few others) to map the classpath location to a URL (this is the job of the ClasspathAssetAliasManager service).

However, what's being contributed is Prototype 1.6.0.3 and for compatibility with Internet Explorer 8, we need the latest and greatest: 1.6.1. That's what tapx-prototype does. And at its core it's just a couple of lines of code:

public class PrototypeModule
{
    public void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
    {
        configuration.override("tapestry.scriptaculous.path", "com/howardlewisship/tapx/prototype");
    }

    public static void contributeClasspathAssetAliasManager(
            MappedConfiguration configuration)
    {
        configuration.add("tapx-prototype/1.6.1", "com/howardlewisship/tapx/prototype");
    }
}

Notice that we can just override part of the configuration of one service (FactoryDefaults) and extend the configuration of another service (ClasspathAssetAliasManager) without disturbing anything else. This is Tapestry IoC in a nutshell!

Glenn Vanderburg has been popularizing a terminology for extensible software: a "seam" is any point where existing software can be extended. He's used to the Ruby world where, literally, every method is a seam. Tapestry, too, is all seams ... every service, and (with more effort than Ruby) every method of every service is a seam, and lots of effort has gone into the design of Tapestry IoC to ensure that it can be extended without massive cut-and-paste or other disruptions.

I'll be releasing the tapx code soon as a stable release, once I do a little more testing with IE8.

3 comments:

Unknown said...

good option, can this be extended to use the one cached by Google?
http://www.prototypejs.org/2008/5/27/prototype-hosted-on-google-s-servers

thanks

Unknown said...

In theory, yes. In practice, that will shut down Tapestry's ability to use Javascript aggregation.

fritz the cat said...

"Tapestry is nice enough to bundle the Prototype and Scriptaculous libraries its client-side support is wired against, which is very convenient ..."
You call that nice, I call that a burden.
I'd much prefer if you left the choice of which front end libraries to use to us, the front end developers.