;;; This file contains the needed mechanism to make a title to the page, and
;;; a menu at the top of it.
;;;
;;; License GPL
;;; Authors: Martin Quinson
;;; To use it, you have to declare a menu-list tag, explaining what is your
;;; menu organization. For example, I have a file called customization.wml,
;;; which contains the following:
;;; <define-tag menu-list>
;;; home/
;;; academia/
;;; academia/publications/
;;; academia/fast/
;;; academia/fast/download/
;;; academia/fast/install/
;;; academia/fast/use/:fast_use
;;; hacking/
;;; </define-tag>
;;; Then, I load it in all my pages on the very first line:
;;; #include "customize.wml"
;;; Afterward, I call the macro in this file (banner.wml), indicating which
;;; file we are building:
;;; #include <banner.wml> title="Mt's Homepage" path="home/"
;;; title will be used twice. In the html <title>, and at the top,
;;; to make a beautiful box containing it on the page.
;;; path is the filename, and should match one of the lines in menu-list.
;;; Please note that the name of the file and the name of the entry don't
;;; have to be the same. If they are different, append the filename (without
;;; the extension) to the name of the entry, separated by a colon (:)
;;; STOP TO READ HERE IF YOU JUST WANT TO USE THIS FILE.
;;; READ FURTHER IF YOU WANT TO CHANGE ANYTHING
;;; Detail of the content:
;;; - Tags:
;;; header: The header at the top of the page.
;;; - Perl functions:
;;; menu_do: Main function. build the menu, and output it
;;; menu_parse: take a space separated list of entries, and build an
;;; internal perl structure of it
;;; menu_add_item: Add an item (recursively) to the menu.
;;; Returns the modified version
;;; Used in menu_parse
;;; menu_output: outputs the visible part of #menu# from #path#
;;; ARGS: (path,menu)
;;; menu_dump: debugging purpose
;;; ARG: (menu)
;;; This is the name of the main file, ie, the one containing the header.
;;; This is used by several tags around there.
<define-tag mainfile whitespace=delete>
<perl>
$mypath="$(OUTPUTFILENAME)";
;;;$mypath = $path;
;;;$mypath =~ s|^([^/]*/)*([^/]+)/?$|$2|;
;;;$mypath =~ s|^[^:]*:(.*)|$1|;
$mypath =~ s|.php$||;
<perl:print>$mypath</perl:print>
</perl>
</define-tag>
#include <php.wml>
#include <template.wml>
#include <gettext.wml>
<phpinit>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; header tag
;;; The header at the top of the page.
;;; Arg: title.
<define-tag header endtag=required>
<table width="100%" border=0 cellspacing=0 cellpadding=0 class="navOutline">
<tr>
<td>
<table width="100%" border="0" cellspacing="1" cellpadding="0">
<tr class="content">
<div class="navTitle" valign=middle>
<preserve title><set-var %attributes>
<get-var title />
<restore title>
</div>
</tr>
<tr>
<td class="navBarColor" colspan="3">
<perl>{<perl:assign>%body</perl:assign>}</perl>
</td>
</tr>
</table>
</td>
</tr>
</table>
</define-tag>
<perl>
my $debug=0;
###########
# sub filename
# Find the file name and the menu entry
sub filename {
my $begin=shift;
my ($title,$filename);
$title=$filename=$begin;
if ($title =~ m/:/) {
$filename =~ s/^(.*):([^:]*)$/$2/;
$title = $1;
}
if ($filename !~ m/\./) {
$filename.="$(CUR_LANG_EXT).html";
}
return ($title,$filename);
}
###########
# sub menu_add_item
# Add an item (recursively) to the menu. Returns the modified version
sub menu_add_item {
my $menu=shift;
my $item=shift;
my ($begin,$end)=($item,"");
my ($title,$filename);
if ($item =~ m,^([^/]*)/(.*)$,) {
($begin,$end)=($1,$2);
}
return $menu if ($item eq "");# stop the recursive call when nothing to do
if (!defined($menu->{'size'})) {
# new entry
$menu->{'size'}=1;
($title,$filename)=filename($begin);
$menu->{'title'}="$title";
$menu->{'filename'}="$filename";
$menu->{'0'}=menu_add_item($menu->{'0'},$end);
} else {
# old entry. Search if this already exists
my $i=0;
for ($i=0 ;
$i<$menu->{'size'}
&& defined($menu->{$i}) && defined($menu->{$i}->{'title'})
&& $menu->{$i}->{'title'} ne $begin ;
$i++) {
#Nothing more to do for the search
}
if ($i==$menu->{'size'}
|| !defined($menu->{$i})
|| !defined($menu->{$i}->{'title'})) {
# Not found
$menu->{'size'}=$menu->{'size'} + 1;
($title,$filename)=filename($begin);
$menu->{"$i"}->{'title'}="$title";
$menu->{"$i"}->{'filename'}="$filename";
$menu->{"$i"}->{'size'}=0;
$menu->{$menu->{'size'}-1}=menu_add_item($menu->{$menu->{'size'}-1},
"$end");
} else {
# found
$menu->{"$i"}=menu_add_item($menu->{"$i"},"$end");;
}
}
return $menu;
}
################
# sub menu_parse
# take a space separated list of entries, and build a menu of it.
sub menu_parse{
my $list=shift;
my $menu;
$menu->{'size'}=0;
foreach my $item (split(/\n\s*/,$list)) {
$item =~ s/\s*$//;
$menu=menu_add_item($menu,$item);
}
menu_dump($menu,0) if $debug;
return $menu;
}
###############
# sub menu_dump
# debugging purpose
sub menu_dump{
my $menu=shift;
my $level=shift||0;
print "------ DUMP MENU (begin)\n" if $level == 0;
for (my $i=0;$i<$level;$i++) {
print " ";
}
if (!defined($menu->{'size'})) {
print "()\n <par>";
} else {
print $menu->{'title'}." (size=".$menu->{'size'}.").\n";
for (my $i=0;$i< ($menu->{'size'}||0);$i++) {
menu_dump($menu->{"$i"},$level+1);
}
}
print "------ DUMP MENU (end)\n" if $level == 0;
}
#################
# sub menu_output
# outputs the visible part of #menu# from #path#
sub menu_output {
my $path=shift;
my $menu=shift;
my $res="";
my $post;
return unless (defined($menu->{'size'}) || defined($menu->{'title'}))
&& ($menu->{'size'} != 0 || $menu->{'title'} ne "");
if ($menu->{'size'} != 0) {
$res .= "<table border=0><tr>\n";
}
for (my $i=0 ; $i<$menu->{'size'} ; $i++) {
my $filename,$title;
$filename=$menu->{$i}->{'filename'};
$title=$menu->{$i}->{'title'};
$res .= "<td valign=top><table border=0>\n<tr><td class=menu>";
$res .= " <a href=\"".$filename."\" "
."class=\"";
$post= "\">".$title."</a> </td>";
if ($i < $menu->{'size'}-1) {
$post .= "</tr>\n"; #<tr>
}
if (defined($menu->{$i}->{'title'})
&& defined($path->[0])
&& $menu->{$i}->{'title'} eq $path->[0]) {
if (defined($path->[1])) {
$res .= "navBar$post";
} else {
$res .= "highlightNav$post";
}
shift @$path;
$res .= "<tr><td>".menu_output($path,$menu->{$i},1)."</tr>";
} else {
$res .= "navBar$post";
}
$res .= "</table></td>\n";#</tr> en tete
}
if ($menu->{'size'} != 0) {
$res .= "</tr></table>";
}
return $res;
}
#############
# sub menu_build_path
# build menu path from filename
sub menu_build_path {
my $filename=shift;
my $menu=shift;
return "" unless (defined($menu->{'size'}) || defined($menu->{'title'}))
&& ($menu->{'size'} != 0 || $menu->{'title'} ne "");
;;;warn ($menu->{'filename'} . " ... " . $filename);
if ($menu->{'filename'} eq $filename) {
;;; warn $menu->{'title'};
return $menu->{'title'};
}
for (my $i=0 ; $i<$menu->{'size'} ; $i++) {
my $path=menu_build_path($filename, $menu->{$i});
if ($path ne "") {
;;;warn $menu->{'title'};
return $menu->{'title'} . "/" . $path;
}
}
return "";
}
#############
# sub menu_do
# build the menu, and output it
sub menu_do {
my $path=shift;
my $list=shift;
my $menu=menu_parse($list);
if ($path eq "") {
$path=menu_build_path("$(OUTPUTFILENAME)", $menu);
$path =~ s,^/,,;
}
;;;warn $path;
menu_output([split(/\//,$path)],$menu)
}
</perl>
{#banner#: \
<header title="$(title)"> \
<perl> \
$menu=menu_do("$(path)","<menu-list>"); \
<perl:print>$menu</perl:print> \
</perl> \
</header> \
:#banner#}
{#PAGETITLE#:
<perl>
my $tit;<perl:assign $tit>$(title)</perl:assign>
$tit =~ s/_/ /g;
;;; FIXME $tit = gettext $tit;
<perl:print>$tit</perl:print>
</perl>
:#PAGETITLE#}