Using Apache Server Side Includes From CGI Scripts

You know the story, you’ve inherited a lovely design and XHTML page build from your designer. The pages are modular and built using server side includes (SSI). The site is easy to update, until you’re asked to make something dynamic.

Normally, I’d use Perl‘s excellent Template Toolkit, and just convert the SSIs to Template Toolkit INCLUDEs. However in this case, the SSIs were nested so I couldn’t take this approach.

The solution turns out to be quite easy, especially as I’m using Apache 2 as my webserver.

Apache 2 has output filters, so I can get the output of my CGI scripts to be parsed by Apache for SSIs directly using mod_include.

In my apache conf file, I need to do something like the following.

<Location /cgi-bin/withssi/>
SetHandler cgi-script
SetOutputFilter INCLUDES
Options +ExecCGI +Includes
</Location>

This will turn on SSI parsing on the output of CGI scripts served from the location of /cgi-bin/withssi.

The key line to notice here is SetOutputFilter INCLUDES as that makes sure the output returned is parsed by mod_include before it reaches the web browser.

Knowing When It’s Safe To Talk To Flash From JavaScript – Part 2

In the previous article Knowing When It’s Safe To Talk To Flash From JavaScript we saw how to call Flash from JavaScript.

We embedded the Flash movie directly into the page, however there are times when we may want to insert the movie dynamically using JavaScript. How can we do this?

Well it turns out fairly easily, especially if we use one of the modern JavaScript framework libraries like jQuery.

jQuery is very extendable, and has a powerful plugin based architecture. Thankfully someone has done the hard work for us and written a plugin to handle the embedding of Flash. Take a look at the jQuery.flash plugin.

How do we use it, well first we need to add the two libraries to the page, jQuery and jQuery.flash.

<script type="text/javascript" src="jquery-1.3.2.js"></script>
<script type="text/javascript" src="jquery.flash.js"></script>

In our page body, we’ll add a bit of HTML that will have it’s content replaced by the Flash movie.

<-- the content of the following div will be replaced. -->
<div id="example">Flash here</div>

Now let’s add the JavaScript that will replace the div’s content. We’ll wrap it inside jQuery’s ready function to make sure everything we need is in place. This is a better version of the window.onload function we saw in the previous article that waits until the page can be manipulated, and not until everythting has been downloaded.


$(document).ready(function() {
$('#example').flash(
{
src: 'test.swf',
height: 1,
width: 1,
flashvars: {onLoad: 'flashLoaded'}
},
{ version: 8}
);
});

This creates the object or embed as necessary, and loads the movie “test.swf”, with a height and width of 1 pixel and the flashvars parameters we saw in the previous article. In this case, the onLoad parameter has a value of flashLoaded, the name of the function we want to call when the flash has loaded and is ready to execute. There is also a parameter saying the minimum version of the Flash player we need, let’s use version 8 here.

Now when the page is loaded, the <div> block will be replaced with the flash movie, and this in turn will call our callback function flashLoaded.

Update: Using Mootools

Mootools is another excellent JavaScript framework library, and it has Flash support built into it’s core using the Swiff class.

For Mootools, firstly we need to make sure it’s loaded.

<!-- load the mootools library -->
<script type="text/javascript" src="mootools.js"></script>

Now we’ll wrap our Swiff object creation in Mootools domready event. This is the equivilant to what we did earlier in jQuery with the ready event.

window.addEvent('domready', function() {
var flash = new Swiff('test.swf', {
container: $('example'),
width: 1,
height: 1,
callBacks: {
onLoad: flashLoaded
}
});
});

Here we’re creating a new Swiff object, and telling it to place the flash object / embed tag it creates inside the div with the id of example like we did with the jQuery example. We specify the height and width both of 1 pixel and setup the callback.

As you can see, Mootools specifically calls this a callback unlike jQuery’s flashvars. They mean the same thing here, so we say the onLoad callback function in the Flash movie’s ActionScript will call the local JavaScript function flashLoaded.

Knowing When It’s Safe To Talk To Flash From JavaScript

I’ve been doing some work lately where JavaScript in an XHTML page needs to talk to some ActionScript 3.0 in a Flash movie.

The most common problem here is knowing when you can start talking to the Flash movie. The browser may have loaded all the scripts and started to execute them, but the flash movie may not have loaded or initialised at that point. If you try to talk to the movie at this point, you’ll get errors.

There are a couple of ways around this. You could code the flash movie into the page using <object> and <embed> html tags, then make sure your JavaScript calls the movie after the onload event has been called. E.g.

function flashLoaded() {
alert("Flash loaded");
}
window.onload = function() {
// flash should have loaded by now.
flashLoaded();
}

Now that isn’t ideal, the flash may have loaded, but the movie may not have initialised so you could still have problems.

The safest way is to include a callback function in your ActionScript that runs once the movie has finished initialising. This will call some JavaScript on your page letting you know the movie has loaded and can be interacted with. We can use the ExternalInterface class in the ActionsScript to achieve this.

Let’s assume our ActionScript class is called test, and we have a function in our JavaScript called flashLoaded. The following code is a quick way to let the JavaScript know the movie has loaded.

public function test():void
{
ExternalInterface.call("flashLoaded");
}

This is great, but it does mean we’ve had to hardcode the name of the calling function. What if we had two Flash movies in the page and they both called this function. This could cause problems. We need a way to pass in a function name dynamically.

Flash has something that used to be called FlashVars that can help us here. It’s basically a list of parameters and values that are passed and appended as a query string to the end of the movie files name. These are then available to ActionScript. In our object we alter the movie paramter accordingly.

<-- in the flash object tag -->
<param name="movie" value="test.swf?onLoad=flashLoaded" />

If you use the embed tag, make sure you alter the movie parameter there as well.

To see the passed parameters in ActionScript was need to use root.loaderInfo.parameters. Our initialiser function should be altered to use the following code, in this case we want to use the onLoad parameter.

public function test():void
{
ExternalInterface.call(root.loaderInfo.parameters.onLoad);
}

Great, we can now vary our the name of our callback. However problems could still occur. The movie may be loaded but the stage may not be ready. We need to add a little bit more wrapping code to handle this. The following code should do the trick.


package {
import flash.display.Sprite;
import flash.events.*;
import flash.external.ExternalInterface;
public class test extends Sprite
{
public function test():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
ExternalInterface.call(root.loaderInfo.parameters.onLoad);
}
}
}

As you can see we’ve moved the callback into the init function, and this is only called when the stage is ready.

You should now be safely able to script your flash movie from JavaScript.

See Knowing When It’s Safe To Talk To Flash From JavaScript – Part 2 for examples on how to integrate this with a modern JavaScript library like jQuery.

getURL and Flash 9

We upgraded our Flash players to the current version today and found a few slides on our sites didn’t work as expected.

When clicked, they were supposed to take you to other pages, but with the upgrade, old code was found to be broken.

Looking around, it appears the security model changed and we weren’t aware of this. I think it’s time to subscribe to the Flash RSS feed to keep on top of bug fixes and upgrades.

Anyway, it turned out our code could be fixed by just setting AllowScriptAccess to be “always” or “sameDomain”, depending on the application. In the <object> tag this was achieved by adding…

<param name="allowScriptAccess" value="always">

… and in the embed tag…

allowScriptAccess="always"

Those of you using SWFObject, the following JavaScript code does the trick…

so.addParam("allScriptAccess", "always");

This means when we call getURL() from ActionScript it is able to navigate to other pages on a foreign or the same domain.

There is a bit more information on this on the Adobe Flash knowledge base, Links from SWF files in HTML page no longer function (Flash Player 9).

Using ExtraFields In Movable Type

I’ve been doing some work with Movable Type using the ExtraFields plugin recently.

One problem I had was offering an alternative if an extra field hadn’t been set. It turns out that it’s possible to nest an <MTElse> in the <MTIfExtraField> tag.

Here’s an example. I have an extrafield called externalurl on an entry, if it exists I want to use that for the link, if not I want to use the entry’s permalink.

<MTIfExtraField field="externalurl">
<$MTExtraFieldValue field="externalurl"$>
<MTElse>
<$MTEntryPermalink$>
</MTElse>
</MTIfExtraField>

This basically gives us the functionality of a <MTElseExtraField> tag.

Using Twitter From Perl

The world and his dog is currently looking at Twitter and eyeing up the possibilities it offers.

I thought i’d jump on the bandwagon, and have a look at the Twitter API.

I wanted to post to a timeline, so the solution is to use one of the update methods. I chose to the XML one, though there is a JSON one also available.

To post to the timeline, Twitter expects an HTTP POST request with a status parameter containing the message you want to post. It associates this to your account by using HTTP’s basic authorization functionality.

It’s simple to throw together a spot of Perl code to post messages to Twitter knowing this. Have a look at this example…


my $message = "A test post from Perl";
my $req = HTTP::Request->new(POST =>'http://twitter.com/statuses/update.xml');
$req->content_type('application/x-www-form-urlencoded');
$req->content('status=' . $message);
$req->authorization_basic($username, $password);
my $resp = $ua->request($req);
my $content = $resp->content;
print $content;

You need to set $username and $password to your username and password, and $message to whatever message you want to appear on your timeline (in this case, “A test post from Perl”).

Posting To Movable Type 3.3 Using Nokia Lifeblog

We’ve been installing Movable Type as a blogging solution at work for various sites recently.

We’d been using Typepad, the hosted version of Movable Type for a while, but wanted some extra flexibility and functionality.

One problem we came across was the lack of support for Nokia Lifeblog on Movable Type, compared to Typepad.

Thankfully Martin Higham has worked on this in the past, and even used my old notes on the Nokia Lifeblog Posting Protocol.

However, the current version of Movable Type is 3.3, and Martin’s work only extends to 3.2.

I took Martin’s code, which modifies AtomServer.pm and modified it so it works on Movable Type 3.3. You can download my Nokia Lifeblog compatible AtomServer.pm for Movable Type 3.3 here.

Make sure you follow Martin’s instructions for Movable Type 3.2 as the method is exactly the same and the same caveats apply (namely, this could well break other Atom tools that use your blog as it has to disable some WSSE authentication).

I hope you find it useful!

UPDATE: 22nd November 2006

With version 2.0 of Lifeblog and web upload functionality from Nokia phones, the authentication method has changed slightly. A new version of AtomServer.pm that works with Lifeblog 2.0 is now available.

UPDATE: 26th June 2007

Neils Berkers has been in touch to say he’s adapted the script so it now works with Movable Type 3.35, Lifeblogging Fixed.

Introducing Acme::Terror::UK

There is a lot of fuss in the press at present about the current terrorist threat to the UK.

The government has put the current threat level on a few of it’s websites. These are…

The US government has had provided it’s threat levels to the public for a while, and there are various ways to access this, incuding a Perl module called Acme::Terror.

Now the UK has this information online, I decided to provide the UK with it’s own version of this Perl module, which I’ve rather originally decided to call Acme::Terror::UK.

It’s really simple to use the module. For example, this small bit of code will fetch and display the current UK threat level.

use Acme::Terror::UK;
my $t = Acme::Terror::UK->new(); # create new Acme::Terror::UK object
my $level = $t->fetch; # fetch the current terror level
print "Current terror alert level is: $leveln";

The code goes off to the home office site behind the scenes and screen scrapes the page to get the current UK threat level as the UK government doesn’t currently provide and automated feed of this information. This makes the module vulnerable to any design changes on the page, but it works for now and that’s the main thing.

There are 5 levels, these are…

  • CRITICAL – an attack is expected imminently
  • SEVERE – an attack is likely
  • SUBSTANTIAL – an attack is a strong possibility
  • MODERATE – an attack is possible but not likely
  • LOW – an attack is unlikely

At the time of writing, Acme::Terror::UK informs me the current threat level is SEVERE.

Retargetting Selected Links With JavaScript

At work I have a new site that makes use of iframes to embed external content onto a page. The content is a blog, written by non technical members of staff who needed to be able to include links to external websites. They are happy with using <a href=" tags, but I didn’t want to worry them with target parameters in the HTML. We have to target _blank as we want the readers to keep the old site open and not open the content in the site framework.

The solution to this is to use a bit of JavaScript to manipulate the DOM and insert blank targeting to all blog entries.

As we control the HTML template of the blog, we made sure all the blog entries were wrapped by an enclosing div tag with a class called blogentry.

Here’s some example HTML. We have one link in the blogentry div we need to re target. The other link is not in a blogentry so has to be ignored.

<div class="blogentry">
<a href="http://www.robertprice.co.uk/">This link needs to open in a new window</a>.
</div>
<div>
<a href="http://www.robertprice.co.uk/">This link won't open in a new window</a>.
</div>

The JavaScript first has to get all div tags on the page. It does this by calling getElementsByTagName on the document. Once we have all the div tags, we have to iterate over them to make sure we only get the ones with the classname of blog entry.

var entries = document.getElementsByTagName('div');
for (var i in entries) {
if (entries[i].className == "blogentry") {
// insert target code here.
}
}

Now have our blogentry’s we need to find all the links inside and make sure they all target blank. We do this by calling getElementsByTagName on each node, then setting the target attribute to blank.

var targets = entries[i].getElementsByTagName('a');
for (var j in targets) {
targets[j].target="blank";
}

It’s as simple as that. The full code follows…

<script language="JavaScript" type="text/javascript">
<!--
var entries = document.getElementsByTagName('div');
for (var i in entries) {
if (entries[i].className == "blogentry") {
var targets = entries[i].getElementsByTagName('a');
for (var j in targets) {
targets[j].target="blank";
}
}
}
// -->
</script>

Using Series 60 Python To Talk To A Webserver

I’ve been continuing my journey into Python by modifying my earlier location script to now post details to my website when run.

I’m using the standard urllib now and moving to slightly more advanced Python language features such as dictionaries (basically the equivalent of a Perl hash).

The code gets the location, calls a CGI script on my website and prints the returned message from that script to the console.

Here’s the code…

# we need access to the location and urllib modules so have to
#import them.
import location
import urllib
# get the mmc, mnc, lac and cellid by calling the gsm_location
# method from the location module.
(mmc, mnc, lac, cellid) = location.gsm_location()
# add the location to a python dictionary called params.
params = urllib.urlencode({'mmc': mmc, 'mnc': mnc, 'lac': lac, 'cellid': cellid})
# open a filehandle to a cgi tracking script that takes
# the contents of dictionary params as parameters.
f = urllib.urlopen("http://www.robertprice.co.uk/cgi-bin/test/cellid.pl?%s" % params)
# get the results, hopefully a message saying OK.
print f.read()

All the CGI script on my website does is to record the parameters passed to it and return a simple text string saying it ran OK.

As you can see it’s really simple to Series 60 Python to communicate over the phone’s network connection. I have to say, this language is turning out to be better than I had expected, and far easier than J2ME.