top menu on a site

H

hudson

here's another function...I really like it, but I wonder if other people will.

basically, you have a hash of pages (scripts, whatever):

my %hash = (one => 'one.html',
two => 'two.html',
three => 'three.html'
);

and feed the calling page onto the script:

print menu('one', %hash);

sub menu {
my $source = shift;
my %scripts = @_;
my @temp;
for my $script (sort keys %scripts) {
if ($script eq $source) { push(@temp, "<b>$source</b>") }
else { push(@temp, "<a href=\"./$scripts{$script}\">$script</a>") }
}
my $output = "<center><small>\n";
$output .= join(" | \n", @temp);
$output .= "</center></small>\n<br>\n";
return $output;
}

of course, the sub is in a module far away from main ;-)

well, it is neat because it starts to take you away from static pages
and into database driven sites.
 
H

hudson

Hmmm .. it's the first time I hear HTML being referred to as "scripts"!

yes, well...using .htaccess I discovered it is very easy to do just that:

RewriteEngine on
RewriteBase /
RewriteRule ^input\..*$ main.cgi [T=application/x-httpd-cgi]
RewriteRule ^output\..*$ main.cgi [T=application/x-httpd-cgi]

and then just grab $script and $action (input or output)

(my $redirect_url = $ENV{REDIRECT_URL}) =~ s|.*/||;
my ($action, $script) = split /\./, $redirect_url;
[snip]
for my $script (sort keys %scripts) {
if ($script eq $source) { push(@temp, "<b>$source</b>") }
else { push(@temp, "<a href=\"./$scripts{$script}\">$script</a>") }
}

Ever heard of exists()?

Well, no...that's why I'm posting here...please inform ;-)
 
A

A. Sinan Unur

well, elaborate please...and maybe an alternative approach would be nice
to consider

Consider using HTML::Template.

For example:

use strict;
use warnings;

# Using a scalar containing a template snippet for illustration
# purposes. Normally, one would have a template file containing
# this snippet.

my $tmpl_src = <<TMPL;
<html>
<head>
<title>Main Page</title>
<style type="text/css">
p.menu a.selected { font-weight: bold; }
</style>
</head>
<p class="menu">|
<TMPL_LOOP MENU>
<TMPL_IF SELECTED>
<a class="selected" href="<TMPL_VAR HREF>" title="<TMPL_VAR TITLE>">
<TMPL_VAR TEXT></a>
<TMPL_ELSE>
<a href="<TMPL_VAR HREF>" title="<TMPL_VAR TITLE>"><TMPL_VAR TEXT></a>
</TMPL_IF>
|
</TMPL_LOOP>
</p>
</html>
TMPL

my %menu = (
1 => { href => 'one.html', title => 'Page 1', text => 'One' },
2 => { href => 'two.html', title => 'Page 2', text => 'Two' },
3 => { href => 'three.html', title => 'Page 3', text => 'Three' },
);

use HTML::Template;
my $tmpl = HTML::Template->new(scalarref => \$tmpl_src);
$tmpl->param(MENU => menu(1, \%menu));
$tmpl->output(print_to => *STDOUT);

sub menu {
my ($selected, $menu) = @_;
my @menu;
for my $item (sort keys %{ $menu }) {
$menu->{$item}->{selected} = 1 if($selected == $item);
push @menu, $menu->{$item};
}
return \@menu;
}
__END__

As for your example, you had:

Couple of problems with this: First, you are using numeric sort with text
keys. Second, when you fix that, you will notice that menu item 'Three'
will be displayed before 'Two'.
 
A

A. Sinan Unur

sub menu {
my ($selected, $menu) = @_;
my @menu;
for my $item (sort keys %{ $menu }) {
$menu->{$item}->{selected} = 1 if($selected == $item);
push @menu, $menu->{$item};
}
return \@menu;
}

Sorry. This should have been:

sub menu {
my ($selected, $menu) = @_;
$menu->{$selected}->{selected} = 1;
my @menu = @menu{sort keys %{ $menu }};
return \@menu;
}
 
L

Lukas Mai

A. Sinan Unur schrob:
4ax.com: [...]

As for your example, you had:
Couple of problems with this: First, you are using numeric sort with text
keys. Second, when you fix that, you will notice that menu item 'Three'
will be displayed before 'Two'.

perldoc -f sort
...
If SUBNAME or BLOCK is omitted, "sort"s in standard
string comparison order. ...
^^^^^^

HTH, Lukas
 
A

A. Sinan Unur

A. Sinan Unur schrob:
news:po1cf0p4g1l2p6dtn65u51r78a7h172mfd@ 4ax.com: [...]

As for your example, you had:
for my $script (sort keys %scripts) {
Couple of problems with this: First, you are using numeric sort with
....

perldoc -f sort
...
If SUBNAME or BLOCK is omitted, "sort"s in standard
string comparison order. ...
^^^^^^

HTH, Lukas

Oooops ... I was up too late again I guess ... Thank you for the
correction.

Sinan.
 
J

Joe Smith

Ala said:
Ever heard of exists()?

For the code he wrote, the key is expected to always exist.

The loop was to make page two to have "two" in bold instead
of having a useless link back to self.

@temp = map { $_ eq $source ? "<b>$_</b>" :
qq(<a href="$scripts{$_}">$_</a>) } keys %scripts;

A better way would be to use an array instead of a hash since
the pages are in a specific order.

@pages = qw(index.html one.html two.html three.html four.html);
@temp = map { qq(<a href="$pages[$_]">$_</a>) } (0 .. $#pages);
$temp[$source] = qq(<b>$source</b>);

-Joe
 
H

hudson

A better way would be to use an array instead of a hash since
the pages are in a specific order.

@pages = qw(index.html one.html two.html three.html four.html);
@temp = map { qq(<a href="$pages[$_]">$_</a>) } (0 .. $#pages);
$temp[$source] = qq(<b>$source</b>);

-Joe

ah...neat. map is over my head, so I will have to study this example.

I was also thinking just using a hash with two anonymous arrays:

%hash = ([home, page_one, some_other_page],
[index.html, one.html, other.html]
)

but that makes it more difficult to access

or an array:

@(home::index.html, page_one::eek:ne.html, some_other_page::eek:ther.html)

and split on '::' somewhere, but that looks like it would get nasty ;-)

sooo...seems like generalizing is always fighting against adding more functions!
 
H

hudson

Consider using HTML::Template.
[snip]

hey, thank you for posting that. I once looked into HTML::Template
and it is really just what I want to do...generalize and remove complexity
from the code, really, by hiding functions

- config
- cgi input
- output html

makes for messy code, especially if you are trying to write pages
that basically look the same but do different things.
As for your example, you had:


Couple of problems with this: First, you are using numeric sort with text
keys. Second, when you fix that, you will notice that menu item 'Three'
will be displayed before 'Two'.

before it didn't matter since the names weren't one, two, etc. but then I
actually tried using one, two, three and ....I had to change the
code...grrrrrrrrrr

oh, actually I decided to go for 1, 2 and 3 as ancor text links on that
page ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,414
Latest member
GayleWedel

Latest Threads

Top