Make a virtual link to the latest source called latest.tar.gz
[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=about    url=about/   txt="About"        img=page-navbar-ab-*.jpg>
134   <navbar:button id=news     url=news/    txt="News"         img=page-navbar-ne-*.jpg>
135   <navbar:button id=FAQ      url=support/faq.html   txt="FAQ"          img=page-navbar-fq-*.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   #   button epilog
139   <navbar:epilog>
140     </td></tr>
141   </navbar:epilog>
142   #   bar footer
143   <navbar:footer>
144   </navbar:footer>
145 </navbar:define>
146
147 #   and then immediately render it into its layout location
148 #   (Hint: The top and buttom images have to be part of the table
149 #   structure because only this way we can put them 0pt to the
150 #   buttons without a gap)
151 ..PAGE_NAVBAR>>\
152   <table cellspacing=0 cellpadding=0 border=0>\
153     <tr><td><img src="$(IMG)/page-navbar-top.jpg"></td></tr>
154     #   render it!
155     <navbar:render name=navbar select=$(area) $(page:+subselected)>
156     <tr><td><img src="$(IMG)/page-navbar-bot.jpg"><br><p></td></tr>
157   </table>
158 <<..
159
160 ##
161 ##  The Sub Navigation Bar (SNB) [top, horizontally]
162 ##
163
164 #   define the <snb>...</snb> container tag
165 <define-tag snb endtag=required>
166   #   1. define the navigation bar through a grammar
167   <navbar:define name=snb urlbase="$(SNB_ROOT)"
168                  txtcol_normal="#666666" txtcol_select="#000000">
169     #   bar header
170     <navbar:header>\
171       <table cellspacing=0 cellpadding=0 border=0>
172         <tr>
173     </navbar:header>
174     #   button prolog (normal)
175     <navbar:prolog>\
176           <td><font face="Arial,Helvetica">&nbsp;
177     </navbar:prolog>
178     #   button prolog (selected)
179     <navbar:prolog type=S>\
180           <td bgcolor="#f0f0f0">&nbsp;<font face="Arial,Helvetica"><b>
181     </navbar:prolog>
182     #   ...here the <snb_button> tags will occur...
183     %body
184     #   button epilog (normal)
185     <navbar:epilog>\
186           </font>&nbsp;</td><td>|</td>
187     </navbar:epilog>
188     #   button epilog (selected)
189     <navbar:epilog type=S>\
190           </b></font>&nbsp;</td><td>|</td>
191     </navbar:epilog>
192     #   last button epilog (normal)
193     <navbar:epilog pos=last>\
194           </font>&nbsp;</td><td></td>
195     </navbar:epilog>
196     #   last button epilog (selected)
197     <navbar:epilog type=S pos=last>\
198           </b></font>&nbsp;</td><td></td>
199     </navbar:epilog>
200     #   bar footer
201     <navbar:footer>\
202         </tr>
203       </table>
204     </navbar:footer>
205   </navbar:define>
206   #   2. render the navigation bar and divert
207   #      divert it into it's final location
208   ..PAGE_SUBNAVBAR>>\
209   <navbar:render name=snb select="$(page)">\
210   <<..
211 </define-tag>
212
213 #   define the <snb_button> tag for the <snb> container
214 #   (this is for consistency with the tag names)
215 <define-tag snb_button>
216   <navbar:button %attributes>
217 </define-tag>
218
219 #   predefine the contents of the SNB location
220 #   by diverting a whitespace character to it.
221 #   This prevents the table to be folded.
222 ..PAGE_SUBNAVBAR!>>
223 &nbsp;
224 <<..
225
226 #   and now the final WML trick: When the page=<page_name>
227 #   attribute is specified for this template, we read in the SNB
228 #   spec-file which now can use the <snb>..</snb> and
229 #   <snb_button> tags to actually define and render a SNB. This
230 #   is accomplished by doing some sort of a conditional #include. ;-)
231 $(page:*# )$(page:+#include ")$(SNB_RC:-.wmlsnb)$(page:+")
232
233 ##
234 ##  Useful tags (for convenience purposes only)
235 ##
236
237 #   define a <item> tag for <ul>/<ol> item similar to <li> but
238 #   which is nice for URL lists like the Related area where
239 #   we want a special layout.
240 <define-tag item>
241 <preserve name>
242 <preserve url>
243 <preserve aio>
244 <preserve info>
245 <set-var aio=*>
246 <set-var %attributes>
247 <li><imgdot width=1 height=18>\
248     <a href="<get-var url>"><font size=+1 face="Arial,Helvetica"><b><get-var name></b></font></a>
249     <ifeq "<get-var aio>" "" <img src="aio.gif" alt="[all-in-one]" align=absmiddle>>
250     <br>
251     <a href="<get-var url>"><font size=-1><get-var url></font></a><br>
252     <ifeq "<get-var info>" "" "" "<get-var info>">
253 <restore info>
254 <restore aio>
255 <restore url>
256 <restore name>
257 </define-tag>
258
259 #   define a <filelist> tag which can be used to create a file listing which
260 #   is optically more compact than the stuff Apache's mod_autoindex creates.
261 #   Especially the current version is marked red, too.
262 <define-tag filelist>
263 <pre>
264 <b>   Bytes      Timestamp       Filename</b>
265 <b>________ ____________________ ____________________________</b>
266 <:
267 @HI = ();
268 open(FP, "<index.current");
269 while (<FP>) {
270    s|\s*\n$||;
271    push(@HI, $_);
272 }
273 close(FP);
274 sub ls {
275     my ($pat) = @_;
276     my (@F, @R, $f, @S, @T);
277     @F = sort { (stat($a))[9] <=> (stat($b))[9]; } (glob($pat));
278     @R = ();
279     foreach $f (@F) {
280         next if ($f =~ m|^index.*|);
281         if ('%1' ne '') {
282             if (! %1 $f) {
283                 next;
284             }
285         }
286         @S = stat($f);
287         $f = "$f/" if (-d $f);
288         @T = localtime($S[9]);
289         my @moy = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
290                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
291         push(@R, sprintf("%"."8d %"."s %"."2d %"."02d:%"."02d:%"."02d %"."d %"."s\n",
292              $S[7], $moy[$T[4]], $T[3], $T[2], $T[1], $T[0], 1900+$T[5], $f));
293     }
294     return @R;
295 }
296 @L = &ls("%0");
297 foreach $l (@L) {
298     next if ($l =~ m|^\s*$|);
299     $l =~ s|(\s+)(\S+[^/])(\s*\n)$|$1."<a href=\"$2\">$2</a>".$3|e;
300     $l =~ s|(\s+)(\S+/)(\s*\n)$|$1."<a href=\"$2\"><b>$2</b></a>".$3|e;
301     foreach $hi (@HI) {
302         $l =~ s|^(.*$hi.*)$|<font color="#cc3333">$1&nbsp;&nbsp;<b>[LATEST]</b></font>|;
303         $l =~ s|>($hi)<|><font color="#cc3333">$1</font><|;
304     }
305     print $l;
306 }
307 :>
308 </pre>
309 </define-tag>
310
311 <define-tag rfilelist>
312 <pre>
313 <b>   Bytes      Timestamp       Filename</b>
314 <b>________ ____________________ ____________________________</b>
315 <:
316 @HI = ();
317 open(FP, "<index.current");
318 while (<FP>) {
319    s|\s*\n$||;
320    s/#.*$//;
321    next if (/^\s*$/);
322    # If line is of form "last <regex>" look for last
323    # matching filename in the list.
324    # This means "last openssl-1*.tar.gz" will automatically
325    # mark the last version of OpenSSL as the latest without
326    # the need to manually update index.current on each release.
327    if (/^\s*last\s*(\S+)\s*$/) {
328         # Get list of all file, skip betas
329         my @list = sort grep(!/beta/, glob($1));
330         my $lastfile = pop @list;
331         push(@HI, $lastfile) if (-f $lastfile);
332    } elsif (-f $_) {
333         push(@HI, $_);
334    }
335 }
336 close(FP);
337 sub ls {
338     my ($pat) = @_;
339     my (@F, @R, $f, @S, @T);
340     @F = sort { (stat($b))[9] <=> (stat($a))[9]; } (glob($pat));
341     @R = ();
342     foreach $f (@F) {
343         next if ($f =~ m|^index.*|);
344         if ('%1' ne '') {
345             if (! %1 $f) {
346                 next;
347             }
348         }
349         @S = stat($f);
350         $f = "$f/" if (-d $f);
351         @T = localtime($S[9]);
352         my @moy = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
353                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
354         push(@R, sprintf("%"."8d %"."s %"."2d %"."02d:%"."02d:%"."02d %"."d %"."s\n",
355              $S[7], $moy[$T[4]], $T[3], $T[2], $T[1], $T[0], 1900+$T[5], $f));
356     }
357     return @R;
358 }
359 @L = &ls("%0");
360 foreach $l (@L) {
361     next if ($l =~ m|^\s*$|);
362     if ($l =~ m|(\s+)(\S+[^/])(\s*\n)$|) {
363         my $h = $`.$1;
364         my $f = $2;
365         my $t = $3;
366         my $r = "<a href=\"$f\">$f</a>";
367         if (-f "$f.md5") { $r .= " (<a href=\"$f.md5\">MD5</a>)"; }
368         if (-f "$f.sha1") { $r .= " (<a href=\"$f.sha1\">SHA1</a>)"; }
369         if (-f "$f.asc") { $r .= " (<a href=\"$f.asc\">PGP sign</a>)"; }
370         $l = $h.$r.$t;
371     }
372     $l =~ s|(\s+)(\S+/)(\s*\n)$|$1."<a href=\"$2\"><b>$2</b></a>".$3|e;
373     foreach $hi (@HI) {
374         $l =~ s|^(.*$hi.*)$|<font color="#cc3333">$1&nbsp;&nbsp;<b>[LATEST]</b></font>|;
375         $l =~ s|>($hi)<|><font color="#cc3333"><span class="latest">$1</span></font><|;
376     }
377     print $l;
378 }
379 :>
380 </pre>
381 </define-tag>
382
383 <define-tag notes>
384 <preserve minversion>
385 <preserve maxversion>
386 <preserve filename>
387 <set-var %attributes>
388 <:
389
390 my $minversion = "<get-var minversion>";
391 my $maxversion = "<get-var maxversion>";
392 my $dirname = "<get-var dirname>";
393 my $file;
394 my $custompage = 0;
395
396 if ($maxversion eq "") {
397         $minversion="<get-var WML_SRC_FILENAME>";
398         $minversion =~ s/^.*-(\d+\.\d+\.\d+)-.*$/$1/;
399         $maxversion = $minversion;
400 } else {
401         $custompage = 1;
402 }
403
404
405 my $dir = defined $ENV{PODSHOME} ? "$ENV{PODSHOME}/../.." : "/var/cache/openssl/checkouts";
406 if ($dirname ne "") {
407         $file = "${dir}/$dirname/NEWS";
408         $custompage = 1;
409 } else {
410         $file = "${dir}/openssl-${minversion}-stable/NEWS";
411 }
412 # For testing
413 $file = $ENV{NEWSTEST} if defined $ENV{NEWSTEST};
414 if ($custompage == 0) {
415         my $brname = $minversion;
416         $brname =~ tr/./_/;
417         $brname = "OpenSSL_${brname}-stable";
418         print <<"END"
419 <title>OpenSSL $minversion Release Notes.</title>
420 <h1>OpenSSL $minversion Branch Release notes</h1>
421
422 The major changes and known issues for the $minversion branch of the OpenSSL
423 toolkit are summarised below. The contents reflect the current state of the
424 <tt>NEWS</tt> file inside the git repository.
425 <p>
426 Additional details of changes can be found in the
427 <a href="https://github.com/openssl/openssl/blob/$brname/CHANGES">
428 change log.</a>.
429 <p>
430 The complete list of changes can be found in the
431 <a href="https://github.com/openssl/openssl/commits/$brname">commit log</a>.
432 <p>
433
434 END
435 }
436
437 my $copy = 0;
438 my $in_ul = 0;
439 open(FP, "<$file") || die "Can't open $file";
440 while (<FP>) {
441         if (/^\s*Major changes between.*(\d+\.\d+\.\d+)\D.*$/ ||
442                 /^\s*Known issues in.*(\d+\.\d+\.\d+)\D.*$/) {
443                 if ($1 ge $minversion && $1 le $maxversion) {
444                         $copy = 1;
445                         s|^(.*)$|<b>$1</b>|;
446                         if ($in_ul) {
447                                 print "</ul>\n";
448                                 $in_ul = 0;
449                         }
450                 print;
451                 next;
452                 } elsif ($copy) {
453                         last;
454                 }
455         }
456         if ($copy) {
457                 s/&/&amp;/g;
458                 s/</&lt;/g;
459                 s/>/&gt;/g;
460                 if (s/^\s+o\s+/<li>/ && !$in_ul) {
461                         print "<ul>\n";
462                         $in_ul = 1;
463                 }
464                 s/CVE-(\d{4}-\d{4})/<a href=vulnerabilities.html#$1>CVE-$1<\/a>/g;
465         print;
466         }
467         
468 }
469 close(FP);
470 print "</ul>";
471 :>
472 <restore minversion>
473 <restore maxversion>
474 <restore filename>
475 </define-tag>
476
477 #
478 <define-tag newsflash>
479 <preserve from>
480 <preserve max>
481 <preserve more>
482 <set-var %attributes>
483 <table width=550 cellspacing=0 cellpadding=1 border=0>
484 <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>
485 <tr><td><hr noshade size=1></td> <td><hr noshade size=1></td></tr>
486 <:
487     open(FP, "< <get-var from>") || die;
488     my $max = ("<get-var max>" eq '' ? 9999 : "<get-var max>");
489     @COL = (
490         '#ffffff',
491         '#f0f0f0',
492     );
493     $ncol = 1;
494     $n = 0;
495     while (<FP>) {
496         $ncol = ($ncol + 1) % 2;
497         $col  = $COL[$ncol];
498         s|="ROOT|="$(ROOT)|g;
499         if (m|^(.+?):(.+)|) {
500             print "<tr bgcolor=\"$col\">\n";
501             print "  <td align=right><font face=\"Arial,Helvetica\"><b>$1:</b></font></td> <td>&nbsp;&nbsp;$2</td>\n";
502             print "</tr>\n";
503         }
504         $n++;
505         last if ($n >= $max);
506     }
507     close(FP);
508 :>
509 <ifeq "<get-var more>" "" "" <group
510 <tr>
511   <td>&nbsp;</td> <td align=right><a href="<get-var more>">more...</a></td>
512 </tr>
513 >>
514 </table>
515 <restore more>
516 <restore max>
517 <restore from>
518 </define-tag>
519
520 #   define a <disclaimer> tag which displays the usual disclaimer stuff
521 <define-tag disclaimer>
522 <font face="Arial,Helvetica" size=-1>
523 This software package uses strong cryptography, so even if it is created,
524 maintained and distributed from liberal countries in Europe (where it is legal
525 to do this), it falls under certain export/import and/or use restrictions in
526 some other parts of the world.
527 <p>
528 PLEASE REMEMBER THAT EXPORT/IMPORT AND/OR USE OF STRONG CRYPTOGRAPHY
529 SOFTWARE, PROVIDING CRYPTOGRAPHY HOOKS OR EVEN JUST COMMUNICATING TECHNICAL
530 DETAILS ABOUT CRYPTOGRAPHY SOFTWARE IS ILLEGAL IN SOME PARTS OF THE WORLD.
531 SO, WHEN YOU IMPORT THIS PACKAGE TO YOUR COUNTRY, RE-DISTRIBUTE IT FROM
532 THERE OR EVEN JUST EMAIL TECHNICAL SUGGESTIONS OR EVEN SOURCE PATCHES TO THE
533 AUTHOR OR OTHER PEOPLE YOU ARE STRONGLY ADVISED TO PAY CLOSE ATTENTION TO
534 ANY EXPORT/IMPORT AND/OR USE LAWS WHICH APPLY TO YOU. THE AUTHORS OF OPENSSL
535 ARE NOT LIABLE FOR ANY VIOLATIONS YOU MAKE HERE. SO BE CAREFUL, IT
536 IS YOUR RESPONSIBILITY.
537 </font>
538 <p>
539 <font face="Arial,Helvetica" size=-1>
540 CREDIT INFORMATION:
541 This product includes cryptographic software written by Eric Young.
542 This product includes software written by Tim Hudson (tjh@cryptsoft.com).
543 </font>
544 </define-tag>
545
546 #  a tag displaying the used tools
547 <define-tag website-tools>
548 <font face="Arial,Helvetica" size=-1>
549 Website designed by
550 <a href="http://www.engelschall.com/">Ralf S. Engelschall</a>
551 and generated with
552 <a href="http://thewml.org/"><font color="#000000">
553 Website META Language</font></a> (WML).<br>
554 All markup code and graphics on this website
555 are Copyright &copy; 1999-2014 <a href="http://www.openssl.org/">The OpenSSL Project</a>,
556 All rights reserved.<br>
557 This website is served by an
558 <a href="http://www.apache.org/"><font color="#000000">Apache</font></a>/
559 <a href="http://www.modssl.org/"><font color="#000000">mod_ssl</font></a>
560 webserver environment.<br>
561 </font>
562 </define-tag>
563
564 #  construct an absolute URL out of a relative URL
565 #  (essential for the mirroring of the website!)
566 <define-tag absolute>
567 <:{
568     my ($cwd, $baseurl, $basedir, $subdir, $page, $url);
569
570     #   determine current working directory
571     $cwd = '<get-var WML_SRC_DIRNAME>';
572
573     #   determine base URL
574     $baseurl = '<get-var BASE_URL>' || 'file://';
575
576     #   determine base directory
577     $basedir = '<get-var BASE_DIR>' || '<get-var WML_SRC_DIRNAME>';
578     $basedir = &canonpath("$cwd/$basedir") if ($basedir !~ m|^/|);
579
580     #   determine subdir from base dir to current working dir
581     $subdir = &relpath($basedir, $cwd);
582
583     #   determine document
584     $page = '%0';
585
586     #   construct final URL
587     $url = "$baseurl/$subdir/$page";
588     $url = &canonurl($url);
589
590     #   replace this tag with the constructed URL
591     print $url;
592 }:>
593 </define-tag>
594
595 ##
596 ##  Finally, the layout is now rendered, so divert all
597 ##  following stuff (the code in the local file after the #use
598 ##  for this template!) into the white body area.
599 ##
600
601 ..PAGE_BODY>>
602