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>&nbsp;&nbsp;</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]

Reply via email to