I've been meaning for a long time to release some code samples-- here is one I
especially like for making menus and navbars in html-- same code will work
for either.
A caveat: I use several custom modules which hides some stuff- most notably
the Page object, which is basically a hash of hashes that contain the
menu-item data, as well as an array of pages (items in a Page object) which
keeps the correct page-order. The general structure of a page-item is like
this:
name => undef, # name of page item (eg. 'contact')
admin => 0, # 1=Admin-Only
caption => undef, # page caption (eg. "Contact Us")
url => undef, # what to do if clicked eg: http://someurl
type => 'user', # User or Prot (Prot=protected & can't edit)
origin => 'user', # User or Int (Int=internal)
active => 0, # mark inactive by default
And not all of these items are relevant to this routine. So, that said, this
snippet of code-- which is meant more for its idea value than its particular
usefulness as written-- (it works well in my apps but you won't have all the
supporting stuff to make it work out of the box). This bit of code will allow
you to very easily specify an html menu/navbar structure and have the
selected item behave differently, and to specify the menu separator (if any).
It easily lends itself to horizontal and vertical menus and its html-like
(xml-ish) syntax is like so (a simplified vertical example):
<table><tr><td>
<my:menu selected="$$args{cmd}">
<sel><b><a href="__URL__">__CAPTION__</a></b><br></sel>
<norm><a href="__URL__">__CAPTION__</a><br></norm>
</my:menu>
</td></tr></table>
This produces a very attractive (albeit simple) vertical menu. What's
important is to notice the <sel>, <norm>, and (if present), <sep> tags (and
they need to be closed). ANY legal html/javascript code (or anything else for
that matter that can be expressed as a string) can be put between the tags.
For example, in more complicated menus, I often use javascript to do button
rollover effects and the like.
The function presented below will take everything (in uppercase) surrounded by
two underscores (ie. '__FIELD__') and attempt to match it to its
corresponding (lower-case) field in the page-item object (or your own
substituted hash structure).
If the <sep> tag is present, it will be used between the menu/navbar items and
will separate the items however you say. I often just use something like
<sep>|</sep> (vertical bar) or <sep> </sep> (a couple of spaces),
but it can be anything html.
To make this work, you have to be using the XMLSubsMatch setting in the
.htaccess or apache config file (wherever you set your other ASP config
vars). Mine looks like this:
PerlSetVar XMLSubsMatch my:\w+
This causes anything beginning with 'my:' in my .html/.asp files to be
interpreted (or attempted anyway) as a sub-routine reference. The args
supplied inside the opening tag itself are passed to the subroutine as
'$args' (or whatever you want to call it-- the first argument passed). The
text (if any) between the tags is passed as the second ($body). Such that:
<my:parseme somefield="someval">
Whatever you want to pass as the body goes here
</my:parseme>
This is all documented better on the main ASP site.
One thing to note that is NOT mentioned on the ASP site-- apparently the
parsing algorithm doesn't know how to handle values that are NOT enclosed in
quotes. Html does not require quotes as long as the value contains no spaces
and only alphanumeric characters. You can't do that here. The other thing to
point out is that any perl variables (eg. $myvar) are NOT escaped in the
usual apache::asp way, (<%=$myvar%>) but instead are just simply passed
between the quotes. Personally I think this is an inconsistancy, and one that
should be dealt with so that clueless users who write html pages using custom
tags don't accidently expose the workings of apache::asp. An alternative
might be to allow a secondary syntax that could only be used as subroutine
references-- eg. [% stuff %]. I can understand the depth of the syntax and
coding problems surrounding this issue-- especially when the subject of
nesting comes up... I'm not complaining, just tossing in my 2 cents and
wishing there was a way to keep the functional aspect without exposing ASP to
the clueless user (or malicious web hacker for that matter).
Anyway, fwiw, here is the routine below. You can see an example of it in
operation at: stores.wizard.org/wizorg, stores.wizard.org/wizcomp, and
stores.wizard.org/dots (I'm not sure that Dot has her store completely set up
and ready to go but you can see the menu anyway).
I hope this helps someone! :)
John Whitten
[EMAIL PROTECTED]
Wizard.Org, Inc.
##----------------------------------------------------------------------------
sub my::navbar { my::menu(@_) }
sub my::menu {
my ($args, $body) = @_;
my $norm = qq{<a href="__URL__">__CAPTION__</a><br>};
my $sel = qq{<b><a href="__URL__">__CAPTION__</a></b><br>};
my $sep = '';
my $themeurl = "$URL{theme}/$Store->{theme}/images";
if ($body =~ /<norm>/i) {
$body =~ /<norm>(.*?)<\/norm>/i; # normal cell
$norm = $1;
}
if ($body =~ /<sel>/i) {
$body =~ /<sel>(.*?)<\/sel>/i; # selected cell
$sel = $1;
}
if ($body =~ /<sep>/i) {
$body =~ /<sep>(.*?)<\/sep>/i; # divider cell
$sep = $1;
}
$$args{selected} = lc($$args{selected});
my $start = 0;
foreach (@{$Store->{pages}}) {
my $page = $Store->{pagedata}->findPage($_);
next if (isPermitted() == 0 && $page->val('admin') == 1);
my $name = $page->val('name');
my $caption = $page->val('caption') || $name;
my $url = $page->val('url');
my $selected = ($name eq $$args{selected})?1:0;
$url = $page->val('url');
$url = "/$storeid/$name" if ($url eq '');
print "$sep\n" if ($sep ne '' && $start++ > 0);
my $str = ($selected == 1)?$sel:$norm;
$str =~ s/__NAME__/$name/gie;
$str =~ s/__URL__/$url/gie;
$str =~ s/__CAPTION__/$caption/gie;
print "$str\n";
}
}
--
--------------------------------------------------------------------------------
Check out http://www.Wizard.Org for great deals on Electronic Parts
*NEW* Computer Parts & Accessories - Drives - LCD - Systems - Linux
--------------------------------------------------------------------------------
** Affordable Online Store w/Merchant Card Processing & Paypal **
Write to us: [EMAIL PROTECTED] -- Get your Store Online Today!
--------------------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]