NAME

OpenInteract Actions - Tell OpenInteract how to respond to requests


DESCRIPTION

This document will describe how Actions work in OpenInteract -- how you can configure them, look them up and retrieve content using them.


ACTION TABLE

The Action Table is the catalog that matches up action names to how the action will be accomplished. Each package in OpenInteract must specify the actions it implements in the file conf/action.perl.

The configuration file is a Perl hashref where the keys are lower-cased names which correspond to the first URL chunk. The value is a hashref with information about how that action should be fulfilled. (Don't worry, it will all make sense shortly.)

The Action/URL Connection

First, note that while the action keys must always be lower-case, the actual URLs that map to them can be of mixed case. This means that you can't have differently-cased URLs of the same word perform different actions -- for instance '/NEWS/' and '/news/' will refer to the same action.

The keys in the configuration file correspond to top-level URL commands. For instance, in the following URL:

 /News/show/?news_id=484

The top-level command is 'News' and the task is 'show'. Once we parse the URL we try to match the top-level command to an action from the action table.

Fulfilling the Action

Once we match up the action to its implementation information, we need to call it. First, what can be in its implementation information?

Top-level Directives

The only exception to the above parsing scheme is when the first item in the URL is a directive. Directives tell OpenInteract something about the request as a whole, generally how it will be displayed.

For instance, when you move your mouse over the 'Logout' in the default user_info_box (found in the base_component package) you'll see something like:

  http://www.mysite.com/NoTmpl/Logout/?return=/docs/oi_is_great.html

The 'NoTmpl' in this URL is a directive that tells OpenInteract not to use a main template at all when displaying content.

The directives are all listed in your 'server.perl' file under the 'page_directives' key. The only other directive currently implemented is 'Popup', which tells OpenInteract to use the 'simple' template (by default this is 'base_simple'). This template typically has very little in the way of graphics and layout.

So when OpenInteract encounters one of these directives, it removes it from the URL and saves it for later so the Conductor knows which main template to put the content into.


SAMPLE CONFIGURATION

First, let's take an easy one -- the action.perl file from the base package:

 $action = {
            'logout'    => {
                'class'     => 'OpenInteract::Handler::Logout',
                'security'  => 'no',
            },
            'redirect' => { 
                'class'     => 'OpenInteract::Handler::Redirect',
                'security'  => 'no',
            },
            'package' => {
                'class'     => 'OpenInteract::Handler::Package',
                'security'  => 'yes',
            },
 };

This defines four actions: 'logout', 'redirect', 'boxes', 'package'. You can visualize the action table as:

 URL         Action
 ======================================================
 /logout     OpenInteract::Handler::Logout->handler()
 /redirect   OpenInteract::Handler::Redirect->handler()
 /boxes      OpenInteract::Handler::Boxes->handler()
 /package    OpenInteract::Handler::Package->handler()

Next, something a little more interesting. This is taken from the news package, distributed with OpenInteract:

 $action = {
           'news'      => {
                'class'     => 'OpenInteract::Handler::News',
                'security'  => 'yes',
            },
            'latest_news' => {
                'class'     => 'OpenInteract::Handler::News',
                'method'    => 'latest',
                'security'  => 'no',
            },
            'news_tools_box' => {
                'template' => 'news_tools_box',
                'package'  => 'news',
                'title'    => 'News Tools',
                'weight'   => 4,
                'security' => 'no',
            },
            'latestnews'   => { redir => 'latest_news' },
            'newstoolsbox' => { redir => 'news_tools_box' },
 };

This defines a normal action ('news') an action that is designed to be addressed as a component ('latestnews'), a template-only action ('news_tools_box') and two different spellings which use the redirect action. This action table will look like:

 URL           Action
 ====================================================
 /news         OpenInteract::Handler::News->handler()
 /latest_news  OpenInteract::Handler::News->latest()
 /latestnews   OpenInteract::Handler::News->latest()

Additionally, you can call the toolbox two ways:

 [% OI.box_add( 'news_tools_box' ) %]
 [% OI.comp( 'news_tools_box' ) %]

The first is recommended because you can override the default box information with your own:

 [% OI.box_add( 'news_tools_box', weight = 1, 
                                  title = 'Okeley-Dokeley-News Box' ) %]


WALKING THROUGH A REQUEST

Now we will walk through a request from the action table's perspective. This example will assume the configuration given above for the news package has been read in properly.

URL given: /News/show/?news_id=484

  1. Parse the URL

    This gives us an array with:

     ( 'News', 'show' )

    The GET parameters are retrieved later.

  2. Map the first part of the URL to an action

    The action 'news' does exist (note the case-change -- a URL action is lowercased before trying to map it in the action table) and uses the handler OpenInteract::Handler::News.

  3. Call the appropriate action

    With the above, we call:

     OpenInteract::Handler::News->handler();

    (with the note that 'handler' is defined as the default method in the 'action_info.default' key of our main website configuration in conf/server.ini)

    This returns the content for the page which is then plugged into the main template.


FAQ

Which happens if I can't match an action to the URL?

There are two distinct cases for this:

  1. There is no path

    This happens when someone goes to your home page:

     http://www.openinteract.org/

    The file 'home.html' (or 'index.html', or 'default.htm', depending on how your webserver handles directory requests) is typically ``understood'' here by web servers. But since it's not specified OpenInteract has no way to know.

    To deal with this, define an action whose key is an empty string. This is defined for you in your conf/server.ini file in your main website configuration directory. The key 'action_info.none' holds action specifications to take in this case.

  2. The path cannot be found

    What happens if someone tries to find the document:

     http://www.mysite.com/zaphrod/live/now.html

    And you don't have an action mapped to 'zaphrod'? OpenInteract will use the action defined in the configuration key 'action_info.not_found'. Typically this maps to the 'base_page' package which treats the path as a normal file request and serves up a file from either the filesystem or the directory.

    As an example, for the above request the base page handler would try to find either a file or object which has the location '/zaphrod/live/now.html'. It would also try '/zaphrod/live/now' (without the file extension).

Why doesn't my website's information match the examples?

Instead of seeing OpenInteract::Handler::News in your website's configuration files , you'll see something similar except with the name of your website instead of 'OpenInteract'. Each website needs a separate namespace so that each website can customize its handlers and keep its data reasonably separate.

Do I have to define all the information for every action?

No! The server.perl configuration file also defines the '_default_action_info_' key under the 'action' key. Specify information that you would like to appear by default in the action configuration and at server startup it will be copied to the configuration only if a value previously was not defined.

For instance, in the configuration files above we never (well, except once) specified the method to call. That's because we defined it in '_default_action_info' to be 'handler'. We also specify the conductor to use by default and the template implementation class to use.

How can I ensure the configuration file's syntax is ok?

Two ways:

  1. Run a normal Perl syntax check:
     [cwinters@genesee news]$ perl -c conf/action.perl
     conf/action.perl syntax OK

    This is the easiest to do, and you can probably script your editor to do this whenever you hit the F9 key or something.

  2. Run the 'check_package' command of oi_manage:
     [cwinters@genesee news]$ oi_manage check_package
     Running check_package...
     =========================
       Status of the packages you requested to be checked:
       news  OK:
       ++ File (Changes) to show package Changelog: ok
       ++ File (conf/spops.perl) ok
       ++ File (conf/action.perl) ok
       ++ File (OpenInteract/Handler/News.pm) ok
       ++ File (OpenInteract/SQLInstall/News.pm) ok
       ++ package.conf: ok
       ++ MANIFEST files all exist in package: ok
       ++ All files in package also in MANIFEST: ok
     =========================
     Finished with check_package!

    This does the same check behind the scenes but does lots of other useful checks for you at the same time.

    Here's what happens if the check fails:

     [cwinters@genesee news]$ oi_manage check_package
     [oi_manage]: Using (/opt/OpenInteract) for 'base_dir'.
     Running check_package...
     =========================
       Status of the packages you requested to be checked:
       news  FAILED!:
        ++ File (Changes) to show package Changelog: ok
        -- File (conf/action.perl) cannot be read in.
           Error reading in perl code: syntax error at
           (eval 8) line 20, near "} oops"
        ++ File (conf/spops.perl) ok
        ++ File (OpenInteract/Handler/News.pm) ok
        ++ File (OpenInteract/SQLInstall/News.pm) ok
        ++ package.conf: ok
        ++ MANIFEST files all exist in package: ok
        ++ All files in package also in MANIFEST: ok
     =========================
     Finished with check_package!

    Note that under some circumstances, a failed syntax check will issue a segfault instead of listing what actually went wrong. If this happens you'll need to check each .perl file by hand.

How do I see what actions are currently used?

The multi-purpose oi_manage script will list packages from a particular website for you. Just run:

 oi_mange --website_dir=/home/httpd/myweb.com list_actions


SEE ALSO

OpenInteract (Apache content handler)

OpenInteract::Request (action lookup methods)


AUTHORS

Chris Winters <chris@cwinters.com>


REVISION

 $Id: actions.html,v 1.2 2002/08/26 05:10:09 lachoy Exp $