skip to content

DRYing up Flash Embedding

3 min read

Most of the Flash embedding I’ve done has involved passing in some dynamic variables to the flash. After trying a few different techniques for passing in those variables, I believe I found a solution I’m happy with. I use the jQuery SWFObject plugin, the jQuery Metadata plugin with JSON, and a small helper plugin to keep things DRY.

jQuery SWFObject

The jQuery SWFObject brings the awesomeness that is SWFObject to the “jQuery Way” of doing things. For example, to embed a simple Flash movie you would write the following JavaScript.

jQuery(function($) { // document ready
    $('#myFlash').flash({ src: 'myflash.swf' });
});

A more complex movie embed might look like this.

jQuery(function($) { // document ready
    $('#myFlash').flash({
        src: 'myflash.swf',
        width: 500,
        height: 250,
        hasVersion: 10,
        expressInstaller: 'installer.swf',
        params: {
            wmode: 'transparent',
            loop: true,
            bgcolor: '#ffffff'
        },
        flashvars: {
            name: 'Joe',
            age: '21'
        }
    })
});

You can find more examples, find out about the defaults, and more on the jQuery SWFObject’s site.

As you can see we are just passing in an object containing a key value pair of settings. Lets take a look at the Metadata plugin now.

Metadata

The Metadata plugin provides us with the ability to easily embed some extra (or meta) data into our HTML that the JavaScript can then use. There are several different ways you can use the Metadata plugin to embed data: via a class, custom attribute or a script tag. I prefer to use a script tag with a type set to “application/json”.

We could embed our flash options using the script tag technique like this.

<div id="myFlash">
    <script type="application/json">
        {
            src: 'myflash.swf',
            width: 500,
            height: 250,
            flashvars: {
                name: 'Joe',
                age: '21'
            }
        }
    </script>
    <p>This is where your alternate content would go.</p>
</div>

Of course we could use our choice back-end tool to make any of those values dynamic. For example, in Rails I often use a Ruby Hash and the to_json method like this.

<div id="myFlash">
    <script type="application/json"><%=
        {
            :src => 'myflash.swf',
            :width => 500,
            :height => 250,
            :flashvars => {
                :name => @person.name,
                :age => @person.age
            }
        }.to_json
    %></script>
    <p>This is where your alternate content would go.</p>
</div>

To get to this data we would use the metadata method like this.

jQuery(function($) { // document ready
    var $div = $('#myFlash'),
        data = $div.metadata({ type: 'elem', name: 'script' });
});

Now all we need to do is pass along the data as-is to the jQuery SWFObject plugin like this.

jQuery(function($) { // document ready
    var $div = $('#myFlash'),
        data = $div.metadata({ type: 'elem', name: 'script' });
    $div.flash( data );
});

Keeping it DRY

If you have more than one flash div then you’ll end up repeating the above code for each one. So, lets turn this into a little helper/utility plugin.

jQuery.fn.setup_flash = function() {
    return this.each(function() {
        var $this = jQuery(this),
            data = $this.metadata({ type: 'elem', name: 'script' });
        $this.flash( data );
    });
};

Now we can give all our elements that should be flash, a class name and use the setup_flash plugin like this.

jQuery(function($) { // document ready
    $('.flash').setup_flash();
});

There is one more tweak we can make to keep code repetition to a minimum. Notice I told the Metadata plugin that I was using a script element to store the metadata. Since I typically always use a script element for my metadata I set it as the default like this.

jQuery.metadata.setType('elem', 'script');

Now we can just call .metadata() without passing anything in.

jQuery.fn.setup_flash = function() {
    return this.each(function() {
        var $this = jQuery(this), data = $this.metadata();
        $this.flash( data );
    });
};