AcePerl
view release on metacpan or search on metacpan
Ace/Browser/AceSubs.pm view on Meta::CPAN
use Ace;
use Ace::Browser::AceSubs;
use CGI qw(:standard);
use CGI::Cookie;
my $obj = GetAceObject() || AceNotFound();
PrintTop($obj);
print $obj->asHTML;
PrintBottom();
=head1 DESCRIPTION
Ace::Browser::AceSubs exports a set of routines that are useful for
creating search pages and displays for AceBrowser CGI pages. See
http://stein.cshl.org/AcePerl/AceBrowser.
The following subroutines are exported by default:
AceError
AceMissing
AceNotFound
Configuration
DoRedirect
GetAceObject
Object2URL
ObjectLink
OpenDatabase
PrintTop
PrintBottom
Url
The following subroutines are exported if explicitly requested:
AceAddCookie
AceInit
AceHeader
AceMultipleChoices
AceRedirect
DB_Name
Footer
Header
ResolveUrl
Style
Toggle
TypeSelector
To load the default subroutines load the module with:
use Ace::Browser::AceSubs;
To bring in a set of optionally routines, load the module with:
use Ace::Browser::AceSubs qw(AceInit AceRedirect);
To bring in all the default subroutines, plus some of the optional
ones:
use Ace::Browser::AceSubs qw(:DEFAULT AceInit AceRedirect);
There are two main types of AceBrowser scripts:
=over 4
=item display scripts
These are called with the CGI parameters b<name> and b<class>,
corresponding to the name and class of an AceDB object to display.
The subroutine GetAceObject() will return the requested object, or
undef if the object does not exist.
To retrieve the parameters, use the CGI.pm param() method:
$name = param('name');
$class = param('class');
=item search scripts
These are not called with any CGI parameters on their first
invocation, but can define their own parameter lists by creating
fill-out forms. The AceBrowser system remembers the last search
performed by a search script in a cookie and regenerates the CGI
parameters the next time the user selects that search script.
=back
=head1 SUBROUTINES
The following sections describe the exported subroutines.
=over 4
=cut
use strict;
use Ace::Browser::SiteDefs;
use Ace 1.76;
use CGI qw(:standard escape);
use CGI::Cookie;
use File::Path 'mkpath';
use vars qw/@ISA @EXPORT @EXPORT_OK $VERSION %EXPORT_TAGS
%DB %OPEN $HEADER $TOP @COOKIES
$APACHE_CONF/;
require Exporter;
@ISA = qw(Exporter);
$VERSION = 1.21;
######################### This is the list of exported subroutines #######################
@EXPORT = qw(
GetAceObject AceError AceNotFound AceMissing DoRedirect
OpenDatabase Object2URL Url
ObjectLink Configuration PrintTop PrintBottom);
@EXPORT_OK = qw(AceRedirect Toggle ResolveUrl AceInit AceAddCookie
AceHeader TypeSelector Style AcePicRoot
Header Footer DB_Name AceMultipleChoices);
%EXPORT_TAGS = ( );
use constant DEFAULT_DATABASE => 'default';
Ace/Browser/AceSubs.pm view on Meta::CPAN
my %searches = map {$_=>1} Configuration()->searches;
my $quovadis = url(-relative=>1);
my $db = get_symbolic();
my $referer = referer();
$referer =~ s!^http://[^/]+!! if defined $referer;
my $home = Configuration()->Home->[0] if Configuration()->Home;
if ($referer && $home && index($referer,$home) >= 0) {
my $bookmark = cookie(
-name=>"HOME_${db}",
-value=>$referer,
-path=>'/');
push(@COOKIES,$bookmark);
}
if ($searches{$quovadis}) {
Delete('Go');
my $search_name = "SEARCH_${db}_${quovadis}";
my $search_data = cookie(-name => $search_name,
-value => query_string(),
-path=>'/',
);
my $last_search = cookie(-name=>"ACEDB_$db",
-value=>$quovadis,
-path=>'/');
push(@COOKIES,$search_data,$last_search);
}
print @COOKIES ? header(-cookie=>\@COOKIES,@_) : header(@_);
@COOKIES = ();
$HEADER++;
}
=item AceInit()
This subroutine initializes the AcePerl connection to the configured
database. If the database cannot be opened, it generates an error
message and exits. This subroutine is not exported by default, but is
called by PrintTop() and Header() internally.
=cut
# Subroutines used by all scripts.
# Will generate an HTTP 'document not found' error if you try to get an
# undefined database name. Check the return code from this function and
# return immediately if not true (actually, not needed because we exit).
sub AceInit {
$HEADER = 0;
$TOP = 0;
@COOKIES = ();
# keeps track of what sections should be open
%OPEN = param('open') ? map {$_ => 1} split(' ',param('open')) : () ;
return 1 if Configuration();
# if we get here, it is a big NOT FOUND error
print header(-status=>'404 Not Found',-type=>'text/html');
$HEADER++;
print start_html(-title => 'Database Not Found',
-style => Ace::Browser::SiteDefs->getConfig(DEFAULT_DATABASE)->Style,
),
h1('Database not found'),
p('The requested database',i(get_symbolic()),'is not recognized',
'by this server.');
print p('Please return to the',a({-href=>referer()},'referring page.')) if referer();
print end_html;
Apache::exit(0) if defined &Apache::exit; # bug out of here!
exit(0);
}
=item AceMissing([$class,$name])
This subroutine will print out an error message indicating that an
object is present in AceDB, but that the information the user
requested is absent. It will then exit the script. This is
infrequently encountered when following XREFed objects. If the class
and name of the object are not provided as arguments, they are taken
from CGI's param() function.
=cut
sub AceMissing {
my ($class,$name) = @_;
$class ||= param('class');
$name ||= param('name');
PrintTop(undef,undef,$name);
print strong('There is no further information about this object in the database.');
PrintBottom();
Apache->exit(0) if defined &Apache::exit;
exit(0);
}
=item AceMultipleChoices($symbol,$report,$objects)
This function is called when a search has recovered multiple objects
and the user must make a choice among them. The user is presented
with an ordered list of the objects, and asked to click on one of
them.
The three arguements are:
$symbol The keyword or query string the user was searching
on, undef if none.
$report The symbolic name of the current display, or undef
if none.
$objects An array reference containing the Ace objects in
question.
This subroutine is not exported by default.
=cut
sub AceMultipleChoices {
my ($symbol,$report,$objects) = @_;
if ($objects && @$objects == 1) {
Ace/Browser/AceSubs.pm view on Meta::CPAN
Example:
my $author = $db->fetch(Author => 'Sulston JE');
print ObjectLink($author,$author->Full_name);
This will print out a link to a page that will display details on the
author page. The text of the link will be the value of the Full_name
tag.
=cut
sub ObjectLink {
my $object = shift;
my $link_text = shift;
my $target = shift;
my $url = Object2URL($object,@_) or return ($link_text || "$object");
my @targ = $target ? (-target=>$target) : ();
return a({-href=>Object2URL($object,@_),-name=>"$object",@targ},($link_text || "$object"));
}
=item $db = OpenDatabase()
This function opens the Acedb database designated by the configuration
file. In modperl environments, this function caches database handles
and reuses them, pinging and reopening them in the case of timeouts.
This function is not exported by default.
=cut
use Carp 'cluck';
################ open a database #################
sub OpenDatabase {
my $name = shift || get_symbolic();
AceInit();
$name =~ s!/$!!;
my $db = $DB{$name};
return $db if $db && $db->ping;
my ($host,$port,$user,$password,
$cache_root,$cache_size,$cache_expires,$auto_purge_interval)
= getDatabasePorts($name);
my @auth = (-user=>$user,-pass=>$password) if $user && $password;
my @cache = (-cache => { cache_root=>$cache_root,
max_size => $cache_size || $Cache::SizeAwareCache::NO_MAX_SIZE || -1, # hardcoded $NO_MAX_SIZE constant
default_expires_in => $cache_expires || '1 day',
auto_purge_interval => $auto_purge_interval || '6 hours',
}
) if $cache_root;
$DB{$name} = Ace->connect(-host=>$host,-port=>$port,-timeout=>50,@auth,@cache);
return $DB{$name};
}
=item PrintTop($object,$class,$title,@html_headers)
The PrintTop() function generates all the boilerplate at the top of a
typical AceBrowser page, including the HTTP header information, the
page title, the navigation bar for searches, the web site banner, the
type selector for choosing alternative displays, and a level-one
header.
Call it with one or more arguments. The arguments are:
$object An AceDB object. The navigation bar and title will be
customized for the object.
$class If no AceDB object is available, then you can pass
a string containing the AceDB class that this page is
designed to display.
$title A title to use for the HTML page and the first level-one
header. If not provided, a generic title "Report for
Object" is generated.
@html_headers Additional HTML headers to pass to the the CGI.pm
start_html.
=cut
# boilerplate for the top of the page
sub PrintTop {
my ($object,$class,$title,@additional_header_stuff) = @_;
return if $TOP++;
$class = $object->class if defined $object && ref($object);
$class ||= param('class') unless defined($title);
AceHeader();
$title ||= defined($object) ? "$class Report for: $object" : $class ? "$class Report" : ''
unless defined($title);
print start_html (
'-Title' => $title,
'-Style' => Style(),
@additional_header_stuff,
);
print Header();
print TypeSelector($object,$class) if defined $object;
print h1($title) if $title;
}
=item PrintBottom()
The PrintBottom() function outputs all the boilerplate at the bottom
of a typical AceBrowser page. If a user-defined footer is present in
the configuration file, that is printed. Otherwise, the method prints
a horizontal rule followed by links to the site home page, the AcePerl
home page, the privacy policy, and the feedback page.
=cut
sub PrintBottom {
print hr,Footer(),end_html();
}
=item $hashref = Style()
This subroutine returns a hashref containing a reference to the
configured stylesheet, in the following format:
Ace/Browser/AceSubs.pm view on Meta::CPAN
collapsed.
In a list context, Toggle() returns a two-element list. The first
element is the HTML link that expands and contracts the section. The
second element is a boolean that indicates whether the section is
currently open or closed.
This example indicates typical usage:
my $sequence = GetAceObject();
print "sequence name = ",$sequence,"\n";
print "sequence clone = ",$sequence->Clone,"\n";
if (Toggle('dna','Sequence DNA')) {
print $sequence->asDNA;
}
An alternative way to do the same thing:
my $sequence = GetAceObject();
print "sequence name = ",$sequence,"\n";
print "sequence clone = ",$sequence->Clone,"\n";
my ($link,$open) = Toggle('dna','Sequence DNA');
print $link;
print $sequence->asDNA if $open;
=cut
# Toggle a subsection open and close
sub Toggle {
my ($section,$label,$count,$addplural,$addcount,$max_open) = @_;
$OPEN{$section}++ if defined($max_open) && $count <= $max_open;
my %open = %OPEN;
$label ||= $section;
my $img;
if (exists $open{$section}) {
delete $open{$section};
$img = img({-src=>'/ico/triangle_down.gif',-alt=>'^',
-height=>6,-width=>11,-border=>0}),
} else {
$open{$section}++;
$img = img({-src=>'/ico/triangle_right.gif',-alt=>'>',
-height=>11,-width=>6,-border=>0}),
my $plural = ($addplural and $label !~ /s$/) ? "${label}s" : "$label";
$label = font({-class=>'toggle'},!$addcount ? $plural : "$count $plural");
}
param(-name=>'open',-value=>join(' ',keys %open));
my $url = url(-absolute=>1,-path_info=>1,-query=>1);
my $link = a({-href=>"$url#$section",-name=>$section},$img.' '.$label);
if (wantarray ){
return ($link,$OPEN{$section})
} else {
print $link,br;
return $OPEN{$section};
}
}
=item $html = TypeSelector($name,$class)
This subroutine generates the HTML for the type selector navigation
bar. The links in the bar are dynamically generated based on the
values of $name and $class. This function is called by PrintTop().
It is not exported by default.
=cut
# Choose a set of displayers based on the type.
sub TypeSelector {
my ($name,$class) = @_;
return unless $class;
my ($n,$c) = (escape("$name"),escape($class));
my @rows;
# add the special displays
my @displays = Configuration()->class2displays($class,$name);
my @basic_displays = Configuration()->class2displays('default');
@basic_displays = Ace::Browser::SiteDefs->getConfig(DEFAULT_DATABASE)->class2displays('default')
unless @basic_displays;
my $display = url(-absolute=>1,-path=>1);
foreach (@displays,@basic_displays) {
my ($url,$icon,$label) = @{$_}{qw/url icon label/};
next unless $url;
my $u = ResolveUrl($url,"name=$n;class=$c");
($url = $u) =~ s/[?\#].*$//;
my $active = $url =~ /^$display/;
my $cell;
unless ($active) {
$cell = defined $icon ? a({-href=>$u,-target=>'_top'},
img({-src=>$icon,-border=>0}).br().$label)
: a({-href=>$u,-target=>'_top'},$label);
} else {
$cell = defined $icon ? img({-src=>$icon,-border=>0}).br().font({-color=>'red'},$label)
: font({-color=>'red'},$label);
}
push (@rows,td({-align=>'CENTER',-class=>'small'},$cell));
}
return table({-width=>'100%',-border=>0,-class=>'searchtitle'},
TR({-valign=>'bottom'},@rows));
}
=item $url = Url($display,$params)
Given a symbolic display name, such as "tree" and a set of parameters,
this function looks up its URL and then calls ResolveUrl() to create a
single Url.
When hard-coding relative URLs into AceBrowser scripts, it is
important to pass them through Url(). The reason for this is that
AceBrowser may need to attach the database name to the URL in order to
identify it.
Example:
my $url = Url('../sequence_dump',"name=$name;long_dump=yes");
print a({-href=>$url},'Dump this sequence');
=cut
sub Url {
my ($display,$parameters) = @_;
my $url = Configuration()->display($display,'url');
return ResolveUrl($url,$parameters);
}
( run in 1.217 second using v1.01-cache-2.11-cpan-df04353d9ac )