NAME

Apache::PageKit - Application framework using mod_perl and HTML::Template

SYNOPSIS

Perl Module that inherits from Apache::PageKit:

  package MyPageKit;

  use Apache::PageKit;

  use vars qw(@ISA);
  @ISA = qw(Apache::PageKit);

  use Apache::Constants qw(OK REDIRECT DECLINED);

  sub handler {
    $dbh = DBI->connect("DBI:mysql:db","user","passwd");
    my $pk = Apache::MyPageKit->new(
				    page_dispatch_prefix => 'MyPageKit::PageCode',
				    module_dispatch_prefix => 'MyPageKit::ModuleCode',
                                    dbh => $dbh,
				    session_handler_class => 'Apache::Session::MySQL',
				    session_args => {
						     Handle => $dbh,
						     LockHandle => $dbh,
                                                    },
                                   );

    my $status_code = $pk->prepare_page;
    return $status_code unless $status_code eq OK;

    $pk->prepare_view;

    $pk->print_view;

    return $status_code;
  }

  sub auth_credential {
    my ($pk, @credentials) = @_;

    # create a session key from credentials
    # your code here.........

    return $ses_key
  }

  sub auth_session_key {
    my ($pk, $ses_key) = @_;

    # check whether $ses_key is valid, if so return user id in $user_id
    # your code here.........

    return $ok ? $user_id : undef;
  }

In httpd.conf

PerlSetVar PKIT_ERROR_HANDLER email
PerlSetVar PKIT_PAGE_INFO_FILE /www/pagekit/page.txt
PerlSetVar PKIT_PRODUCTION on
PerlSetVar PKIT_TEMPLATE_ROOT /www/pagekit/template
PerlSetVar PKIT_COOKIE_DOMAIN .pagekit.org
PerlRequire /www/pagekit/startup.pl
SetHandler perl-script
PerlHandler +MyPageKit
PerlSetupEnv Off

DESCRIPTION

PageKit is a set of Perl modules that provides an application framework based on mod_perl and HTML::Template. It is based on the Model/View/Controller approach to design, with complete seperation of Perl from HTML. It includes session management, authentication, form validation, sticky html forms, multiple views/co-branding, modules and includes, and a simple content management system.

You have to write a module that inherits from Apache::PageKit and provides a handler for the PerlHandler request phase. If you wish to support authentication, it must include the two methods auth_credential and auth_session_key.

For more information, visit http://www.pagekit.org or http://sourceforge.net/projects/pagekit/

OBJECTS

Each $pk object contains the following objects:

$pk->{apr}

An Apache::Request object

$pk->{info}

An Apache::PageKit::Info object, which loads and accesses data about the set of pages making up the the application.

$pk->{session}

A reference to a hash tied to Apache::Session.

$pk->{validator}

An Apache::PageKit::FormValidator object, a wrapper to HTML::FormValidator, used for validating HTML forms.

$pk->{view}

An Apache::PageKit::View object, which interfaces with the HTML::Template templates.

Features

Model/View/Controller approach to design

The Model is the user provided classes, which encapsulate the business logic behind the web site.

The View is a set of HTML::Template templates. Apache::PageKit::View acts as a bridge between the templates and the controller.

The Controller is a subclass of Apache::PageKit, which reads the client request, accesses the back end, and uses Apache::PageKit::View to fill in the data needed by the templates.

Seperation of Perl from HTML

By using HTML::Template, this application enforces an important divide - design and programming. Designers can edit HTML without having to deal with any Perl, while programmers can edit the Perl code with having to deal with any HTML.

Page based attributes

Many of the attributes of each Page are managed from a tab-delimited file. This makes it easy to change Pages across the site. Apache::PageKit::Info provides a wrapper around this text file.

For example, to protect a page, all you have to do is change its require_login attribute to yes, instead of modifying the Perl code or moving the script to a protected directory.

To change a page to a popup, all you have to do is set is_popup to yes, and all the links to that page across the site will magically become javascript popup links.

Automatic Dispatching of URIs

Apache::PageKit translates $r->uri into a class and method in the user provided classes. In the example in the synopsis, the URI /account/update will map to MyPageKit::PageCode::account->page_update.

Easy error handling.

Both warnings and fatal errors can be displayed on the screen for easy debugging in a development environment, or e-mailed to the site adminstrator in a production environment, as specified in the Apache ServerAdmin configuration directive.

Session Management

Provides easy access to a hash tied to Apache::Session.

Authentication

Restricts access to pages based on the require_login attribute. If require_login is set to recent, then PageKit requires that session is currently active in the last recent_login_timeout seconds.

Form Validation

Uses HTML::FormValidator to provide easy form validation. Highlights fields in red that user filled incorrectly by using the <PKIT_ERRORFONT NAME="FIELD_NAME"> </PKIT_ERRORFONT> tag.

Sticky HTML Forms

Uses HTML::FillInForm to implement Sticky CGI Forms.

One useful application is after a user submits an HTML form without filling out a required field. PageKit will display the HTML form with all the form elements containing the submitted info.

Multiple Views/Co-branding

Any page can have multiple views, by using a pkit_view request parameter. One example is Printable pages. Another is having the same web site branded differently for different companies.

Modules and Includes

PageKit can easily share Perl code and HTML templates across multiple pages using modules. To only share HTML, includes can be used.

Content Management System

An authorized user can edit the HTML Templates for views, pages, modules and includes online by simply clicking on a "edit this (view|page|module|include)" link.

METHODS

The following methods are available to the user as Apache::PageKit API.

new

Constructor object.

  $pk = Apache::PageKit->new(
			     page_dispatch_prefix => 'MyPageKit::PageCode',
			     module_dispatch_prefix => 'MyPageKit::ModuleCode',
                             dbh => $dbh,
			     session_handler_class => 'Apache::Session::MySQL',
			     session_args => {
					      Handle => $dbh,
					      LockHandle => $dbh,
                                             },
			    );

Each option is accessible from the object's hash. For example $dbh is acessible from $pk->{dbh}.

prepare_page

This executes all of the back-end business logic need for preparing the page, including executing the page and module code.

prepare_view

This fills in the view template with all of the data from the back-end

Called as a last step to output filled in view template.

message

Displays a special message to the user. The message can displayed using the <TMPL_LOOP NAME="PKIT_MESSAGE"> </TMPL_LOOP> code.

To add a message,

$pk->message("Your listing has been deleted.");

To add an error message (highlighted in red), use

$pk->message("You did not fill out the required fields.",
             is_error => 1);
auth_credential

You must define the method yourself in your subclass of Apache::PageKit.

Verify the user-supplied credentials and return a session key. The session key can be any string - often you'll use the user ID and a MD5 hash of a a secret key, user ID, password.

auth_session_key

You must define the method yourself in your subclass of Apache::PageKit.

Verify the session key (previously generated by auth_credential) and return the user ID. This user ID will be fed to $r->connection->user().

MARKUP TAGS

See the HTML::Template manpage for description of the <TMPL_VAR>, <TMPL_LOOP>, <TMPL_IF>, and <TMPL_INCLUDE> tags.

<PKIT_ERRORFONT NAME="FIELD_NAME"> </PKIT_ERRORFONT>

This tag highlights fields in red that Apache::PageKit::FormValidator reported as being filled in incorrectly.

<PKIT_JAVASCRIPT>

This tag includes Javascript code (if necessary) for popup windows.

These tags gets converted to <A HREF="LINK_FOR_PAGE_143"> </A> tags. Given a page ID, it determines what the link should be. If PKIT_PAGE_DOMAIN is turned on, the link may include the domain name for that page. If is_popup is yes, then the link will be a javascript popup. If is_secure is yes, then the link will use the https:// protocal.

<TMPL_VAR NAME="PKIT_ADMIN">

True if user is authenticated and has administration capability.

<TMPL_LOOP NAME="PKIT_EDIT"> </TMPL_LOOP>

Links to Content Management System. This is displayed if authenticated user has administration capability.

Template should contain code that looks like

<TMPL_LOOP NAME="PKIT_EDIT">
  <PKIT_LINK PAGE="edit_page?template=<TMPL_VAR NAME="TEMPLATE">&pkit_done=<TMPL_VAR NAME="pkit_done">">(edit template <TMPL_VAR NAME="TEMPLATE">)</PKIT_LINK><<br>
</TMPL_LOOP>
<TMPL_VAR NAME="PKIT_LOGINOUT_LINK">

If user is logged in, provides link to log out. If user is not logged in, provides link to log in.

<TMPL_LOOP NAME="PKIT_MESSAGE"> </TMPL_LOOP>

Displays messages passed to $pk->message method.

Template should contain something that looks like

<TMPL_LOOP NAME="PKIT_MESSAGE">
   <TMPL_IF NAME="IS_ERROR"><font color="#ff0000"></TMPL_IF>
   <TMPL_VAR NAME="MESSAGE">
   <TMPL_IF NAME="IS_ERROR"></font></TMPL_IF>
   <p>
</TMPL_LOOP>

This code will show error messages in red.

<TMPL_VAR NAME="PKIT_MODULE:module_id">

Calls the module code and includes the module template for the module module_id.

<TMPL_LOOP NAME="PKIT_NAV"> </TMPL_LOOP>

Displays navigation for pages that have use_nav set to yes.

Template should contain code that looks like

<TMPL_LOOP NAME="PKIT_NAV">
  <TMPL_UNLESS NAME="__LAST__"><PKIT_LINK PAGE="<tmpl_var name="page">"></TMPL_UNLESS><TMPL_VAR NAME="NAME"><TMPL_UNLESS NAME="__LAST__"></PKIT_LINK></TMPL_UNLESS>
  <TMPL_UNLESS NAME="__LAST__"> &gt; </TMPL_UNLESS>
</TMPL_LOOP>
<TMPL_VAR NAME="PKIT_PAGE">

Includes the Page template inside a View template.

<TMPL_VAR NAME="PKIT_SELFURL">

The URL of the current page, including CGI parameters. Appends a '&' or '?' at the end to allow additionial parameters.

<TMPL_VAR NAME="PKIT_USER">

user_id of authenticated user, equal to $r->connection->user, unless overridden.

<TMPL_IF NAME="PKIT_VIEW:view"> </TMPL_IF>

Set to true if pkit_view request parameter equals view.

OPTIONS

Constructor Arguments

These sessions are global in the sense that they apply over all pages and servers.

cookies_not_set_page

This is the page that gets displayed if the user attempts to log in, but their cookies are not enabled. Defaults to login_page.

default_page

Default page user gets when no page is specified. Defaults to index.

fill_in_form

When set to 1, automatically fills in HTML forms with values from the $apr (Apache::Request) object. Defaults to 1.

login_page

Page that gets displayed when user attempts to log in. Defaults to login.

module_dispatch_prefix

This prefixes the class that the contains the module code. Defaults to MyPageKit::ModuleCode.

not_found_page

Error page when page cannot be found. Defaults to default_page.

page_dispatch_prefix

This prefixes the class that the contains the page code. Defaults to MyPageKit::PageCode.

post_max

Maximum size of file uploads. Defaults to 100000000 (100 MB).

recent_login_timeout

Seconds that user's session has to be inactive before a user is asked to verify a password on pages with the require_login attribute set to recent. Defaults to 3600 (1 hour).

session_args

Reference to an hash containing options for the session_handler_class.

session_handler_class

The subclass of Apache::Session that should be used for session handler.

uri_prefix

Prefix of URI that should be trimmed before dispatching to the Page code.

verify_page

Verify password form. Defaults to login_page.

view_cache

If set to normal, enables cache option of HTML::Template for the View template.

If set to shared, enables shared_cache option of HTML::Template.

Apache Configuration

These options are global over all pages, but are local to each server configuration (production, staging, development).

PKIT_COOKIE_DOMAIN .pagekit.org

Domain for that cookies are issued. Note that you must have at least two periods in the cookie domain.

PKIT_ERROR_HANDLER
PKIT_ERROR_HANDLER (email|display|none)

Specifies the type of error handling. email e-mails the server administrator, display displays the error on the web page.

Default is none.

PKIT_FILES_MATCH
PKIT_FILES_MATCH \.html?$

Declines requests that match value.

PKIT_PAGE_DOMAIN
PKIT_PAGE_DOMAIN (on|off)

If on, multiple domains are used for the site. Domains can be used to map to pages. Default is off.

PKIT_PAGE_INFO_FILE
PKIT_PAGE_INFO_FILE /www/site/page.txt

Tab delimited file containing page attributes.

PKIT_PRODUCTION
PKIT_PRODUCTION (on|off)

Set to on, if in production environment. If set to off, checks for new PKIT_PAGE_INFO_FILE for each request.

Default is off.

PKIT_SEARCH_ENGINE_HEADERS
PKIT_SEARCH_ENGINE_HEADERS (on|off)

If set to on, sends Content-Length and Last-Modified headers on pages that don't require a login. Many search engines require that these headers be set in order to index a page.

Default is off.

PKIT_SUBDOMAIN
PKIT_SUBDOMAIN staging

This specifies the subdomain under the domain that this particular server is running. Only needs to be set if PKIT_PAGE_DOMAIN is on.

Used in development environments where the hostname is different from the production environment.

PKIT_TEMPLATE_ROOT
PKIT_TEMPLATE_ROOT /www/site/template

Directory containing HTML::Template files. Defaults to the Apache DocumentRoot configuration directive.

Page Attributes

These options are local to each page on the site, but are global across each server.

page_id (required)

Page ID for this page.

view (required)

View template that is used to display page.

browser_cache

If set to no, sends an Expires = -1 header to disable client-side caching on the browser.

domain

The domain name that is associated with the page.

error_page

If a submitted form includes invalid data, then this is the page that is displayed.

error_page_run_code

If set to yes, then page_code on error_page is run. Defaults to no.

is_popup

If set to yes, links to this page popup a window using javascript.

is_secure

If set to yes, links to this page will begin with https://.

is_topdomain

If set to yes, page will be the default page for the domain specified in the domain field.

Title used in navigation bar - used in <TMPL_LOOP NAME="PKIT_NAV"> </TMPL_LOOP> tag.

new_credential

Should be set to yes for pages that process credentials and update the database, such as pages that process new registration and edit account forms.

If set to yes, then it reissues the cookie that contains the credentials and authenticates the user.

page_id_match

Value should be a regular expression. Servers requests whose URL (after the host name) match the regular expression. For example, ^member\/\d*$ matches http://yourdomain.tld/member/4444.

parent_id

Parent page id - used for navigation bar.

Width of popup window. Used when is_popup is set to yes.

Height of popup window. Used when is_popup is set to yes.

require_login

If set to yes, page requires a login. If set to recent, page requires a login and that the user has been active in the last recent_login_timeout seconds. Default is no.

template_cache

If set to normal, enables cache option of HTML::Template for the Page and Module templates.

If set to shared, enables shared_cache option of HTML::Template.

use_nav

If set to yes, creates navigation bar in location specified by <TMPL_LOOP NAME="PKIT_NAV"> </TMPL_LOOP> in the template.

use_template

If set to yes, uses HTML::Template files. If set to no page code is responsible for sending output. Default is yes.

REQUEST PARAMETERS

These are parameters that are specified in GET requests and POST requests where Content-type is one of application/x-www-form-urlencoded or multipart/form-data.

pkit_credential_#

Login data, typically userid/login/email (pkit_credential_0) and password (pkit_credential_1).

pkit_done

The page to return to after the user has finished logging in or creating a new account.

pkit_login_page

This parameter is used to specify the page that user attempted to login from. If the login fails, this page is redisplayed.

pkit_remember

If set to true upon login, will save user's cookie so that they are still logged in next time they restart their browser.

pkit_view

Used to implement multiple views/co-branding. For example, if set to print, will search for templates ending with .print.tmpl before using templates ending with .tmpl, and sets the pkit_view:print parameter in the view to true.

SEE ALSO

Apache::PageKit::Error, Apache::PageKit::FormValidator, Apache::PageKit::Info, Apache::PageKit::View, Apache::Request, HTML::FillInForm, HTML::Template, HTML::FormValidator

VERSION

This document describes Apache::PageKit module version 0.01

NOTES

Requires mod_perl, HTML::FillInForm, HTML::FormValidator, and HTML::Template.

I wrote these modules because I needed an application framework that was based on mod_perl and seperated HTML from Perl. HTML::Embperl, Apache::ASP and HTML::Mason are frameworks that work with mod_perl, but embed Perl code in HTML. The development was inspired in part by Webmacro, which is an open-source Java servlet framework that seperates Code from HTML.

The goal is of this module is to develop a framework that provides most of the functionality that is common across dynamic web sites, including session management, authorization, form validation, component design, error handling, and content management.

BUGS

This framework is in alpha stage. The interface may change in later releases.

Please submit any bug reports, comments, or suggestions to tjmather@thoughtstore.com, or join the Apache::PageKit mailing list at http://lists.sourceforge.net/mailman/listinfo/pagekit-users

TODO

Associate sessions with authenticated user ID.

Use path_info for the url to pass along session IDs when cookies are disabled.

AUTHOR

T.J. Mather (tjmather@thoughtstore.com)

COPYRIGHT

Copyright (c) 2000, ThoughtStore, Inc. All rights Reserved. PageKit is a trademark of ThoughtStore, Inc.

LICENSE

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Ricoh Source Code Public License for more details.

You can redistribute this module and/or modify it only under the terms of the Ricoh Source Code Public License.

You should have received a copy of the Ricoh Source Code Public License along with this program; if not, obtain one at http://www.pagekit.org/license