package Combo; ###### Combo main package. # $Id: Combo.pm,v 1.18 2003/05/09 21:29:18 admin Exp $ # This file is part of Combo and is licensed under the GPL and LGPL. # Copyright 2001-2002 by the authors. See README and LICENSE files # for more details or see http://penguinsong.org/. ### Combo is the main class of the Community website kit. # The Combo package provides services specific to Combo-based websites. # In particular, it does things like expanding the "//" in index paths. # Combo extends Context (q.v.) and hence provides the global entity # bindings and pointers to the CGI, Config, Version, Resource and User # objects needed to process the request. The reason for this clumsy # arrangement is so that Combo can contain site-dependent overrides for # defaults in Context. # Combo also includes site-specific overrides for global functions # for processing files, expanding templates, and generating web pages # for error messages and directory listings. All of these in Combo # rely on the AMP file processor for template expansion; other sites # might differ. # Usage: my $c = new Combo($path); # === eventually perh. $c = new Context($path) and let the site figure out # === which subclass to supply. # === what else belongs in Combo: # Global objects: User, Version, Process -- all might be different # at other sites. # # Global functions: # header, footer, web page, directory formatting (all of which depend # on Process for formatting) # path-to-file mappings -- depend on things like // expansion. # By contrast, Context wants base versions of these, .cf-file loading, # and other things that don't depend on URL remapping, site policies, # or file-processing techniques. # === actually, should use $c = Site::Config::topContext($path) # === and let the site file specify the context class BEGIN { use Exporter(); use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $cvsid = '$Id: Combo.pm,v 1.18 2003/05/09 21:29:18 admin Exp $ '; $cvsid =~ /,v ([0-9]+.[0-9]+)/; $VERSION=$1; @ISA = qw(Exporter Context); @EXPORT = ( ); } use Context; use Site::Config; use AMP::Tagset; ########################################################################## ### ### Constructors: ### ### Combo->new() # Obtain a new Combo instance for the # $path is the URL path from the request, usually from PATH_INFO # $trans_path is the translated path, usually from PATH_TRANSLATED # sub new { my ($class, $path, $trans_path) = (@_); my $self = Context::new(@_); $self = bless $self, $class; $self->initializeCombo(); return $self; } ########################################################################## ### ### Access Functions: ### sub getProcessor { my ($c) = @_; my $p; # === mustn't do this -- refcounts. # === To make this work we would need a cleanup function. #$p = $c->get('_processor'); #return $p if ref $p; $p = AMP::Process->new($c, $c->getPath, $c->getRealPath); #$c->{'_processor'} = $p; return $p; } ########################################################################## ### ### Indirect Access Functions: ### ### $c->getAreaMap sub getAreaMap { my $self = shift; my @urls = split(" ", $self->get("area.urls")); my @text = split(" ", $self->get("area.text")); my $hash = {}; for (my $i = @text; --$i >= 0; ) { $hash->{$urls[$i]} = $text[$i]; } return $hash; } ########################################################################## ### ### Path Manipulation: ### ### $c->expandIndexPath($path) # expand ...//... constructs in $path # ### === has to move to Site::Config; so does inverse. === # === really need to test for possible one-level directory === # sub expandIndexPath { my ($self, $path) = @_; my $p = "$path"; $p =~ s|//(.)(.)|/$1/$1$2/$1$2|; return $p; } ########################################################################## ### ### Initialization: ### ### $c->findConfig() # Locate and read the configuration file. # Set up the main configuration globals. # sub findConfig { my ($self) = (@_); $serverRoot = $ENV{SERVER_ROOT}; $docRoot = $ENV{DOCUMENT_ROOT}; # locate the site directory (COMBO_SITE_DIR, default /site) # Always relative to the document root. $siteDir = $ENV{COMBO_SITE_DIR}; $siteDir = '/site' unless $siteDir; # locate the site configuration file (COMBO_SITE_CF, default site.cf) # in $siteDir unless it contains a slash; if it doesn't _start with_ # a slash it's relative to the cgi directory, which allows for defaults # that can't be edited or viewed from the web. # Should really look along a path. $siteCF = $ENV{COMBO_SITE_CF}; $siteCF = 'site.cf' unless $siteCF; $siteCF = "$docRoot$siteDir/$siteCF" unless $siteCF =~ m|/|; $siteCF = './site.cf' unless -f $siteCF; } ### $c->initializeCombo() # Initialize a CGI. # sub initializeCombo { my ($self) = (@_); # Note that we have already called Context::initialize # so all we need here is the Combo-specific stuff. #$self->findConfig() unless $siteDir; #$self->readConfig($siteCF); #$templateDir = "$siteDir/templates" unless $templateDir; # set up areas # === in mod_perl, re-read $siteCF if it's changed. } ########################################################################## ### ### Utilities: ### ### $c->webPage($title, $text) # Put out a simple web page sub webPage { my ($self, $title, $text) = @_; print $self->start_html($title); $self->printHeader($title); print $text; $self->printFooter(); print " "; } ### $c->printHeader($title, $templateName) # Put out a standard header. $templateName is the template name; # if not found the default is "header". sub printHeader { my ($c, $title, $tname) = (@_); $title = '' unless $title; my $path = $c->getPath; my $areas = $c->getAreaMap; my $area = ''; my $p = $c->getProcessor; if ($path =~ m|^/(.)/|) { $area = $areas->{$1}; } if ($title) {} elsif ($path !~ m|//|) { $title = "$area Index"; } elsif ($c->isDir) { $title = "Index"; } else { $title = ""; } $p->{'title'} = $title; my $tdir = $c->getTemplateDir; my $t = ($tname)? "$tdir/$tname.htt" : ""; $t = "$tdir/header.htt" unless ($tname && -f $t); $p->processHT($t); print "

\n"; } sub printFooter { my ($c, $path, $tname) = (@_); my $p = $c->getProcessor; print "

\n"; # check for dir-footer before footer my $tdir = $c->getTemplateDir; my $t = ($tname)? "$tdir/$tname.htt" : ""; $t = "$tdir/footer.htt" unless ($tname && -f $t); $p->processHT($t); } ########################################################################### 'Package loaded';