Merge pull request #1482 from solgenomics/topic/move_fixture_to_repo
[sgn.git] / lib / SGN / View / Toolbar.pm
blob10212247236f0332ddefeca463ea400bd2e6611a
1 package SGN::View::Toolbar;
2 use Moose;
4 extends 'Catalyst::View';
6 has 'toolbar_data' => (
7 is => 'rw',
8 isa => 'ArrayRef',
9 required => 1,
10 default => \&default_toolbar_data
13 sub default_toolbar_data {
16 name => 'search',
17 link => '/search/direct_search.pl?search=loci',
18 desc => 'Search our database.',
19 menu => [
22 name => 'Organisms',
23 link => '/search/organisms',
24 desc => 'search for organisms'
27 name => 'Genes',
28 link => '/search/locus',
29 desc => 'Gene search.'
32 name => 'Genome features',
33 link => '/search/features',
34 desc => 'Search for many types of annotations and sequences.'
37 name => 'Phenotypes',
38 link => '/search/stocks',
39 desc => 'Search for mutants, accessions, and traits.'
42 name => 'QTLs',
43 link => '/search/phenotypes/qtl',
44 desc => 'A web interface for uploading QTL raw data, on-the-fly QTL mapping and search interface for QTLs.'
46 # {
47 # name => 'Genomic Selection',
48 # link => '/solgs/search/',
49 # desc => 'A tool for estimating breeding values using rrBlUP.'
50 # },
52 name => 'Unigenes',
53 link => '/search/transcripts/unigene',
54 desc => 'Unigene search.'
57 name => "Gene Families",
58 link => "/search/family",
59 desc => "Unigene family search."
62 name => 'Markers',
63 link => '/search/markers',
64 desc => 'Marker search.'
67 name => 'BACs',
68 link => '/search/genomic/clones',
69 desc => 'BAC (Bacterial Artificial Chromosome) search.'
72 name => 'ESTs and libraries',
73 link => '/search/transcripts/est',
74 desc =>
75 'Find EST (Expressed Sequence Tag) libraries by keyword, e.g. library name, organism, tissue, development stage, or authors.'
78 name => 'Insitu database',
79 link => '/insitu/',
80 desc =>
81 'A database of in-situ images which can be updated by users, with image add, delete and annotation editing functions. The current images were generated by the floral genome project (FGP). For more information on the floral genome project, visit http://floralgenome.org/ and http://pgn.cornell.edu/.'
84 name => 'Images',
85 link => '/search/images',
86 desc => 'Search images contained in the SGN database.'
89 name => 'Expression',
90 link => '/search/expression',
91 desc => 'Search images contained in the SGN database.'
94 name => 'People',
95 link => '/search/people',
96 desc => 'Search database of researchers who use SGN.'
99 name => 'FAQ',
100 link => '/help/faq.pl',
101 desc => 'Frequently asked questions from users of SGN.',
106 name => 'maps',
107 link => '/cview/',
108 desc => 'View and compare chromosomes from various organisms.',
109 menu => [
111 name => 'Tomato-EXPEN 2000',
112 link =>
113 '/cview/map.pl?map_id=9&show_offsets=1&show_ruler=1',
114 desc =>
115 'A combined genetic and physical map, showing the association of BACs (Bacterial Artificial Chromosomes) and BAC-Contigs to this genetic map.',
116 style => 'color:#400'
119 name => 'Tomato-Kazusa/SolCAP',
120 link =>
121 '/cview/map.pl?map_id=31&show_offsets=1&show_ruler=1',
122 desc => '',
123 style => 'color:#400'
126 name => 'Tomato QTLs',
127 link =>
128 '/cview/map.pl?map_id=34&show_offsets=1&show_ruler=1',
129 desc => '',
130 style => 'color:#400'
134 name => 'Tomato physical map',
135 link =>
136 '/cview/map.pl?map_id=p9&show_offsets=1&show_ruler=1',
137 desc =>
138 'This map is extracted from the S. lycopersicum LA925 x S. pennellii LA716 type F2.2000 genetic map.',
139 style => 'color:#400'
143 name => 'Tomato FPC contig map',
144 link =>
145 '/cview/map.pl?map_id=c9&show_offsets=1&show_ruler=1',
146 desc =>
147 'This map shows the positions of the Sanger HindIII/MboI FPC contigs relative to the the S. lycopersicum LA925 x S. pennellii LA716 type F2.2000 genetic map.',
148 style => 'color:#400'
153 name => 'Tomato IL map',
154 link =>
155 '/cview/map.pl?map_id=il6&show_offsets=1&show_ruler=1',
156 desc =>
157 'This map shows the locations of the introgressed fragments of S. pennellii in the S. lycopersicum genome, tied to the 1992 map.',
158 style => 'color:#400'
162 name => 'Tomato FISH map',
163 link => '/cview/map.pl?map_id=13',
164 desc =>
165 'Map of FISH (Fluorescent In Situ Hybridization) data.',
166 style => 'color:#400'
170 name => 'Tomato AGP map',
171 link => '/cview/map.pl?map_id=agp',
172 desc =>
173 'The Accessioned Golden Path (AGP) map for the tomato genome.',
174 style => 'color:#400'
177 name => 'Pepper COSII map',
178 link => '/cview/map.pl?map_version_id=58',
179 desc => 'COSII map',
180 style => 'color:#530'
184 name => 'Pepper-AC99',
185 link => '/cview/map.pl?map_id=11',
186 desc =>
187 'This map is based on 100 individuals from an inter-specific F2 population of Capsicum. annuum cv. NuMex RNaky and Capsicum chinense var PI159234. 426 molecular markers, including 359 SSR markers 3 specific PCR markers and 68 RFLP markers were used to construct this linkage map, with a total length of 1304.8 cM.',
188 style => 'color:#530'
191 name => 'Pepper-FA03',
192 link => '/cview/map.pl?map_id=10',
193 desc =>
194 'This map is based on 100 individuals from an inter-specific F2 population of Capsicum. annuum cv. NuMex RNaky and Capsicum frutescens BG 2814-6. 728 molecular markers, including 489 SSR markers 195 AFLP, 8 specific PCR markers and 36 RFLP were used to construct this linkage map, with a total length of 1358.7 cM.',
195 style => 'color:#530'
198 name => 'Potato-TXB 1992',
199 link => '/cview/map.pl?map_id=3',
200 desc =>
201 'This is a map based on a S. tuberosum x S. berthaultii BC S. tuberosum population reported in Tanksley et al (1992).',
202 style => 'color:#220'
205 name => 'Eggplant COSII map',
206 link => '/cview/map.pl?map_version_id=63',
207 desc => 'COSII map',
208 style => 'color:#202'
211 name => 'Eggplant-LXM 2002',
212 link => '/cview/map.pl?map_id=6',
213 desc =>
214 'This map is based on 58 F2 plants from an interspecific cross between S. linnaeanum (MM195) and S. melongena (MM738) and contains 233 RFLP markers.',
215 style => 'color:#202'
218 name => 'Tobacco SSR 2007',
219 link => '/cview/map.pl?map_id=15',
220 desc => 'Nicotiana tabacum',
221 style => 'color:#333'
224 name => 'Arabidopsis COSII',
225 link =>
226 '/cview/map.pl?map_id=7&show_offsets=1&show_ruler=1',
227 desc => 'Arabidopsis thaliana sequenced-based COSII map.',
228 style => 'color:#002800'
232 name => 'Comparative viewer...',
233 link =>
234 '/cview/view_chromosome.pl?show_offsets=1&show_ruler=1&show_offsets=1',
235 desc =>
236 'Compare chromosomes from different maps, side by side.',
237 style => 'font-style:italic;'
240 name => 'See all available maps...',
241 link => '/cview/index.pl',
242 desc => 'All chromosome maps that are available on SGN.',
243 style => 'font-style:italic'
248 name => 'genomes',
249 link => '/genomes/',
250 desc => 'Read about sequencing projects.',
251 menu => [
252 { name => 'Reference genomes' },
254 name => 'Tomato',
255 link => '/organism/Solanum_lycopersicum/genome',
256 desc =>
257 'The tomato genome has been sequenced by an international consortium.',
260 name => '<i>Solanum pennellii</i>',
261 link => '/organism/Solanum_pennellii/genome',
262 desc => 'Wild tomato genome',
267 name => 'Potato',
268 link => '/organism/Solanum_tuberosum/genome',
269 desc => '',
272 name => 'Pepper',
273 link => '/organism/Capsicum_annuum/genome',
274 desc => '',
276 { name => 'Draft genomes' },
278 name => '<i>Solanum pimpinellifolium</i>',
279 link => '/organism/Solanum_pimpinellifolium/genome',
280 desc => 'Draft genome sequence of tomato\'s closest wild relative.',
283 name => '<i>Nicotiana benthamiana</i>',
284 link => '/organism/Nicotiana_benthamiana/genome',
285 desc => 'Draft sequence for Nicotiana benthamiana, sequenced by labs at the Boyce Thompson Institute',
288 name => '<i>Nicotiana tabacum</i> &amp; related',
289 link => '/organism/Nicotiana_tabacum/genome',
290 desc => 'Draft sequence for Nicotiana tabacum accessions K326, BX, and TN90. Parental genomes <i>Nicotiana sylvestris</i> and <i>Nicotiana tomentosiformis</i>.',
293 { name => 'Resequencing projects' },
295 name => '<i>Solanum lycopersicum</i> inbreds',
296 link => '/organism/Solanum_lycopersicum/inbred_genomes',
297 desc => 'Resequencing projects of tomato inbred lines'
300 name => '150 Tomato Genome Resequencing Project',
301 link => '/organism/Solanum_lycopersicum/tomato_150',
302 desc => 'Resequencing project by the University of Wageningen'
305 name => 'BGI Tomato 360 genomes',
306 link => '/organism/Solanum_lycopersicum/tomato_360',
307 desc => 'Resequencing project of 360 tomato varieties by BGI'
310 { name => 'Projects', type => 'title' },
313 name => 'Solanaceae project (SOL)',
314 link => '/solanaceae-project/index.pl',
315 desc =>
316 'Over the coming decade the International Solanaceae Genome Project (SOL) will create a coordianted network of knowledge about the Solanaceae family aimed at answering two of the most important questions about life and agriculture: How can a common set of genes/proteins give rise to such a wide range of morphologically and ecologically distinct organisms that occupy our planet? How can a deeper understanding of the genetic basis of diversity be harnessed to better meet the needs of society in an environmentally-friendly way? On this page, you will find more information about the strategy that will be used to answer these questions.'
320 name => 'SOL-100 Project',
321 link => '/organism/sol100/view',
322 desc => 'The SOL community aims to create a common Solanaceae-based genomic framework that includes sequences and phenotypes of 100 genomes encompassing the phylogenetic diversity of the group.',
326 name => 'International Tomato Sequencing Project',
327 link => '/organism/Solanum_lycopersicum/genome',
328 desc =>
329 'The gene-rich euchromatic portion of the tomato genome is being sequenced by an international consortium. This page gives more information about the progress of the sequencing effort.'
332 name => 'U.S. tomato sequencing project',
333 link => '/about/us_tomato_sequencing.pl',
334 desc => 'An overview of the US Tomato Sequencing Project'
337 name => '<i>Nicotiana benthamiana</i> BTI site',
338 link => 'http://bti.cornell.edu/research/projects/nicotiana-benthamiana',
339 desc => 'BTI project for the Nicotiana benthamiana Draft sequence',
345 name => 'tools',
346 link => '/tools/',
347 desc => 'Tools for biologists.',
348 menu => [
350 #Sequence Analysis
351 { name => 'Sequence Analysis' },
353 name => 'BLAST',
354 link => '/tools/blast/',
355 desc =>
356 'Compare a given sequence to known sequences using the Basic Local Alignment Search Tool, NCBI BLAST v. 2.2.9 [May-01-2004]'
359 name => 'VIGS Tool',
360 link => 'http://vigs.solgenomics.net/',
361 desc =>
362 'Determine which genes a probe will silence using VIGS.',
363 target => '_blank',
368 name => 'Alignment Analyzer',
369 link => '/tools/align_viewer/',
370 desc =>
371 'Calculate alignments using Muscle v3.6, or view existing alignments using our navigator.'
374 name => 'Tree Browser',
375 link => '/tools/tree_browser/',
376 desc =>
377 'Visualize and manipulate phylogenetic trees from a newick-formatted string.'
380 # name => 'Intron Finder',
381 # link => '/tools/intron_detection/find_introns.pl',
382 # desc =>
383 # 'The SGN Intron Finder works by doing a BLAST search for <em>Arabidopsis thaliana</em> proteins that are similar to the translated protein sequence of the DNA input.'
384 # },
386 #Mapping
387 { name => 'Mapping' },
389 name => 'Genome Browser (Jbrowse)',
390 link => '/jbrowse_solgenomics/',
391 desc => 'browse genomic annotations using the fast Jbrowse browser',
395 # name => 'Genome Browser (Gbrowse)',
396 # link => '/gbrowse/bin/gbrowse/',
397 # desc => 'browse genomic annotations using GBrowse',
398 # },
400 # name => 'Comparative Genome Browser',
401 # link => 'http://solgenomics.net/gbrowse2/bin/gbrowse_syn/sol2/?search_src=pot;name=ST3.10ch01:1..90000000',
402 # desc => 'Compare genomes using GBrowse_syn',
403 # },
405 name => 'Comparative Map Viewer',
406 link =>
407 '/cview/view_chromosome.pl?show_offsets=1&amp;show_ruler=1&amp;show_offsets=1',
408 desc =>
409 'Compare chromosomes from different maps, side by side.',
412 name => 'CAPS Designer',
413 link => '/tools/caps_designer/caps_input.pl',
414 desc =>
415 'Designs CAPS (Cleaved Amplified Polymorphic Sequence) assays for up to twelve sequences. Two types of nucleotide inputs are accepted: fasta sequences and clustal aligment. It generates a list of polymorphic enzymes that cut the sequences into different length products.'
418 # name => 'Seed BAC Finder',
419 # link => '/tools/seedbac/',
420 # desc =>
421 # 'Lists all anchored BACs for a given chromosome to help identify seed BACs, or suggests a seed BAC given a marker name. '
422 # },
424 name => 'solQTL: QTL Mapping',
425 link => '/search/phenotypes/qtl',
426 desc =>
427 'A web interface for uploading raw QTL data, on-the-fly QTL mapping, linking predicted QTLs to relevant genetic and genomic data in SGN, and search interface for QTLs.'
430 # name => 'solGS: Genomic Selection',
431 # link => '/solgs/search',
432 # desc =>
433 # 'Builds genomic selection models and predicts genomic estimated breeding values. Prediction is done using Ridge Regression - Best Linear Unbiased Prediction (RR-BLUP).'
434 # },
435 #Molecular Biology
436 { name => "Molecular Biology" },
439 # name => 'Signal Peptide Finder',
440 # link => '/tools/sigpep_finder/input.pl',
441 # desc =>
442 #'This method of searching for signal sequences is designed to complement SignalP, and has similar success rates.'
443 # },
445 name => 'In Silico PCR',
446 link => '/tools/insilicopcr',
447 desc => 'In Silico PCR tool based on BLAST'
450 name => 'Tomato Expression Atlas (TEA)',
451 link =>'http://tea.solgenomics.net/',
452 desc => 'The Tomato Expression Atlas',
455 name => 'Tomato Expression Database (TED)',
456 link => '/ted',
457 desc => 'The Tomato Expression Database',
459 #Systems Biology
460 { name => "Systems Biology" },
462 name => 'SolCyc Biochemical Pathways',
463 link => '/tools/solcyc/',
464 desc => 'An interactive map of metabolic pathways.'
468 name => 'Coffee Interactomic Data',
469 link => '/tools/interactomics',
470 desc => 'Coffee Interactome Data with Cytoscape Web Start viewer.'
473 name => 'SGN Ontology Browser',
474 link => '/tools/onto/',
475 desc => 'AJAX ontology browser.'
478 { name => "Breeder Tools" },
480 name => 'Breeder Home',
481 link => '/breeders/home',
482 desc => 'Manage a breeding program',
484 #Bulk Query
485 { name => 'Bulk Query' },
488 name => 'FTP Site',
489 link => '/tools/bulk?mode=ftp',
490 desc =>
491 'FTP (File Transfer Protocol) is more efficient than HTTP (HyperText Transfer Protocol) for transferring large files. Many of our larger archive files are accessible here.'
494 name => 'Download Gene Sequences',
495 link => '/tools/bulk?mode=genes',
496 desc => 'Download nucleotide or protein sequences for a list of genes'
499 name => 'Clones, Arrays, Unigenes and BACs',
500 link => '/tools/bulk',
501 desc =>
502 'Rather than sifting through SGN page by page, here you can download large quantities of information in a single step.'
505 name => 'Unigene Converter',
506 link => '/tools/bulk?mode=converter',
507 desc => 'get the last version of unigenes and tomato gene ids from a list of unigenes.'
510 # name => 'ID Converter (SGN <=> TIGR)',
511 # link => '/tools/convert/input.pl',
512 # desc =>
513 # 'The Institute for Genomic Research and SGN maintain independent unigene databases, entries in which tend to have common member ESTs (Expressed Sequence Tags), although they tend not to correspond completely. This tool uses common members to convert back and forth between the two identifier sets.'
514 # },
516 #Other
517 # { name => "Other" },
519 # name => 'Primer 3',
520 # link => '/primer3/',
521 # desc => 'Pick primers for PCR reactions'
522 # },
528 =head2 headings
530 my @headings=$tb->headings();
532 Returns a list of the names of the main toolbar buttons
533 ('search','maps','genomes','tools'). These can then be used to
534 access other parts of this object.
536 =cut
538 sub headings {
539 map { $_->{name} } @{ shift->toolbar_data };
542 =head2 heading_link
544 print '<a href="'.$_->heading_link($heading).qq|">$_</a>|
545 for @headings;
547 Takes a heading (which can be gotten from the headings
548 function). Returns the stuff that is supposed to go in the href
549 attribute for this heading.
551 =cut
553 sub heading_link {
554 my $self = shift;
555 my ($heading) = @_;
556 for my $heading_hash ( @{ $self->toolbar_data } ) {
557 if ( $heading_hash->{name} eq $heading ) {
558 return $heading_hash->{link};
563 =head2 heading_desc
565 for my $heading(@headings)
567 print"$heading description: ".$tb->heading_desc($heading);
570 Takes a heading (which can be gotten from the headings function). Returns a description of what the linked-to page is supposed to do.
572 =cut
574 sub heading_desc {
575 my $self = shift;
576 my ($heading) = @_;
577 for my $heading_hash ( @{ $self->toolbar_data } ) {
578 if ( $heading_hash->{name} eq $heading ) {
579 return $heading_hash->{desc};
584 =head2 menu_options
586 for my $heading(@headings)
588 my @menu_options=$tb->menu_options($heading);
591 Takes a heading (which can be gotten from the headings function). Returns a list of the names of the options below that heading ('Genes','Unigenes','Markers','BACs','Annotations','ESTs and libraries','People'). Like the list returned by the headings function, these can then be used to access other information from this object.
593 =cut
595 sub menu_options {
596 my $self = shift;
597 my ($heading) = @_;
598 for my $heading_hash ( @{ $self->toolbar_data } ) {
599 if ( $heading_hash->{name} eq $heading ) {
601 # the toolbar links don't work if you add tooltips to the toolbar. fix?
602 # my @menu_options=map {CXGN::Page::FormattingHelpers::tooltipped_text($_->{name},$_->{desc},'toolbar_help')} @{$heading_hash->{menu}};
603 my @menu_options = map { $_->{name} } @{ $heading_hash->{menu} };
604 return @menu_options;
609 =head2 option_link
611 for my $heading(@headings)
613 my @menu_options=$tb->menu_options($heading);
614 for my $option(@menu_options)
616 print"<a href=\"".$tb->option_link($heading,$option)."\">$option</a>";
620 Takes a heading and an option. Returns the stuff that goes in the href for that option.
622 =cut
624 sub option_link {
625 my $self = shift;
626 my ( $heading, $option ) = @_;
628 #print STDERR "option_link received: heading '$heading' option '$option'\n";
629 for my $heading_hash ( @{ $self->toolbar_data } ) {
630 if ( $heading_hash->{name} eq $heading ) {
631 for my $menu_option_hash ( @{ $heading_hash->{menu} } ) {
632 if ( $menu_option_hash->{name} eq $option ) {
633 my $option_link = $menu_option_hash->{link};
634 if ($option_link) { return $option_link }
640 #die"Option link not found for heading '$heading' option '$option'";
643 sub option_target {
644 my $self = shift;
645 my ( $heading, $option ) = @_;
647 #print STDERR "option_link received: heading '$heading' option '$option'\n";
648 for my $heading_hash ( @{ $self->toolbar_data } ) {
649 if ( $heading_hash->{name} eq $heading ) {
650 for my $menu_option_hash ( @{ $heading_hash->{menu} } ) {
651 if ( $menu_option_hash->{name} eq $option ) {
652 my $option_target = $menu_option_hash->{target};
653 if ($option_target) { return ' target=$option_target ' }
661 =head2 option_style
663 for my $heading(@headings)
665 my @menu_options=$tb->menu_options($heading);
666 for my $option(@menu_options)
668 my $style = $tb->option_style($heading,$option); print "<span style='$style'>";
669 #print option item
670 print "</span>";
674 Takes a heading and an option. Returns the stuff that goes in the href for that option. Override me.
677 =cut
679 sub option_style {
680 my $self = shift;
681 my ( $heading, $option ) = @_;
683 #print STDERR "option_link received: heading '$heading' option '$option'\n";
684 for my $heading_hash ( @{ $self->toolbar_data } ) {
685 if ( $heading_hash->{name} eq $heading ) {
686 for my $menu_option_hash ( @{ $heading_hash->{menu} } ) {
687 if ( $menu_option_hash->{name} eq $option ) {
688 my $option_style = $menu_option_hash->{style};
689 if ($option_style) { return $option_style }
695 #die"Option link not found for heading '$heading' option '$option'";
698 =head2 option_desc
700 for my $heading(@headings)
702 my @menu_options=$tb->menu_options($heading);
703 for my $option(@menu_options)
705 print"$option description: ".$tb->option_desc($heading,$option);
709 Takes a heading and an option. Returns the stuff that goes in the href for that option.
711 =cut
713 sub option_desc {
714 my $self = shift;
715 my ( $heading, $option ) = @_;
716 for my $heading_hash ( @{ $self->toolbar_data } ) {
717 if ( $heading_hash->{name} eq $heading ) {
718 for my $menu_option_hash ( @{ $heading_hash->{menu} } ) {
719 if ( $menu_option_hash->{name} eq $option ) {
720 return $menu_option_hash->{desc};
727 sub as_html {
728 my $self = shift;
729 my @headings = $self->headings();
731 #decorate the headings array with its menu alignments
732 @headings = map [ 'center', $_ ], @headings;
733 if ( @headings > 1 ) {
734 $headings[0]->[0] = 'left';
736 # $headings[-1]->[0] = 'right';
739 my $index = 0;
740 my $toolbar_html = <<EOH
741 <table class="toolbar" summary="" cellspacing="0" cellpadding="0">
742 <tr class="toolbar_content">
743 <td class="toolbar_l"><img src="/documents/img/toolbar_l.gif" alt="" /></td>
745 . join(
747 map {
748 my ( $align, $heading ) = @$_;
749 my $heading_link = $self->heading_link($heading);
750 my $popup_menu = $self->render_menu($heading);
751 <<EOH
752 <td class="toolbar_content" onmouseover="CXGN.Page.Toolbar.showmenu('$heading')" onmouseout="CXGN.Page.Toolbar.hidemenu()" style="text-align: $align">
753 <a class="toolbar_menuname" href="$heading_link">$heading</a>
754 <div style="position: relative; text-align: left">
755 $popup_menu
756 </div>
757 </td>
759 } @headings
761 . <<EOH
763 <td class="toolbar_search toolbar_content">
764 <form name="quicksearch" class="quicksearch" action="/search/quick_search.pl">
765 <input class="quicksearch field" type="text" name="term" size="14" />
766 <input class="quicksearch imgbutton" type="image" src="/documents/img/sol_search_button.gif" value="sol search" />
767 </form>
768 </td>
769 <td class="toolbar_r" height="1">
770 <img src="/documents/img/toolbar_r.gif" alt="" />
771 </td>
772 </tr>
773 </table>
774 <script language="JavaScript" type="text/javascript">
776 . join( '', map <<EOH, @headings )
777 CXGN.Page.Toolbar.addmenu('$_->[1]');
779 . <<EOH
780 </script>
784 #return HTML for the popup menu for the menu heading
785 sub render_menu {
786 my ( $self, $heading ) = @_;
788 my @menu_options = $self->menu_options($heading);
790 return <<EOH
791 <table cellspacing="0" cellpadding="0" id="$heading" class="toolbar_popmenu">
793 . join( '',
794 map {
795 my $menu_option = $_;
797 #menu options for each heading, these will be invisible unless hovered over
798 my $option_link = $self->option_link( $heading, $menu_option );
799 my $option_target = $self->option_target( $heading, $menu_option );
800 $option_link &&=
801 qq|<a class="toolbar_item" $option_target href="$option_link">$menu_option</a>|;
802 $option_link ||= qq|<span class="toolbar_item">$menu_option</span>|;
803 my $style = $self->option_style( $heading, $menu_option );
804 <<EOH
805 <tr><td class="toolbar_item">$option_link</td></tr>
807 } @menu_options
809 . <<EOH
810 </table>
814 sub index_page {
815 my $self = shift;
816 my ($heading) = @_;
817 my $content = '';
818 my $disp_heading = ucfirst($heading);
819 for my $option ( $self->menu_options($heading) ) {
820 my $link = $self->option_link( $heading, $option );
821 my $desc = $self->option_desc( $heading, $option );
822 if ($link) {
823 $content .=
824 qq|<div style="margin-left:10px"><a href="$link">$option</a> - $desc<br /><br /></div>|;
826 else {
827 $content .=
828 "<br /><span style='font-size:1.00em; font-weight:bold'>$option</span> $desc";
829 $content .= ": $desc" if $desc;
830 $content .= "<br /><br />";
833 return <<END_HEREDOC;
834 <center>
835 <table class="boxbgcolor2" width="100%" summary="">
836 <tr>
837 <td width="15%">&nbsp;</td>
838 <td width="70%" class="left">
839 <div class="boxcontent">
840 <div class="subheading" style='font-size:1.1em'>
841 $disp_heading<br />
842 </div>
843 <div class="boxsubcontent">
844 $content
845 </div>
846 </div>
847 </td>
848 <td width="15%">&nbsp;</td>
849 </tr>
850 </table>
851 </center>
852 END_HEREDOC