Home | Wiki | OI 1.x Docs | OI 2.x Docs |
OpenInteract Actions - Tell OpenInteract how to respond to requests
This document will describe how Actions work in OpenInteract -- how you can configure them, look them up and retrieve content using them.
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.)
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.
Once we match up the action to its implementation information, we need to call it. First, what can be in its implementation information?
The class used to return the content; used with 'method'.
The method run from 'class' to return the content. If not given, use the method 'handler'.
Only utilized when the action is a component. Checks whether security should be checked when running the action -- 'yes' means security should be checked, 'no' means it shouldn't. If not given, use 'yes'.
The conductor to use. Currently there is only one conductor ('main'), but in the future you might have different conductors -- one for SOAP, one for WAP, etc. If not given, use the default conductor, given in the '_default_action_info_' action in your 'server.perl' configuration file.
Actions can redirect to an action which actually fulfills it. For instance, say we wanted the news package to respond not only to 'news' but also to 'nouvelles' for your French-speaking audience. Instead of repeating the same information in separate places (and risk changing only one in the future), you would do something like:
'nouvelles' => { redir => 'news' },
Redirects can nest as many levels deep as you need.
For template-only components, the name of the template to run. (Also see 'package' below.)
For template-only components, the package the template (specified in 'template') is in.
Use in boxes only -- the title of the box.
Use in boxes only -- the weight of the box.
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.
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' ) %]
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
This gives us an array with:
( 'News', 'show' )
The GET parameters are retrieved later.
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
.
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.
There are two distinct cases for this:
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.
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).
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.
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.
Two ways:
[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.
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.
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
OpenInteract
(Apache content handler)
OpenInteract::Request
(action lookup methods)
Chris Winters <chris@cwinters.com>
$Id: actions.html,v 1.2 2002/08/26 05:10:09 lachoy Exp $