CGI in Lingo

From Director Online Wiki
Jump to: navigation, search

With Lingo, you can call server-side scripting languages using CGI. Your server-side scripts could be written in PHP, ASP, Perl, Python, Ruby, or anything else you like.

It works just like forms in HTML. In fact, it would be prudent to test your server-side code using a simple HTML form first. Then, when you have made sure it does what you expect it to do for every possible input, convert your HTML form into Lingo.

Converting a simple HTML form to Lingo

Let's take a simple example: user authentication. You will send a username and a password to a script on your server. The script will return a response to say whether the user is valid or not. For now, we won't concern ourselves with the return values, only sending the inputs with an HTTP POST operation.

We would start with a form, such as this one:

<form action="auth.php" method="post">

 <input type="text" name="username">
<input type="text" name="password">
<input type="submit">

</form>

It doesn't matter what type the input boxes are. Since we are just using this form for testing, it makes sense to use standard text fields. We could use a "password" field for the password, but while that would be a good idea in production, it will needlessly increase the difficulty of testing.

Now build a script to authenticate a user. Take a look at the authentication script samples for examples that will work with this form.

We can create a Lingo equivalent of this HTML form with a property list, like so:

 tFormValues = [:]
 tFormValues[ "username" ] = "username"
 tFormValues[ "password" ] = "password"

To send this form, we need to use either postNetText (for POST method) or getNetText (for GET method). For calling a script like this, we will generally want to use POST rather than GET because this ensures that the script is actually called. GET does not guarantee that the script will be called every time.

getNetText and postNetText both return a unqiue network operation identifier, which can be used to track the progress of operation. This is needed because network operations do not return an instantaneous result, so we need to wait for a result to come back. After setting up our form values, we call the script like so:

 tURL = the moviePath & "auth.php"
 pNetID = postNetText( tURL, tFormValues )

Getting a result

Notice that we called the network ID pNetID rather than tNetID. This is because while all the other variables are temporary, we'll need to remember the network ID. In fact, to create a simple working example, we can make it a property of a frame script, which will check for a result every frame. Here is the complete script:

 property pNetID


 -- Make sure network ID is initialised to VOID
 on beginSprite me
   pNetID = VOID
 end


 -- Handler for submitting the form
 on submitForm me, aUsername, aPassword
   tFormValues = [:]
   tFormValues[ "username" ] = aUsername
   tFormValues[ "password" ] = aPassword
   tURL = the moviePath & "auth.php"
   pNetID = postNetText( tURL, tFormValues )
 end


 -- Submit a test when the user clicks
 on mouseUp me
    me.submitForm( "joebloggs", "joespassword" )
 end


 -- Wait until network operation has finished
 on exitFrame me
   -- No operation started yet? Wait.
   if( voidP( pNetID ) ) then go to the frame
   -- Operation in progress? Wait.
   if( not netDone( pNetID ) ) then go to the frame
   -- Operation has completed...
   -- Did the operation fail?
   tNetError = netError( pNetID )
   if( tNetError <> "OK" ) then
     put "network error: " & tNetError
     halt
   end if
   -- Operation was successful, so get the result
   tResult = netTextResult( pNetID )
   -- Display the result
   put tResult
   halt
 end

This is a very simple example, but demonstrates all the features that are necessary for handling a network operation. These are:

  • Must wait until the operation has finished before doing anything
  • Must check to see if the operation was successful before looking at the result - remember to include decent error-handling.
  • If everything else is OK, the result must be interpreted somehow.

Getting values from a script

There many different approaches to returning values to Lingo, each with their own merits. Some of the common approaches are:

  • Return only a few possible values such as "OK" and "Fail"
  • Return a simple comma-delimited (or other delimited) list of items, which can be parsed easily using "item" or "line"
  • Return CGI standard key=value pairs, separated by & characters and using urlencoding to escape each string. Lingo cannot parse this automatically (Flash would) but it is relatively easy to implement.
  • Return Lingo code that can be evaluted using "value" or "do". This method is potentially unsafe, and not recommended, although it is quite common practise.
  • Return XML, to be parsed using an XML parser. This method is highly recommended for Director MX2004 - older versions may suffer from bugs in the XML parser Xtra, which makes this technique less attractive. There are pure lingo xml parsers as an alternative for those using older versions.

<<<< MORE TO BE ADDED >>>>