RocketSled Tutorial 1: Basics

Author: David Grinton thegrinch@workingsoftware.com.au

Table of Contents

Introduction

Welcome to RocketSled Tutorial 1.

In this tutorial we will create a basic implementation of a RocketSled package using the framework, without connecting to a database. In this way you will get a better idea of how the framework actually works, by implementing its classes and methods in the simplest fashion. Our package will be based on the schema in the sys package, and all the files in the package ('my') will be based upon the file names and classes in the 'sys' package.

Checking out, cleaning up

On your own server or Working Software's development webserver, create your own directory under WEBROOT (/usr/local/www/apache22/data on Working Software's server), and checkout RocketSled using CVS (Concurrent Versioning System).

$ cd WEBROOT
$ mkdir yourdir
$ cd yourdir
$ cvs -d :ext:idcvs@socata.iaindooley.com:/home/iain/cvsroot co -r v0-4 RocketSled

This will create a directory under the one you just made called 'RocketSled'. Move the contents of RocketSled directly into your directory, then delete RocketSled. Do this as follows in your directory:

$ mv RocketSled/* .
$ rmdir RocketSled

You will not need any package except 'sys' 'pilot' and 'nozzle' in the packages directory, so delete the rest (however first we will borrow some css from the sample package).

$ mkdir packages/my
$ cp packages/sample/views/sample.css packages/my/style.css
$ cd packages
$ rm -r antenna/ blueprint/ comms/ decal/ logbook/ murphy/ remote/ sample/

Creating our own package

Create the following files in 'my' using the touch command:

$ cd my
$ touch my_application.class.php
$ touch my_display.class.php
$ touch my_user.class.php
$ touch home.class.php
$ touch site_template.rsml.php
$ touch home.rsml.php

The MyUser class

Our first class MyUser implements the SystemUser interface in the 'sys' package (if you are unfamiliar with the PHP interface system, read this). Note that the naming convention used in RocketSled is: this_class.class.php -> ThisClass

To implement MyUser, paste the following into WEBROOT/yourdir/packages/my/my_user.class.php:

<?php
   class MyUser implements SystemUser
   {
      public function authorise($handler)
      {
         return TRUE;
      }
  
      public function toString()
      {
         return strval($this->id());
      }
  
      public function getHandlerTree()
      {
         $ret = new HandlerTree();
         $ret->addHandler(new Home());
         return $ret;
      }
  
      public function id()
      {
         return md5(serialize($this));
      }
   }
?>

This implementation of SystemUser contains four methods:

The first method, authorise(), returns true or false depending on whether the user has permission to use a particular Handler. (A Handler is the class in the RocketSled system which constitutes a webpage). Because our application does not yet require a login we have overridden the authorise() method to always return true.

The second method, toString(), returns a string representation of the user. Because our initial application does not use a database, the class may return any string, such as 'guest', or the user id generated by the class.

The third method, getHandlerTree(), returns a list of all the Handlers in a web application that a user has permission to access. It is up to you to decide which Handlers the user will have access to. In some applications this may be done using a database, or from a config file, but in our simple application we can just hard code in calls to the addHandler() method.

The fourth method, id(), returns the id of the user. This id should be the same each time the id() method is called for any given User object. In the implementation above, the serialize() method converts its input into a storable string, and md5() converts this string into a unique format. Once we have a database to store users in, this would probably be the primary key column of the users table.

The MyApplication class

Our second class is an extension of Application which we will call MyApplication. Paste the following into WEBROOT/packages/my/my_application.class.php:

<?php
   class MyApplication extends Application
   {
      function MyApplication()
      {
         $this->Application();
      }
  
      protected function defaultUser()
      {
         return new MyUser();
      }
   }
?>

This class uses a constructor which calls the constructor of its parent class, Application. The defaultUser method generally specifies which user in the database will be the default user of the application. However, because this demonstration does not use a database, this particular implementation of defaultUser overrides its parent method in Application in order to return a MyUser object (which we defined previously).

The MyDisplay class

Our third class is an extension of Display which we will call MyDisplay.

Display is the class responsible for rendering the various displayable elements of your application into a whole webpage. Display is a global or singleton object in RocketSled; i.e. there is only ever one instance of it. (See here for more details.) The tasks performed by this Display object can be understood in terms of a distinction between a site template and page content. By default, Display expects to find this site template in a file called site_template.rsml.php, however a site template file with another name can also be passed to Display. In RocketSled, both site templates and page content are called views (not to be confused with database views), where a view is a complete XML file written either in one of RocketSled's two unique XML languages: RocketSled Markup Language (RSML, *.rsml.php) which is for general HTML templating, or Form Markup Language (FormML, *.frm.php), for HTML Form templating.

This distinction between site template and page content is implemented in practice through RocketSled's Display and Handler classes. The global Display object, while initialised via a call from Handler, stores all global site templating information irrelevant to how the application as a whole is rendered into HTML. Handler can invoke Display's public methods to change this information, or add extra views for the particular tasks of the Handler.

This Display method thus defers from standard templating engines insofar as it operates around the idea of integrating data fragments into a central site template, rather than bringing together various constitutive templates.

The code below should be pasted into WEBROOT/yourdir/packages/my/my_display.class.php. MyDisplay uses a constructor which calls its parent constructor, and a method init() to add some initial properties to the Display object:

<?php
   class MyDisplay extends Display
   {
      public function __construct()
      {
         parent::Display();
      }
  
      public function init()
      {
         $this->addView('site_template','my.SiteTemplate');
         $this->setTitle('My Home');
         $this->addStylesheet('my.Style');
      }
   }
?>

In the class definition above, the first line in method init() adds a view called 'my.SiteTemplate', which resides in the file 'my/site_template.rsml.php', to the display; the second line sets the title of the display to 'My Home'; and the third line appends the stylesheet 'my.Style' (which literally translates through our naming convention to 'my/style.css').

Paste the following into WEBROOT/yourdir/packages/my/site_template.rsml.php:

<rsml>
   <head>
      <title />
      <css />
   </head>
   <body>
      <view name="page_content" />
   </body>
</rsml>

In <head> the <title> and <css> nodes will print out values as set in the Handler code.

In <body> the <view> tag will display whatever RSML fragment we set as the 'page_content' view on the Display object.

The Home class

The final class in this tutorial is an extension of the Handler which we will call 'Home'. In RocketSled, 'Home' is generally the first page a user will see in their application. Paste in the following into WEBROOT/yourdir/packages/my/home.class.php:

<?php
   class Home extends Handler
   {
      public function Home()
      {
         $name = 'Home';
         $description = 'Welcome to my application!';
         $this->Handler($name, $description);
      }
  
      public function display()
      {
         $disp = Display::current();
         $disp->addView('page_content','my.Home');
         $disp->displaySiteTemplate();
      }
  
      public function performHandlerTasks()
      {
      }
   }
?>

This class implements a constructor Home() which passes two variables to its parent constructor defining its name and description.

Secondly, it implements a method called display(). This method firstly creates a reference to RocketSled's global Display object, next note the call to addView() which sets the 'page_content' view which is referenced in the site template RSML we just created. The call to displaySiteTemplate() actually outputs the page.

Thirdly, it implements a method called performHandlerTasks(), this method will be called before display(), for now we will leave this empty.

This class also requires the following to be pasted into WEBROOT/yourdir/packages/my/home.rsml.php:

<fragment>
   <h2>Home</h2>
   <p>welcome home</p>
</fragment>

Final configuration

Before the application will work, you need to change some directory permissions in RocketSled:

$ cd WEBROOT/yourdir/managed_code
$ cvs update -d
$ cd ..
$ sudo chown -R [webuser]:[webuser's group] managed_code/

Finally, open WEBROOT/yourdir/packages/sys/sys.config.php and modify the defines as follows:

define('ADMIN_EMAIL','test@example.org');
define('SESSION','my');
define('DEFAULT_HANDLER','Home');
define('APPLICATION','MyApplication');

You should now be able to point a web browser at WEBROOT/yourdir/ - this will call index.php?h=Home by default, utilising the Home Handler you implemented.


Generated on Wed Oct 22 18:48:19 2008 for RocketSled by  doxygen 1.5.7