More cleanups.
[openssl-web.git] / openssl.wml
1 ##
2 ##  openssl.wml -- WML Template for the www.openssl.org website
3 ##  Written by Ralf S. Engelschall <rse@engelschall.com>
4 ##
5 ##  Usage: #use wml::openssl area=<area_name> [page=<page_name>]
6 ##
7
8 #use wml::std::tags
9 #use wml::std::info
10 #use wml::des::navbar
11 #use wml::des::space
12
13 ##
14 ##  The Global Page Layout
15 ##
16
17 #   start of page header
18 [PAGE_HEAD:\
19 <html>
20 <head>
21
22 #   insert information about the webpage
23 <info style=comment domainname="openssl.org"
24       copyright="1998-2014 The OpenSSL Project, http://www.openssl.org/">
25 <info style=meta domainname="openssl.org"
26       copyright="1998-2014 The OpenSSL Project, http://www.openssl.org/">
27
28 #   insert overideable title container
29 <title*>OpenSSL: {#PAGE_TITLE#}</title*>
30 #   predefine it to show errors
31 ..PAGE_TITLE!>>Error: Undefined Title !!<<..
32 #   define override tag
33 <define-tag title endtag=required>
34 ..PAGE_TITLE>>%body<<..
35 </define-tag>
36
37 #   define a style-sheet for adjusting some HTML layouting things
38 #   to conform to some typographically stronger conventions.
39 <style type="text/css"><!--
40 BODY      { position: absolute; left: 0px; top: 0px; background: #666699; }
41 A         { text-decoration: none; font-weight: bold; }
42 A:link    { text-decoration: none; font-weight: bold; color: #666699; }
43 A:visited { text-decoration: none; font-weight: bold; color: #666699; }
44 A:hover   { text-decoration: none; font-weight: bold; color: #666699; text-decoration: underline; }
45 \#red { color: #cc3333; }
46 \#sf  { font-family: arial,helvetica; font-variant: normal; font-style: normal; }
47 \#sfl { font-weight: bold; font-family: arial,helvetica; font-size: 16pt; \
48         line-height: 16pt; font-variant: normal; font-style: normal; }
49 H1    { font-weight: bold; font-size: 18pt; line-height: 18pt; \
50         font-family: arial,helvetica; font-variant: normal; font-style: normal; }
51 H2    { font-weight: bold; font-size: 14pt; line-height: 14pt; \
52         font-family: arial,helvetica; font-variant: normal; font-style: normal; }
53 H3    { font-weight: bold; font-size: 12pt; line-height: 12pt; \
54         font-family: arial,helvetica; font-variant: normal; font-style: normal; }
55 --></style>
56
57 #   end of header and start of physical body
58 #   (use additionally use colors here for older browsers)
59 </head>
60 <body link="#6666cc" alink="#6666cc" vlink="#6666cc" bgcolor="#666699" text="#000000"
61       marginheight=0 leftmargin=0 rightmargin=0 topmargin=0>
62
63 #   now define the page layout by a nested table
64 #   structure consisting of a 5x5 cell grid.
65 <table width=100% cellspacing=0 cellpadding=0 border=0>
66   #   visually: the top line of the page
67   <tr>\
68     <td align=left width=100 bgcolor="#666699"><img src="$(IMG)/page-head-tl.jpg" alt="OpenSSL"></td>\
69     <td align=left colspan=2 width=600 bgcolor="#666699"><img src="$(IMG)/page-head-tm.jpg" alt=""></td>\
70     <td align=right width=20 bgcolor="#666699">&nbsp;&nbsp;&nbsp;</td>\
71     <td align=right width=50 bgcolor="#666699">&nbsp;</td>\
72   </tr>
73   #   visually: the top of the white body with the subnavbar
74   <tr>\
75     <td align=left width=100><img src="$(IMG)/page-head-bl.jpg"></td>\
76     <td align=left width=20><img src="$(IMG)/page-head-bm.jpg"></td>\
77     <td align=left width=100% bgcolor="#ffffff">\
78         {#PAGE_SUBNAVBAR#}\
79     </td>\
80     <td align=right width=20><img src="$(IMG)/page-corner-tr.gif"></td>\
81     <td align=right width=50 bgcolor="#666699">&nbsp;</td>\
82   </tr>
83   #   visually: the left main navigation bar and the white body
84   <tr>\
85     <td align=left valign=top width=100 bgcolor="#666699">{#PAGE_NAVBAR#}</td>\
86     <td align=left valign=top width=20  bgcolor="#ffffff">&nbsp;</td>\
87     <td align=left valign=top bgcolor="#ffffff">\
88         <br>
89         :PAGE_HEAD][PAGE_BODY:
90         {#PAGE_BODY#}
91         :PAGE_BODY][PAGE_FOOT:\
92     </td>\
93     <td align=right width=20 bgcolor="#ffffff">&nbsp;&nbsp;&nbsp;</td>\
94     <td align=right width=50 bgcolor="#666699">&nbsp;</td>\
95   </tr>
96   #   visually: the bottom of the white body
97   <tr>\
98     <td align=left valign=top width=100 bgcolor="#666699">&nbsp;</td>\
99     <td align=left width=20><img src="$(IMG)/page-corner-bl.gif"></td>\
100     <td align=left valign=top bgcolor="#ffffff">&nbsp;</td>\
101     <td align=right width=20><img src="$(IMG)/page-corner-br.gif"></td>\
102     <td align=right width=50 bgcolor="#666699">&nbsp;</td>\
103   </tr>
104   #   visually: the bottom of the page (only for esthetical
105   #   reasons, i.e. the page doesn't end with the white body)
106   <tr>\
107     <td colspan=5 bgcolor="#666699">&nbsp;</td>\
108   </tr>
109 </table>
110
111 #   the physical end of the body
112 </body>
113 </html>
114 :PAGE_FOOT]
115
116 ##
117 ##  The main Navigation Bar [left, vertically]
118 ##
119
120 #   define the navigation bar through a grammar
121 <navbar:define name=navbar imgstar="n:s:s"
122                imgbase="$(IMG)" urlbase="$(ROOT)">
123   #   bar header
124   <navbar:header>
125   </navbar:header>
126   #   button prolog
127   <navbar:prolog>
128     <tr><td>
129   </navbar:prolog>
130   #   the buttons itself
131   <navbar:button id=title    url="."      txt="Home"        img=page-navbar-ti-*.jpg>
132   <navbar:button id=source   url=source/  txt="Download"       img=page-navbar-so-*.jpg>
133   <navbar:button id=FAQ      url=support/faq.html   txt="FAQ"          img=page-navbar-fq-*.jpg>
134   <navbar:button id=about    url=about/   txt="About"        img=page-navbar-ab-*.jpg>
135   <navbar:button id=news     url=news/    txt="News"         img=page-navbar-ne-*.jpg>
136   <navbar:button id=docs     url=docs/    txt="Documents"    img=page-navbar-do-*.jpg>
137   <navbar:button id=support  url=support/ txt="Support"      img=page-navbar-su-*.jpg>
138   <navbar:button id=security url=news/vulnerabilities.html txt="Security"      img=page-navbar-se-*.jpg>
139   #   button epilog
140   <navbar:epilog>
141     </td></tr>
142   </navbar:epilog>
143   #   bar footer
144   <navbar:footer>
145   </navbar:footer>
146 </navbar:define>
147
148 #   and then immediately render it into its layout location
149 #   (Hint: The top and buttom images have to be part of the table
150 #   structure because only this way we can put them 0pt to the
151 #   buttons without a gap)
152 ..PAGE_NAVBAR>>\
153   <table cellspacing=0 cellpadding=0 border=0>\
154     <tr><td><img src="$(IMG)/page-navbar-top.jpg"></td></tr>
155     #   render it!
156     <navbar:render name=navbar select=$(area) $(page:+subselected)>
157     <tr><td><img src="$(IMG)/page-navbar-bot.jpg"><br><p></td></tr>
158   </table>
159 <<..
160
161 ##
162 ##  The Sub Navigation Bar (SNB) [top, horizontally]
163 ##
164
165 #   define the <snb>...</snb> container tag
166 <define-tag snb endtag=required>
167   #   1. define the navigation bar through a grammar
168   <navbar:define name=snb urlbase="$(SNB_ROOT)" 
169                  txtcol_normal="#666666" txtcol_select="#000000">
170     #   bar header
171     <navbar:header>\
172       <table cellspacing=0 cellpadding=0 border=0>
173         <tr>
174     </navbar:header>
175     #   button prolog (normal)
176     <navbar:prolog>\
177           <td><font face="Arial,Helvetica">&nbsp;
178     </navbar:prolog>
179     #   button prolog (selected)
180     <navbar:prolog type=S>\
181           <td bgcolor="#f0f0f0">&nbsp;<font face="Arial,Helvetica"><b>
182     </navbar:prolog>
183     #   ...here the <snb_button> tags will occur...
184     %body
185     #   button epilog (normal)
186     <navbar:epilog>\
187           </font>&nbsp;</td><td>|</td>
188     </navbar:epilog>
189     #   button epilog (selected)
190     <navbar:epilog type=S>\
191           </b></font>&nbsp;</td><td>|</td>
192     </navbar:epilog>
193     #   last button epilog (normal)
194     <navbar:epilog pos=last>\
195           </font>&nbsp;</td><td></td>
196     </navbar:epilog>
197     #   last button epilog (selected)
198     <navbar:epilog type=S pos=last>\
199           </b></font>&nbsp;</td><td></td>
200     </navbar:epilog>
201     #   bar footer
202     <navbar:footer>\
203         </tr>
204       </table>
205     </navbar:footer>
206   </navbar:define>
207   #   2. render the navigation bar and divert
208   #      divert it into it's final location
209   ..PAGE_SUBNAVBAR>>\
210   <navbar:render name=snb select="$(page)">\
211   <<..
212 </define-tag>
213
214 #   define the <snb_button> tag for the <snb> container
215 #   (this is for consistency with the tag names)
216 <define-tag snb_button>
217   <navbar:button %attributes>
218 </define-tag>
219
220 #   predefine the contents of the SNB location
221 #   by diverting a whitespace character to it.
222 #   This prevents the table to be folded.
223 ..PAGE_SUBNAVBAR!>>
224 &nbsp;
225 <<..
226
227 #   and now the final WML trick: When the page=<page_name>
228 #   attribute is specified for this template, we read in the SNB
229 #   spec-file which now can use the <snb>..</snb> and
230 #   <snb_button> tags to actually define and render a SNB. This
231 #   is accomplished by doing some sort of a conditional #include. ;-)
232 $(page:*# )$(page:+#include ")$(SNB_RC:-.wmlsnb)$(page:+")
233
234 ##
235 ##  Useful tags (for convenience purposes only)
236 ##
237
238 #   define a <item> tag for <ul>/<ol> item similar to <li> but
239 #   which is nice for URL lists like the Related area where
240 #   we want a special layout.
241 <define-tag item>
242 <preserve name>
243 <preserve url>
244 <preserve aio>
245 <preserve info>
246 <set-var aio=*>
247 <set-var %attributes>
248 <li><imgdot width=1 height=18>\
249     <a href="<get-var url>"><font size=+1 face="Arial,Helvetica"><b><get-var name></b></font></a>
250     <ifeq "<get-var aio>" "" <img src="aio.gif" alt="[all-in-one]" align=absmiddle>>
251     <br>
252     <a href="<get-var url>"><font size=-1><get-var url></font></a><br>
253     <ifeq "<get-var info>" "" "" "<get-var info>">
254 <restore info>
255 <restore aio>
256 <restore url>
257 <restore name>
258 </define-tag>
259
260 #   define a <filelist> tag which can be used to create a file listing which
261 #   is optically more compact than the stuff Apache's mod_autoindex creates.
262 #   Especially the current version is marked red, too.
263 <define-tag filelist>
264 <pre>
265 <b>   Bytes      Timestamp       Filename</b>
266 <b>________ ____________________ ____________________________</b>
267 <:
268 @HI = ();
269 open(FP, "<index.current");
270 while (<FP>) {
271    s|\s*\n$||;
272    push(@HI, $_);
273 }
274 close(FP);
275 sub ls {
276     my ($pat) = @_;
277     my (@F, @R, $f, @S, @T);
278     @F = sort { (stat($a))[9] <=> (stat($b))[9]; } (glob($pat));
279     @R = ();
280     foreach $f (@F) {
281         next if ($f =~ m|^index.*|);
282         if ('%1' ne '') {
283             if (! %1 $f) {
284                 next;
285             }
286         }
287         @S = stat($f);
288         $f = "$f/" if (-d $f);
289         @T = localtime($S[9]);
290         my @moy = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
291                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
292         push(@R, sprintf("%"."8d %"."s %"."2d %"."02d:%"."02d:%"."02d %"."d %"."s\n", 
293              $S[7], $moy[$T[4]], $T[3], $T[2], $T[1], $T[0], 1900+$T[5], $f));
294     }
295     return @R;
296 }
297 @L = &ls("%0");
298 foreach $l (@L) {
299     next if ($l =~ m|^\s*$|);
300     $l =~ s|(\s+)(\S+[^/])(\s*\n)$|$1."<a href=\"$2\">$2</a>".$3|e;
301     $l =~ s|(\s+)(\S+/)(\s*\n)$|$1."<a href=\"$2\"><b>$2</b></a>".$3|e;
302     foreach $hi (@HI) {
303         $l =~ s|^(.*$hi.*)$|<font color="#cc3333">$1&nbsp;&nbsp;<b>[LATEST]</b></font>|;
304         $l =~ s|>($hi)<|><font color="#cc3333">$1</font><|;
305     }
306     print $l;
307 }
308 :>
309 </pre>
310 </define-tag>
311
312 <define-tag rfilelist>
313 <pre>
314 <b>   Bytes      Timestamp       Filename</b>
315 <b>________ ____________________ ____________________________</b>
316 <:
317 @HI = ();
318 open(FP, "<index.current");
319 while (<FP>) {
320    s|\s*\n$||;
321    s/#.*$//;
322    next if (/^\s*$/);
323    # If line is of form "last <regex>" look for last
324    # matching filename in the list.
325    # This means "last openssl-1*.tar.gz" will automatically
326    # mark the last version of OpenSSL as the latest without
327    # the need to manually update index.current on each release.
328    if (/^\s*last\s*(\S+)\s*$/) {
329         # Get list of all file, skip betas
330         my @list = sort grep(!/beta/, glob($1));
331         my $lastfile = pop @list;
332         push(@HI, $lastfile) if (-f $lastfile);
333    } elsif (-f $_) {
334         push(@HI, $_);
335    }
336 }
337 close(FP);
338 sub ls {
339     my ($pat) = @_;
340     my (@F, @R, $f, @S, @T);
341     @F = sort { (stat($b))[9] <=> (stat($a))[9]; } (glob($pat));
342     @R = ();
343     foreach $f (@F) {
344         next if ($f =~ m|^index.*|);
345         if ('%1' ne '') {
346             if (! %1 $f) {
347                 next;
348             }
349         }
350         @S = stat($f);
351         $f = "$f/" if (-d $f);
352         @T = localtime($S[9]);
353         my @moy = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
354                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
355         push(@R, sprintf("%"."8d %"."s %"."2d %"."02d:%"."02d:%"."02d %"."d %"."s\n", 
356              $S[7], $moy[$T[4]], $T[3], $T[2], $T[1], $T[0], 1900+$T[5], $f));
357     }
358     return @R;
359 }
360 @L = &ls("%0");
361 foreach $l (@L) {
362     next if ($l =~ m|^\s*$|);
363     if ($l =~ m|(\s+)(\S+[^/])(\s*\n)$|) {
364         my $h = $`.$1;
365         my $f = $2;
366         my $t = $3;
367         my $r = "<a href=\"$f\">$f</a>";
368         if (-f "$f.md5") { $r .= " (<a href=\"$f.md5\">MD5</a>)"; }
369         if (-f "$f.sha1") { $r .= " (<a href=\"$f.sha1\">SHA1</a>)"; }
370         if (-f "$f.asc") { $r .= " (<a href=\"$f.asc\">PGP sign</a>)"; }
371         $l = $h.$r.$t;
372     }
373     $l =~ s|(\s+)(\S+/)(\s*\n)$|$1."<a href=\"$2\"><b>$2</b></a>".$3|e;
374     foreach $hi (@HI) {
375         $l =~ s|^(.*$hi.*)$|<font color="#cc3333">$1&nbsp;&nbsp;<b>[LATEST]</b></font>|;
376         $l =~ s|>($hi)<|><font color="#cc3333">$1</font><|;
377     }
378     print $l;
379 }
380 :>
381 </pre>
382 </define-tag>
383
384 <define-tag notes>
385 <preserve minversion>
386 <preserve maxversion>
387 <preserve filename>
388 <set-var %attributes>
389 <:
390
391 my $minversion = "<get-var minversion>";
392 my $maxversion = "<get-var maxversion>";
393 my $dirname = "<get-var dirname>";
394 my $file;
395 my $custompage = 0;
396
397 if ($maxversion eq "") {
398         $minversion="<get-var WML_SRC_FILENAME>";
399         $minversion =~ s/^.*-(\d+\.\d+\.\d+)-.*$/$1/;
400         $maxversion = $minversion;
401 } else {
402         $custompage = 1;
403 }
404
405
406 my $dir = defined $ENV{PODSHOME} ? "$ENV{PODSHOME}/../.." : "/v/openssl/checkouts";
407 if ($dirname ne "") {
408         $file = "${dir}/$dirname/NEWS";
409         $custompage = 1;
410 } else {
411         $file = "${dir}/openssl-${minversion}-stable/NEWS";
412 }
413 # For testing
414 $file = $ENV{NEWSTEST} if defined $ENV{NEWSTEST};
415 if ($custompage == 0) {
416         my $brname = $minversion;
417         $brname =~ tr/./_/;
418         $brname = "OpenSSL_${brname}-stable";
419         print <<"END"
420 <title>OpenSSL $minversion Release Notes.</title>
421 <h1>OpenSSL $minversion Branch Release notes</h1>
422
423 The major changes and known issues for the $minversion branch of the OpenSSL
424 toolkit are summarised below. The contents reflect the current state of the
425 <tt>NEWS</tt> file inside the git repository.
426 <p>
427 Additional details of changes can be found in the <a href="http://git.openssl.org/gitweb/?p=openssl.git;a=blob_plain;f=CHANGES;hb=refs/heads/$brname">ChangeLog for OpenSSL $minversion</a>.
428 <p>
429 A complete list of changes to OpenSSL $minversion can be found in the <a href="http://git.openssl.org/gitweb/?p=openssl.git;a=shortlog;h=refs/heads/$brname">git repository commit log</a>.
430 <p>
431
432 END
433 }
434
435 my $copy = 0;
436 my $in_ul = 0;
437 open(FP, "<$file") || die "Can't open $file";
438 while (<FP>) {
439         if (/^\s*Major changes between.*(\d+\.\d+\.\d+)\D.*$/ ||
440                 /^\s*Known issues in.*(\d+\.\d+\.\d+)\D.*$/) {
441                 if ($1 ge $minversion && $1 le $maxversion) {
442                         $copy = 1;
443                         s|^(.*)$|<b>$1</b>|;
444                         if ($in_ul) {
445                                 print "</ul>\n";
446                                 $in_ul = 0;
447                         }
448                 print;
449                 next;
450                 } elsif ($copy) {
451                         last;
452                 }
453         }
454         if ($copy) {
455                 s/&/&amp;/g;
456                 s/</&lt;/g;
457                 s/>/&gt;/g;
458                 if (s/^\s+o\s+/<li>/ && !$in_ul) {
459                         print "<ul>\n";
460                         $in_ul = 1;
461                 }
462                 s/CVE-(\d{4}-\d{4})/<a href=vulnerabilities.html#$1>CVE-$1<\/a>/g;
463         print;
464         }
465         
466 }
467 close(FP);
468 print "</ul>";
469 :>
470 <restore minversion>
471 <restore maxversion>
472 <restore filename>
473 </define-tag>
474
475 #
476 <define-tag newsflash>
477 <preserve from>
478 <preserve max>
479 <preserve more>
480 <set-var %attributes>
481 <table width=550 cellspacing=0 cellpadding=1 border=0>
482 <tr><td><font face="Arial,Helvetica"><b>Date</b></font></td> <td>&nbsp;&nbsp;&nbsp;<font face="Arial,Helvetica"><b>Newsflash</b></font></td></tr>
483 <tr><td><hr noshade size=1></td> <td><hr noshade size=1></td></tr>
484 <:
485     open(FP, "< <get-var from>") || die;
486     my $max = ("<get-var max>" eq '' ? 9999 : "<get-var max>");
487     @COL = (
488         '#ffffff',
489         '#f0f0f0',
490     );
491     $ncol = 1;
492     $n = 0;
493     while (<FP>) {
494         $ncol = ($ncol + 1) % 2;
495         $col  = $COL[$ncol];
496         s|="ROOT|="$(ROOT)|g;
497         if (m|^(.+?):(.+)|) {
498             print "<tr bgcolor=\"$col\">\n";
499             print "  <td align=right><font face=\"Arial,Helvetica\"><b>$1:</b></font></td> <td>&nbsp;&nbsp;$2</td>\n";
500             print "</tr>\n";
501         }
502         $n++;
503         last if ($n >= $max);
504     }
505     close(FP);
506 :>
507 <ifeq "<get-var more>" "" "" <group
508 <tr>
509   <td>&nbsp;</td> <td align=right><a href="<get-var more>">more...</a></td>
510 </tr>
511 >>
512 </table>
513 <restore more>
514 <restore max>
515 <restore from>
516 </define-tag>
517
518 #   define a <disclaimer> tag which displays the usual disclaimer stuff
519 <define-tag disclaimer>
520 <font face="Arial,Helvetica" size=-1>
521 This software package uses strong cryptography, so even if it is created,
522 maintained and distributed from liberal countries in Europe (where it is legal
523 to do this), it falls under certain export/import and/or use restrictions in
524 some other parts of the world.
525 <p>
526 PLEASE REMEMBER THAT EXPORT/IMPORT AND/OR USE OF STRONG CRYPTOGRAPHY
527 SOFTWARE, PROVIDING CRYPTOGRAPHY HOOKS OR EVEN JUST COMMUNICATING TECHNICAL
528 DETAILS ABOUT CRYPTOGRAPHY SOFTWARE IS ILLEGAL IN SOME PARTS OF THE WORLD.
529 SO, WHEN YOU IMPORT THIS PACKAGE TO YOUR COUNTRY, RE-DISTRIBUTE IT FROM
530 THERE OR EVEN JUST EMAIL TECHNICAL SUGGESTIONS OR EVEN SOURCE PATCHES TO THE
531 AUTHOR OR OTHER PEOPLE YOU ARE STRONGLY ADVISED TO PAY CLOSE ATTENTION TO
532 ANY EXPORT/IMPORT AND/OR USE LAWS WHICH APPLY TO YOU. THE AUTHORS OF OPENSSL
533 ARE NOT LIABLE FOR ANY VIOLATIONS YOU MAKE HERE. SO BE CAREFUL, IT
534 IS YOUR RESPONSIBILITY.
535 </font>
536 <p>
537 <font face="Arial,Helvetica" size=-1>
538 CREDIT INFORMATION:
539 This product includes cryptographic software written by Eric Young.  
540 This product includes software written by Tim Hudson (tjh@cryptsoft.com).
541 </font>
542 </define-tag>
543
544 #  a tag displaying the used tools   
545 <define-tag website-tools>
546 <font face="Arial,Helvetica" size=-1> 
547 Website designed by
548 <a href="http://www.engelschall.com/">Ralf S. Engelschall</a>
549 and generated with
550 <a href="http://thewml.org/"><font color="#000000">
551 Website META Language</font></a> (WML).<br>
552 All markup code and graphics on this website
553 are Copyright &copy; 1999-2014 <a href="http://www.openssl.org/">The OpenSSL Project</a>, 
554 All rights reserved.<br>
555 This website is served by an 
556 <a href="http://www.apache.org/"><font color="#000000">Apache</font></a>/
557 <a href="http://www.modssl.org/"><font color="#000000">mod_ssl</font></a>
558 webserver environment.<br>
559 </font>
560 </define-tag>
561
562 #  construct an absolute URL out of a relative URL
563 #  (essential for the mirroring of the website!)
564 <define-tag absolute>
565 <:{
566     my ($cwd, $baseurl, $basedir, $subdir, $page, $url);
567
568     #   determine current working directory
569     $cwd = '<get-var WML_SRC_DIRNAME>';
570
571     #   determine base URL
572     $baseurl = '<get-var BASE_URL>' || 'file://';
573
574     #   determine base directory
575     $basedir = '<get-var BASE_DIR>' || '<get-var WML_SRC_DIRNAME>';
576     $basedir = &canonpath("$cwd/$basedir") if ($basedir !~ m|^/|);
577
578     #   determine subdir from base dir to current working dir
579     $subdir = &relpath($basedir, $cwd);
580
581     #   determine document
582     $page = '%0';
583
584     #   construct final URL
585     $url = "$baseurl/$subdir/$page";
586     $url = &canonurl($url);
587
588     #   replace this tag with the constructed URL
589     print $url;
590 }:>
591 </define-tag>
592
593 ##
594 ##  Finally, the layout is now rendered, so divert all
595 ##  following stuff (the code in the local file after the #use 
596 ##  for this template!) into the white body area.
597 ##
598
599 ..PAGE_BODY>>
600