[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> template.php (source)

   1  <?php
   2  /**
   3   * DokuWiki template functions
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Andreas Gohr <andi@splitbrain.org>
   7   */
   8  
   9  if(!defined('DOKU_INC')) die('meh.');
  10  
  11  /**
  12   * Returns the path to the given template, uses
  13   * default one if the custom version doesn't exist.
  14   *
  15   * @author Andreas Gohr <andi@splitbrain.org>
  16   */
  17  function template($tpl){
  18    global $conf;
  19  
  20    if(@is_readable(DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$tpl))
  21      return DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$tpl;
  22  
  23    return DOKU_INC.'lib/tpl/default/'.$tpl;
  24  }
  25  
  26  /**
  27   * Print the content
  28   *
  29   * This function is used for printing all the usual content
  30   * (defined by the global $ACT var) by calling the appropriate
  31   * outputfunction(s) from html.php
  32   *
  33   * Everything that doesn't use the main template file isn't
  34   * handled by this function. ACL stuff is not done here either.
  35   *
  36   * @author Andreas Gohr <andi@splitbrain.org>
  37   */
  38  function tpl_content($prependTOC=true) {
  39      global $ACT;
  40      global $INFO;
  41      $INFO['prependTOC'] = $prependTOC;
  42  
  43      ob_start();
  44      trigger_event('TPL_ACT_RENDER',$ACT,'tpl_content_core');
  45      $html_output = ob_get_clean();
  46      trigger_event('TPL_CONTENT_DISPLAY',$html_output,'ptln');
  47  
  48      return !empty($html_output);
  49  }
  50  
  51  function tpl_content_core(){
  52    global $ACT;
  53    global $TEXT;
  54    global $PRE;
  55    global $SUF;
  56    global $SUM;
  57    global $IDX;
  58  
  59    switch($ACT){
  60      case 'show':
  61        html_show();
  62        break;
  63      case 'preview':
  64        html_edit($TEXT);
  65        html_show($TEXT);
  66        break;
  67      case 'recover':
  68        html_edit($TEXT);
  69        break;
  70      case 'edit':
  71        html_edit();
  72        break;
  73      case 'draft':
  74        html_draft();
  75        break;
  76      case 'wordblock':
  77        html_edit($TEXT,'wordblock');
  78        break;
  79      case 'search':
  80        html_search();
  81        break;
  82      case 'revisions':
  83        $first = is_numeric($_REQUEST['first']) ? intval($_REQUEST['first']) : 0;
  84        html_revisions($first);
  85        break;
  86      case 'diff':
  87        html_diff();
  88        break;
  89      case 'recent':
  90        if (is_array($_REQUEST['first'])) {
  91          $_REQUEST['first'] = array_keys($_REQUEST['first']);
  92          $_REQUEST['first'] = $_REQUEST['first'][0];
  93        }
  94        $first = is_numeric($_REQUEST['first']) ? intval($_REQUEST['first']) : 0;
  95        html_recent($first);
  96        break;
  97      case 'index':
  98        html_index($IDX); #FIXME can this be pulled from globals? is it sanitized correctly?
  99        break;
 100      case 'backlink':
 101        html_backlinks();
 102        break;
 103      case 'conflict':
 104        html_conflict(con($PRE,$TEXT,$SUF),$SUM);
 105        html_diff(con($PRE,$TEXT,$SUF),false);
 106        break;
 107      case 'locked':
 108        html_locked();
 109        html_edit();
 110        break;
 111      case 'login':
 112        html_login();
 113        break;
 114      case 'register':
 115        html_register();
 116        break;
 117      case 'resendpwd':
 118        html_resendpwd();
 119        break;
 120      case 'denied':
 121        print p_locale_xhtml('denied');
 122        break;
 123      case 'profile' :
 124        html_updateprofile();
 125        break;
 126      case 'admin':
 127        tpl_admin();
 128        break;
 129      default:
 130        $evt = new Doku_Event('TPL_ACT_UNKNOWN',$ACT);
 131        if ($evt->advise_before())
 132          msg("Failed to handle command: ".hsc($ACT),-1);
 133        $evt->advise_after();
 134        unset($evt);
 135        return false;
 136    }
 137    return true;
 138  }
 139  
 140  /**
 141   * Places the TOC where the function is called
 142   *
 143   * If you use this you most probably want to call tpl_content with
 144   * a false argument
 145   *
 146   * @author Andreas Gohr <andi@splitbrain.org>
 147   */
 148  function tpl_toc($return=false){
 149      global $TOC;
 150      global $ACT;
 151      global $ID;
 152      global $REV;
 153      global $INFO;
 154      global $conf;
 155      $toc = array();
 156  
 157      if(is_array($TOC)){
 158          // if a TOC was prepared in global scope, always use it
 159          $toc = $TOC;
 160      }elseif(($ACT == 'show' || substr($ACT,0,6) == 'export') && !$REV && $INFO['exists']){
 161          // get TOC from metadata, render if neccessary
 162          $meta = p_get_metadata($ID, false, true);
 163          if(isset($meta['internal']['toc'])){
 164              $tocok = $meta['internal']['toc'];
 165          }else{
 166              $tocok = true;
 167          }
 168          $toc   = $meta['description']['tableofcontents'];
 169          if(!$tocok || !is_array($toc) || !$conf['tocminheads'] || count($toc) < $conf['tocminheads']){
 170              $toc = array();
 171          }
 172      }elseif($ACT == 'admin'){
 173          // try to load admin plugin TOC FIXME: duplicates code from tpl_admin
 174          $plugin = null;
 175          if (!empty($_REQUEST['page'])) {
 176              $pluginlist = plugin_list('admin');
 177              if (in_array($_REQUEST['page'], $pluginlist)) {
 178                  // attempt to load the plugin
 179                  $plugin =& plugin_load('admin',$_REQUEST['page']);
 180              }
 181          }
 182          if ( ($plugin !== null) &&
 183               (!$plugin->forAdminOnly() || $INFO['isadmin']) ){
 184              $toc = $plugin->getTOC();
 185              $TOC = $toc; // avoid later rebuild
 186          }
 187      }
 188  
 189      trigger_event('TPL_TOC_RENDER', $toc, NULL, false);
 190      $html = html_TOC($toc);
 191      if($return) return $html;
 192      echo $html;
 193  }
 194  
 195  /**
 196   * Handle the admin page contents
 197   *
 198   * @author Andreas Gohr <andi@splitbrain.org>
 199   */
 200  function tpl_admin(){
 201      global $INFO;
 202      global $TOC;
 203  
 204      $plugin = null;
 205      if (!empty($_REQUEST['page'])) {
 206          $pluginlist = plugin_list('admin');
 207  
 208          if (in_array($_REQUEST['page'], $pluginlist)) {
 209  
 210            // attempt to load the plugin
 211            $plugin =& plugin_load('admin',$_REQUEST['page']);
 212          }
 213      }
 214  
 215      if ($plugin !== null){
 216          if($plugin->forAdminOnly() && !$INFO['isadmin']){
 217              msg('For admins only',-1);
 218              html_admin();
 219          }else{
 220              if(!is_array($TOC)) $TOC = $plugin->getTOC(); //if TOC wasn't requested yet
 221              if($INFO['prependTOC']) tpl_toc();
 222              $plugin->html();
 223          }
 224      }else{
 225          html_admin();
 226      }
 227      return true;
 228  }
 229  
 230  /**
 231   * Print the correct HTML meta headers
 232   *
 233   * This has to go into the head section of your template.
 234   *
 235   * @triggers TPL_METAHEADER_OUTPUT
 236   * @param  boolean $alt Should feeds and alternative format links be added?
 237   * @author Andreas Gohr <andi@splitbrain.org>
 238   */
 239  function tpl_metaheaders($alt=true){
 240    global $ID;
 241    global $REV;
 242    global $INFO;
 243    global $ACT;
 244    global $QUERY;
 245    global $lang;
 246    global $conf;
 247    $it=2;
 248  
 249    // prepare the head array
 250    $head = array();
 251  
 252  
 253    // the usual stuff
 254    $head['meta'][] = array( 'name'=>'generator', 'content'=>'DokuWiki '.getVersion() );
 255    $head['link'][] = array( 'rel'=>'search', 'type'=>'application/opensearchdescription+xml',
 256                             'href'=>DOKU_BASE.'lib/exe/opensearch.php', 'title'=>$conf['title'] );
 257    $head['link'][] = array( 'rel'=>'start', 'href'=>DOKU_BASE );
 258    if(actionOK('index')){
 259      $head['link'][] = array( 'rel'=>'contents', 'href'=> wl($ID,'do=index',false,'&'),
 260                             'title'=>$lang['btn_index'] );
 261    }
 262  
 263    if($alt){
 264      $head['link'][] = array( 'rel'=>'alternate', 'type'=>'application/rss+xml',
 265                               'title'=>'Recent Changes', 'href'=>DOKU_BASE.'feed.php');
 266      $head['link'][] = array( 'rel'=>'alternate', 'type'=>'application/rss+xml',
 267                               'title'=>'Current Namespace',
 268                               'href'=>DOKU_BASE.'feed.php?mode=list&ns='.$INFO['namespace']);
 269      if(($ACT == 'show' || $ACT == 'search') && $INFO['writable']){
 270          $head['link'][] = array( 'rel'=>'alternate', 'type'=>'application/wiki',
 271                                   'title'=>$lang['btn_edit'],
 272                                   'href'=> wl($ID,'do=edit',false,'&'));
 273      }
 274  
 275      if($ACT == 'search'){
 276        $head['link'][] = array( 'rel'=>'alternate', 'type'=>'application/rss+xml',
 277                                 'title'=>'Search Result',
 278                                 'href'=>DOKU_BASE.'feed.php?mode=search&q='.$QUERY);
 279      }
 280  
 281      if(actionOK('export_xhtml')){
 282        $head['link'][] = array( 'rel'=>'alternate', 'type'=>'text/html', 'title'=>'Plain HTML',
 283                                 'href'=>exportlink($ID, 'xhtml', '', false, '&'));
 284      }
 285  
 286      if(actionOK('export_raw')){
 287        $head['link'][] = array( 'rel'=>'alternate', 'type'=>'text/plain', 'title'=>'Wiki Markup',
 288                                 'href'=>exportlink($ID, 'raw', '', false, '&'));
 289      }
 290    }
 291  
 292    // setup robot tags apropriate for different modes
 293    if( ($ACT=='show' || $ACT=='export_xhtml') && !$REV){
 294      if($INFO['exists']){
 295        //delay indexing:
 296        if((time() - $INFO['lastmod']) >= $conf['indexdelay']){
 297          $head['meta'][] = array( 'name'=>'robots', 'content'=>'index,follow');
 298        }else{
 299          $head['meta'][] = array( 'name'=>'robots', 'content'=>'noindex,nofollow');
 300        }
 301      }else{
 302        $head['meta'][] = array( 'name'=>'robots', 'content'=>'noindex,follow');
 303      }
 304    }elseif(defined('DOKU_MEDIADETAIL')){
 305      $head['meta'][] = array( 'name'=>'robots', 'content'=>'index,follow');
 306    }else{
 307      $head['meta'][] = array( 'name'=>'robots', 'content'=>'noindex,nofollow');
 308    }
 309  
 310    // set metadata
 311    if($ACT == 'show' || $ACT=='export_xhtml'){
 312      // date of modification
 313      if($REV){
 314        $head['meta'][] = array( 'name'=>'date', 'content'=>date('Y-m-d\TH:i:sO',$REV));
 315      }else{
 316        $head['meta'][] = array( 'name'=>'date', 'content'=>date('Y-m-d\TH:i:sO',$INFO['lastmod']));
 317      }
 318  
 319      // keywords (explicit or implicit)
 320      if(!empty($INFO['meta']['subject'])){
 321        $head['meta'][] = array( 'name'=>'keywords', 'content'=>join(',',$INFO['meta']['subject']));
 322      }else{
 323        $head['meta'][] = array( 'name'=>'keywords', 'content'=>str_replace(':',',',$ID));
 324      }
 325    }
 326  
 327    // load stylesheets
 328    $head['link'][] = array('rel'=>'stylesheet', 'media'=>'all', 'type'=>'text/css',
 329                            'href'=>DOKU_BASE.'lib/exe/css.php?s=all&t='.$conf['template']);
 330    $head['link'][] = array('rel'=>'stylesheet', 'media'=>'screen', 'type'=>'text/css',
 331                            'href'=>DOKU_BASE.'lib/exe/css.php?t='.$conf['template']);
 332    $head['link'][] = array('rel'=>'stylesheet', 'media'=>'print', 'type'=>'text/css',
 333                            'href'=>DOKU_BASE.'lib/exe/css.php?s=print&t='.$conf['template']);
 334  
 335    // load javascript
 336    $js_edit  = ($ACT=='edit' || $ACT=='preview' || $ACT=='recover' || $ACT=='wordblock' ) ? 1 : 0;
 337    $js_write = ($INFO['writable']) ? 1 : 0;
 338    if(defined('DOKU_MEDIAMANAGER')){
 339      $js_edit  = 1;
 340      $js_write = 0;
 341    }
 342    if(($js_edit && $js_write) || defined('DOKU_MEDIAMANAGER')){
 343      $script = "NS='".$INFO['namespace']."';";
 344      if($conf['useacl'] && $_SERVER['REMOTE_USER']){
 345        require_once (DOKU_INC.'inc/toolbar.php');
 346        $script .= "SIG='".toolbar_signature()."';";
 347      }
 348      $head['script'][] = array( 'type'=>'text/javascript', 'charset'=>'utf-8',
 349                                 '_data'=> $script);
 350    }
 351    $head['script'][] = array( 'type'=>'text/javascript', 'charset'=>'utf-8', '_data'=>'',
 352                               'src'=>DOKU_BASE.'lib/exe/js.php?edit='.$js_edit.'&write='.$js_write);
 353  
 354    // trigger event here
 355    trigger_event('TPL_METAHEADER_OUTPUT',$head,'_tpl_metaheaders_action',true);
 356    return true;
 357  }
 358  
 359  /**
 360   * prints the array build by tpl_metaheaders
 361   *
 362   * $data is an array of different header tags. Each tag can have multiple
 363   * instances. Attributes are given as key value pairs. Values will be HTML
 364   * encoded automatically so they should be provided as is in the $data array.
 365   *
 366   * For tags having a body attribute specify the the body data in the special
 367   * attribute '_data'. This field will NOT BE ESCAPED automatically.
 368   *
 369   * @author Andreas Gohr <andi@splitbrain.org>
 370   */
 371  function _tpl_metaheaders_action($data){
 372    foreach($data as $tag => $inst){
 373      foreach($inst as $attr){
 374        echo '<',$tag,' ',buildAttributes($attr);
 375        if(isset($attr['_data'])){
 376            if($tag == 'script' && $attr['_data'])
 377              $attr['_data'] = "<!--//--><![CDATA[//><!--\n".
 378                               $attr['_data'].
 379                               "\n//--><!]]>";
 380  
 381            echo '>',$attr['_data'],'</',$tag,'>';
 382        }else{
 383          echo '/>';
 384        }
 385        echo "\n";
 386      }
 387    }
 388  }
 389  
 390  /**
 391   * Print a link
 392   *
 393   * Just builds a link.
 394   *
 395   * @author Andreas Gohr <andi@splitbrain.org>
 396   */
 397  function tpl_link($url,$name,$more=''){
 398    print '<a href="'.$url.'" ';
 399    if ($more) print ' '.$more;
 400    print ">$name</a>";
 401    return true;
 402  }
 403  
 404  /**
 405   * Prints a link to a WikiPage
 406   *
 407   * Wrapper around html_wikilink
 408   *
 409   * @author Andreas Gohr <andi@splitbrain.org>
 410   */
 411  function tpl_pagelink($id,$name=NULL){
 412    print html_wikilink($id,$name);
 413    return true;
 414  }
 415  
 416  /**
 417   * get the parent page
 418   *
 419   * Tries to find out which page is parent.
 420   * returns false if none is available
 421   *
 422   * @author Andreas Gohr <andi@splitbrain.org>
 423   */
 424  function tpl_getparent($id){
 425    global $conf;
 426    $parent = getNS($id).':';
 427    resolve_pageid('',$parent,$exists);
 428    if($parent == $id) {
 429      $pos = strrpos (getNS($id),':');
 430      $parent = substr($parent,0,$pos).':';
 431      resolve_pageid('',$parent,$exists);
 432      if($parent == $id) return false;
 433    }
 434    return $parent;
 435  }
 436  
 437  /**
 438   * Print one of the buttons
 439   *
 440   * Available Buttons are
 441   *
 442   *  edit        - edit/create/show/draft button
 443   *  history     - old revisions
 444   *  recent      - recent changes
 445   *  login       - login/logout button - if ACL enabled
 446   *  profile     - user profile button (if logged in)
 447   *  index       - The index
 448   *  admin       - admin page - if enough rights
 449   *  top         - a back to top button
 450   *  back        - a back to parent button - if available
 451   *  backlink    - links to the list of backlinks
 452   *  subscription- subscribe/unsubscribe button
 453   *
 454   * @author Andreas Gohr <andi@splitbrain.org>
 455   * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 456   */
 457  function tpl_button($type){
 458    global $ACT;
 459    global $ID;
 460    global $REV;
 461    global $NS;
 462    global $INFO;
 463    global $conf;
 464    global $auth;
 465  
 466    // check disabled actions and fix the badly named ones
 467    $ctype = $type;
 468    if($type == 'history') $ctype='revisions';
 469    if(!actionOK($ctype)) return false;
 470  
 471    switch($type){
 472      case 'edit':
 473        #most complicated type - we need to decide on current action
 474        if($ACT == 'show' || $ACT == 'search'){
 475          if($INFO['writable']){
 476            if(!empty($INFO['draft'])){
 477              echo html_btn('draft',$ID,'e',array('do' => 'draft'),'post');
 478            }else{
 479              if($INFO['exists']){
 480                echo html_btn('edit',$ID,'e',array('do' => 'edit','rev' => $REV),'post');
 481              }else{
 482                echo html_btn('create',$ID,'e',array('do' => 'edit','rev' => $REV),'post');
 483              }
 484            }
 485          }else{
 486            if(!actionOK('source')) return false; //pseudo action
 487            echo html_btn('source',$ID,'v',array('do' => 'edit','rev' => $REV),'post');
 488          }
 489        }else{
 490            echo html_btn('show',$ID,'v',array('do' => 'show'));
 491        }
 492        return true;
 493      case 'history':
 494        if(!actionOK('revisions'))
 495          return false;
 496        print html_btn('revs',$ID,'o',array('do' => 'revisions'));
 497        return true;
 498      case 'recent':
 499        if(!actionOK('recent'))
 500          return false;
 501        print html_btn('recent',$ID,'r',array('do' => 'recent'));
 502        return true;
 503      case 'index':
 504        if(!actionOK('index'))
 505          return false;
 506        print html_btn('index',$ID,'x',array('do' => 'index'));
 507        return true;
 508      case 'back':
 509        if ($parent = tpl_getparent($ID)) {
 510          print html_btn('back',$parent,'b',array('do' => 'show'));
 511          return true;
 512        }
 513        return false;
 514      case 'top':
 515        print html_topbtn();
 516        return true;
 517      case 'login':
 518        if($conf['useacl'] && $auth){
 519          if($_SERVER['REMOTE_USER']){
 520            print html_btn('logout',$ID,'',array('do' => 'logout', 'sectok' => getSecurityToken()));
 521          }else{
 522            print html_btn('login',$ID,'',array('do' => 'login', 'sectok' => getSecurityToken()));
 523          }
 524          return true;
 525        }
 526        return false;
 527      case 'admin':
 528        if($INFO['ismanager']){
 529          print html_btn('admin',$ID,'',array('do' => 'admin'));
 530          return true;
 531        }
 532        return false;
 533      case 'subscribe':
 534      case 'subscription':
 535        if($conf['useacl'] && $auth && $ACT == 'show' && $conf['subscribers'] == 1){
 536          if($_SERVER['REMOTE_USER']){
 537            if($INFO['subscribed']){
 538              if(!actionOK('unsubscribe'))
 539                return false;
 540              print html_btn('unsubscribe',$ID,'',array('do' => 'unsubscribe',));
 541            } else {
 542              if(!actionOK('subscribe'))
 543                return false;
 544              print html_btn('subscribe',$ID,'',array('do' => 'subscribe',));
 545            }
 546            if($type == 'subscribe') return true;
 547          }
 548        }
 549        if($type == 'subscribe') return false;
 550        // fall through for backward compatibility
 551      case 'subscribens':
 552        if($conf['useacl'] && $auth && $ACT == 'show' && $conf['subscribers'] == 1){
 553          if($_SERVER['REMOTE_USER']){
 554            if($INFO['subscribedns']){
 555              if(!actionOK('unsubscribens'))
 556                return false;
 557              print html_btn('unsubscribens',$ID,'',array('do' => 'unsubscribens',));
 558            } else {
 559              if(!actionOK('subscribens'))
 560                return false;
 561              print html_btn('subscribens',$ID,'',array('do' => 'subscribens',));
 562            }
 563            return true;
 564          }
 565        }
 566        return false;
 567      case 'backlink':
 568        if(!actionOK('backlink'))
 569          return false;
 570        print html_btn('backlink',$ID,'',array('do' => 'backlink'));
 571        return true;
 572      case 'profile':
 573        if($conf['useacl'] && $_SERVER['REMOTE_USER'] && $auth &&
 574           $auth->canDo('Profile') && ($ACT!='profile')){
 575          print html_btn('profile',$ID,'',array('do' => 'profile'));
 576          return true;
 577        }
 578        return false;
 579      default:
 580        print '[unknown button type]';
 581        return true;
 582    }
 583  }
 584  
 585  /**
 586   * Like the action buttons but links
 587   *
 588   * Available links are
 589   *
 590   *  edit    - edit/create/show link
 591   *  history - old revisions
 592   *  recent  - recent changes
 593   *  login   - login/logout link - if ACL enabled
 594   *  profile - user profile link (if logged in)
 595   *  index   - The index
 596   *  admin   - admin page - if enough rights
 597   *  top     - a back to top link
 598   *  back    - a back to parent link - if available
 599   *  backlink - links to the list of backlinks
 600   *  subscribe/subscription - subscribe/unsubscribe link
 601   *
 602   * @author Andreas Gohr <andi@splitbrain.org>
 603   * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 604   * @see    tpl_button
 605   */
 606  function tpl_actionlink($type,$pre='',$suf='',$inner=''){
 607    global $ID;
 608    global $INFO;
 609    global $REV;
 610    global $ACT;
 611    global $conf;
 612    global $lang;
 613    global $auth;
 614  
 615    // check disabled actions and fix the badly named ones
 616    $ctype = $type;
 617    if($type == 'history') $ctype='revisions';
 618    if(!actionOK($ctype)) return false;
 619  
 620    switch($type){
 621      case 'edit':
 622        #most complicated type - we need to decide on current action
 623        if($ACT == 'show' || $ACT == 'search'){
 624          if($INFO['writable']){
 625            if(!empty($INFO['draft'])) {
 626              tpl_link(wl($ID,'do=draft'),
 627                         $pre.(($inner)?$inner:$lang['btn_draft']).$suf,
 628                         'class="action edit" accesskey="e" rel="nofollow"');
 629            } else {
 630              if($INFO['exists']){
 631                tpl_link(wl($ID,'do=edit&amp;rev='.$REV),
 632                         $pre.(($inner)?$inner:$lang['btn_edit']).$suf,
 633                         'class="action edit" accesskey="e" rel="nofollow"');
 634              }else{
 635                tpl_link(wl($ID,'do=edit&amp;rev='.$REV),
 636                         $pre.(($inner)?$inner:$lang['btn_create']).$suf,
 637                         'class="action create" accesskey="e" rel="nofollow"');
 638              }
 639            }
 640          }else{
 641            if(!actionOK('source')) return false; //pseudo action
 642            tpl_link(wl($ID,'do=edit&amp;rev='.$REV),
 643                     $pre.(($inner)?$inner:$lang['btn_source']).$suf,
 644                     'class="action source" accesskey="v" rel="nofollow"');
 645          }
 646        }else{
 647            tpl_link(wl($ID,'do=show'),
 648                     $pre.(($inner)?$inner:$lang['btn_show']).$suf,
 649                     'class="action show" accesskey="v" rel="nofollow"');
 650        }
 651        return true;
 652      case 'history':
 653        if(!actionOK('revisions'))
 654          return false;
 655        tpl_link(wl($ID,'do=revisions'),
 656                 $pre.(($inner)?$inner:$lang['btn_revs']).$suf,
 657                 'class="action revisions" accesskey="o" rel="nofollow"');
 658        return true;
 659      case 'recent':
 660        if(!actionOK('recent'))
 661          return false;
 662        tpl_link(wl($ID,'do=recent'),
 663                 $pre.(($inner)?$inner:$lang['btn_recent']).$suf,
 664                'class="action recent" accesskey="r" rel="nofollow"');
 665        return true;
 666      case 'index':
 667        if(!actionOK('index'))
 668          return false;
 669        tpl_link(wl($ID,'do=index'),
 670                 $pre.(($inner)?$inner:$lang['btn_index']).$suf,
 671                'class="action index" accesskey="x" rel="nofollow"');
 672        return true;
 673      case 'top':
 674        print '<a href="#dokuwiki__top" class="action top" accesskey="x">'.
 675              $pre.(($inner)?$inner:$lang['btn_top']).$suf.'</a>';
 676        return true;
 677      case 'back':
 678        if ($parent = tpl_getparent($ID)) {
 679          tpl_link(wl($parent,'do=show'),
 680          $pre.(($inner)?$inner:$lang['btn_back']).$suf,
 681          'class="action back" accesskey="b" rel="nofollow"');
 682          return true;
 683        }
 684        return false;
 685      case 'login':
 686        if($conf['useacl'] && $auth){
 687          if($_SERVER['REMOTE_USER']){
 688            tpl_link(wl($ID,'do=logout&amp;sectok='.getSecurityToken()),
 689                     $pre.(($inner)?$inner:$lang['btn_logout']).$suf,
 690                     'class="action logout" rel="nofollow"');
 691          }else{
 692            tpl_link(wl($ID,'do=login&amp;sectok='.getSecurityToken()),
 693                     $pre.(($inner)?$inner:$lang['btn_login']).$suf,
 694                     'class="action login" rel="nofollow"');
 695          }
 696          return true;
 697        }
 698        return false;
 699      case 'admin':
 700        if($INFO['ismanager']){
 701          tpl_link(wl($ID,'do=admin'),
 702                   $pre.(($inner)?$inner:$lang['btn_admin']).$suf,
 703                   'class="action admin" rel="nofollow"');
 704          return true;
 705        }
 706        return false;
 707     case 'subscribe':
 708     case 'subscription':
 709        if($conf['useacl'] && $auth && $ACT == 'show' && $conf['subscribers'] == 1){
 710          if($_SERVER['REMOTE_USER']){
 711            if($INFO['subscribed']) {
 712              if(!actionOK('unsubscribe'))
 713                return false;
 714              tpl_link(wl($ID,'do=unsubscribe'),
 715                       $pre.(($inner)?$inner:$lang['btn_unsubscribe']).$suf,
 716                       'class="action unsubscribe" rel="nofollow"');
 717            } else {
 718              if(!actionOK('subscribe'))
 719                return false;
 720              tpl_link(wl($ID,'do=subscribe'),
 721                       $pre.(($inner)?$inner:$lang['btn_subscribe']).$suf,
 722                       'class="action subscribe" rel="nofollow"');
 723            }
 724            return true;
 725          }
 726        }
 727        return false;
 728      case 'subscribens':
 729        if($conf['useacl'] && $auth && $ACT == 'show' && $conf['subscribers'] == 1){
 730          if($_SERVER['REMOTE_USER']){
 731            if($INFO['subscribedns']) {
 732              if(!actionOK('unsubscribens'))
 733                return false;
 734              tpl_link(wl($ID,'do=unsubscribens'),
 735                       $pre.(($inner)?$inner:$lang['btn_unsubscribens']).$suf,
 736                       'class="action unsubscribens" rel="nofollow"');
 737            } else {
 738              if(!actionOK('subscribens'))
 739                return false;
 740              tpl_link(wl($ID,'do=subscribens'),
 741                       $pre.(($inner)?$inner:$lang['btn_subscribens']).$suf,
 742                       'class="action subscribens" rel="nofollow"');
 743            }
 744            return true;
 745          }
 746        }
 747        return false;
 748      case 'backlink':
 749        if(!actionOK('backlink'))
 750          return false;
 751        tpl_link(wl($ID,'do=backlink'),
 752                 $pre.(($inner)?$inner:$lang['btn_backlink']).$suf,
 753                 'class="action backlink" rel="nofollow"');
 754        return true;
 755      case 'profile':
 756        if($conf['useacl'] && $auth && $_SERVER['REMOTE_USER'] &&
 757           $auth->canDo('Profile') && ($ACT!='profile')){
 758          tpl_link(wl($ID,'do=profile'),
 759                   $pre.(($inner)?$inner:$lang['btn_profile']).$suf,
 760                   'class="action profile" rel="nofollow"');
 761          return true;
 762        }
 763        return false;
 764      default:
 765        print '[unknown link type]';
 766        return true;
 767    }
 768  }
 769  
 770  /**
 771   * Print the search form
 772   *
 773   * If the first parameter is given a div with the ID 'qsearch_out' will
 774   * be added which instructs the ajax pagequicksearch to kick in and place
 775   * its output into this div. The second parameter controls the propritary
 776   * attribute autocomplete. If set to false this attribute will be set with an
 777   * value of "off" to instruct the browser to disable it's own built in
 778   * autocompletion feature (MSIE and Firefox)
 779   *
 780   * @author Andreas Gohr <andi@splitbrain.org>
 781   */
 782  function tpl_searchform($ajax=true,$autocomplete=true){
 783    global $lang;
 784    global $ACT;
 785  
 786    // don't print the search form if search action has been disabled
 787    if (!actionOk('search')) return false;
 788  
 789    print '<form action="'.wl().'" accept-charset="utf-8" class="search" id="dw__search"><div class="no">';
 790    print '<input type="hidden" name="do" value="search" />';
 791    print '<input type="text" ';
 792    if($ACT == 'search') print 'value="'.htmlspecialchars($_REQUEST['id']).'" ';
 793    if(!$autocomplete) print 'autocomplete="off" ';
 794    print 'id="qsearch__in" accesskey="f" name="id" class="edit" title="[F]" />';
 795    print '<input type="submit" value="'.$lang['btn_search'].'" class="button" title="'.$lang['btn_search'].'" />';
 796    if($ajax) print '<div id="qsearch__out" class="ajax_qsearch JSpopup"></div>';
 797    print '</div></form>';
 798    return true;
 799  }
 800  
 801  /**
 802   * Print the breadcrumbs trace
 803   *
 804   * @author Andreas Gohr <andi@splitbrain.org>
 805   */
 806  function tpl_breadcrumbs($sep='&raquo;'){
 807    global $lang;
 808    global $conf;
 809  
 810    //check if enabled
 811    if(!$conf['breadcrumbs']) return false;
 812  
 813    $crumbs = breadcrumbs(); //setup crumb trace
 814  
 815    //reverse crumborder in right-to-left mode, add RLM character to fix heb/eng display mixups
 816    if($lang['direction'] == 'rtl') {
 817      $crumbs = array_reverse($crumbs,true);
 818      $crumbs_sep = ' &#8207;<span class="bcsep">'.$sep.'</span>&#8207; ';
 819    } else {
 820      $crumbs_sep = ' <span class="bcsep">'.$sep.'</span> ';
 821    }
 822  
 823    //render crumbs, highlight the last one
 824    print '<span class="bchead">'.$lang['breadcrumb'].':</span>';
 825    $last = count($crumbs);
 826    $i = 0;
 827    foreach ($crumbs as $id => $name){
 828      $i++;
 829      echo $crumbs_sep;
 830      if ($i == $last) print '<span class="curid">';
 831      tpl_link(wl($id),hsc($name),'class="breadcrumbs" title="'.$id.'"');
 832      if ($i == $last) print '</span>';
 833    }
 834    return true;
 835  }
 836  
 837  /**
 838   * Hierarchical breadcrumbs
 839   *
 840   * This code was suggested as replacement for the usual breadcrumbs.
 841   * It only makes sense with a deep site structure.
 842   *
 843   * @author Andreas Gohr <andi@splitbrain.org>
 844   * @author Nigel McNie <oracle.shinoda@gmail.com>
 845   * @author Sean Coates <sean@caedmon.net>
 846   * @author <fredrik@averpil.com>
 847   * @todo   May behave strangely in RTL languages
 848   */
 849  function tpl_youarehere($sep=' &raquo; '){
 850    global $conf;
 851    global $ID;
 852    global $lang;
 853  
 854    // check if enabled
 855    if(!$conf['youarehere']) return false;
 856  
 857    $parts = explode(':', $ID);
 858    $count = count($parts);
 859  
 860    echo '<span class="bchead">'.$lang['youarehere'].': </span>';
 861  
 862    // always print the startpage
 863    $title = useHeading('navigation') ? p_get_first_heading($conf['start']) : $conf['start'];
 864    if(!$title) $title = $conf['start'];
 865    tpl_link(wl($conf['start']),hsc($title),'title="'.$conf['start'].'"');
 866  
 867    // print intermediate namespace links
 868    $part = '';
 869    for($i=0; $i<$count - 1; $i++){
 870      $part .= $parts[$i].':';
 871      $page = $part;
 872      resolve_pageid('',$page,$exists);
 873      if ($page == $conf['start']) continue; // Skip startpage
 874  
 875      // output
 876      echo $sep;
 877      if($exists){
 878        $title = useHeading('navigation') ? p_get_first_heading($page) : $page;
 879        if(!$title) $title = $parts[$i];
 880        tpl_link(wl($page),hsc($title),'title="'.$page.'"');
 881      }else{
 882        tpl_link(wl($page),$parts[$i],'title="'.$page.'" class="wikilink2" rel="nofollow"');
 883      }
 884    }
 885  
 886    // print current page, skipping start page, skipping for namespace index
 887    if(isset($page) && $page==$part.$parts[$i]) return;
 888    $page = $part.$parts[$i];
 889    if($page == $conf['start']) return;
 890    echo $sep;
 891    if(page_exists($page)){
 892      $title = useHeading('navigation') ? p_get_first_heading($page) : $page;
 893      if(!$title) $title = $parts[$i];
 894      tpl_link(wl($page),hsc($title),'title="'.$page.'"');
 895    }else{
 896      tpl_link(wl($page),$parts[$i],'title="'.$page.'" class="wikilink2" rel="nofollow"');
 897    }
 898    return true;
 899  }
 900  
 901  /**
 902   * Print info if the user is logged in
 903   * and show full name in that case
 904   *
 905   * Could be enhanced with a profile link in future?
 906   *
 907   * @author Andreas Gohr <andi@splitbrain.org>
 908   */
 909  function tpl_userinfo(){
 910    global $lang;
 911    global $INFO;
 912    if($_SERVER['REMOTE_USER']){
 913      print $lang['loggedinas'].': '.$INFO['userinfo']['name'].' ('.$_SERVER['REMOTE_USER'].')';
 914      return true;
 915    }
 916    return false;
 917  }
 918  
 919  /**
 920   * Print some info about the current page
 921   *
 922   * @author Andreas Gohr <andi@splitbrain.org>
 923   */
 924  function tpl_pageinfo($ret=false){
 925    global $conf;
 926    global $lang;
 927    global $INFO;
 928    global $REV;
 929    global $ID;
 930  
 931    // return if we are not allowed to view the page
 932    if (!auth_quickaclcheck($ID)) { return false; }
 933  
 934    // prepare date and path
 935    $fn = $INFO['filepath'];
 936    if(!$conf['fullpath']){
 937      if($REV){
 938        $fn = str_replace(fullpath($conf['olddir']).'/','',$fn);
 939      }else{
 940        $fn = str_replace(fullpath($conf['datadir']).'/','',$fn);
 941      }
 942    }
 943    $fn = utf8_decodeFN($fn);
 944    $date = strftime($conf['dformat'],$INFO['lastmod']);
 945  
 946    // print it
 947    if($INFO['exists']){
 948      $out = '';
 949      $out .= $fn;
 950      $out .= ' &middot; ';
 951      $out .= $lang['lastmod'];
 952      $out .= ': ';
 953      $out .= $date;
 954      if($INFO['editor']){
 955        $out .= ' '.$lang['by'].' ';
 956        $out .= editorinfo($INFO['editor']);
 957      }else{
 958        $out .= ' ('.$lang['external_edit'].')';
 959      }
 960      if($INFO['locked']){
 961        $out .= ' &middot; ';
 962        $out .= $lang['lockedby'];
 963        $out .= ': ';
 964        $out .= editorinfo($INFO['locked']);
 965      }
 966      if($ret){
 967          return $out;
 968      }else{
 969          echo $out;
 970          return true;
 971      }
 972    }
 973    return false;
 974  }
 975  
 976  /**
 977   * Prints or returns the name of the given page (current one if none given).
 978   *
 979   * If useheading is enabled this will use the first headline else
 980   * the given ID is used.
 981   *
 982   * @author Andreas Gohr <andi@splitbrain.org>
 983   */
 984  function tpl_pagetitle($id=null, $ret=false){
 985    global $conf;
 986    if(is_null($id)){
 987      global $ID;
 988      $id = $ID;
 989    }
 990  
 991    $name = $id;
 992    if (useHeading('navigation')) {
 993      $title = p_get_first_heading($id);
 994      if ($title) $name = $title;
 995    }
 996  
 997    if ($ret) {
 998        return hsc($name);
 999    } else {
1000        print hsc($name);
1001        return true;
1002    }
1003  }
1004  
1005  /**
1006   * Returns the requested EXIF/IPTC tag from the current image
1007   *
1008   * If $tags is an array all given tags are tried until a
1009   * value is found. If no value is found $alt is returned.
1010   *
1011   * Which texts are known is defined in the functions _exifTagNames
1012   * and _iptcTagNames() in inc/jpeg.php (You need to prepend IPTC
1013   * to the names of the latter one)
1014   *
1015   * Only allowed in: detail.php
1016   *
1017   * @author Andreas Gohr <andi@splitbrain.org>
1018   */
1019  function tpl_img_getTag($tags,$alt='',$src=null){
1020    // Init Exif Reader
1021    global $SRC;
1022  
1023    if(is_null($src)) $src = $SRC;
1024  
1025    static $meta = null;
1026    if(is_null($meta)) $meta = new JpegMeta($src);
1027    if($meta === false) return $alt;
1028    $info = $meta->getField($tags);
1029    if($info == false) return $alt;
1030    return $info;
1031  }
1032  
1033  /**
1034   * Prints the image with a link to the full sized version
1035   *
1036   * Only allowed in: detail.php
1037   */
1038  function tpl_img($maxwidth=0,$maxheight=0){
1039    global $IMG;
1040    $w = tpl_img_getTag('File.Width');
1041    $h = tpl_img_getTag('File.Height');
1042  
1043    //resize to given max values
1044    $ratio = 1;
1045    if($w >= $h){
1046      if($maxwidth && $w >= $maxwidth){
1047        $ratio = $maxwidth/$w;
1048      }elseif($maxheight && $h > $maxheight){
1049        $ratio = $maxheight/$h;
1050      }
1051    }else{
1052      if($maxheight && $h >= $maxheight){
1053        $ratio = $maxheight/$h;
1054      }elseif($maxwidth && $w > $maxwidth){
1055        $ratio = $maxwidth/$w;
1056      }
1057    }
1058    if($ratio){
1059      $w = floor($ratio*$w);
1060      $h = floor($ratio*$h);
1061    }
1062  
1063    //prepare URLs
1064    $url=ml($IMG,array('cache'=>$_REQUEST['cache']));
1065    $src=ml($IMG,array('cache'=>$_REQUEST['cache'],'w'=>$w,'h'=>$h));
1066  
1067    //prepare attributes
1068    $alt=tpl_img_getTag('Simple.Title');
1069    $p = array();
1070    if($w) $p['width']  = $w;
1071    if($h) $p['height'] = $h;
1072           $p['class']  = 'img_detail';
1073    if($alt){
1074      $p['alt']   = $alt;
1075      $p['title'] = $alt;
1076    }else{
1077      $p['alt'] = '';
1078    }
1079    $p = buildAttributes($p);
1080  
1081    print '<a href="'.$url.'">';
1082    print '<img src="'.$src.'" '.$p.'/>';
1083    print '</a>';
1084    return true;
1085  }
1086  
1087  /**
1088   * This function inserts a 1x1 pixel gif which in reality
1089   * is the inexer function.
1090   *
1091   * Should be called somewhere at the very end of the main.php
1092   * template
1093   */
1094  function tpl_indexerWebBug(){
1095    global $ID;
1096    global $INFO;
1097    if(!$INFO['exists']) return false;
1098  
1099    if(isHiddenPage($ID)) return false; //no need to index hidden pages
1100  
1101    $p = array();
1102    $p['src']    = DOKU_BASE.'lib/exe/indexer.php?id='.rawurlencode($ID).
1103                   '&'.time();
1104    $p['width']  = 1;
1105    $p['height'] = 1;
1106    $p['alt']    = '';
1107    $att = buildAttributes($p);
1108    print "<img $att />";
1109    return true;
1110  }
1111  
1112  // configuration methods
1113  /**
1114   * tpl_getConf($id)
1115   *
1116   * use this function to access template configuration variables
1117   */
1118  function tpl_getConf($id){
1119    global $conf;
1120    global $tpl_configloaded;
1121  
1122    $tpl = $conf['template'];
1123  
1124    if (!$tpl_configloaded){
1125      $tconf = tpl_loadConfig();
1126      if ($tconf !== false){
1127        foreach ($tconf as $key => $value){
1128          if (isset($conf['tpl'][$tpl][$key])) continue;
1129          $conf['tpl'][$tpl][$key] = $value;
1130        }
1131        $tpl_configloaded = true;
1132      }
1133    }
1134  
1135    return $conf['tpl'][$tpl][$id];
1136  }
1137  
1138  /**
1139   * tpl_loadConfig()
1140   * reads all template configuration variables
1141   * this function is automatically called by tpl_getConf()
1142   */
1143  function tpl_loadConfig(){
1144  
1145    $file = DOKU_TPLINC.'/conf/default.php';
1146    $conf = array();
1147  
1148    if (!@file_exists($file)) return false;
1149  
1150    // load default config file
1151    include($file);
1152  
1153    return $conf;
1154  }
1155  
1156  /**
1157   * prints the "main content" in the mediamanger popup
1158   *
1159   * Depending on the user's actions this may be a list of
1160   * files in a namespace, the meta editing dialog or
1161   * a message of referencing pages
1162   *
1163   * Only allowed in mediamanager.php
1164   *
1165   * @author Andreas Gohr <andi@splitbrain.org>
1166   */
1167  function tpl_mediaContent(){
1168    global $IMG;
1169    global $AUTH;
1170    global $INUSE;
1171    global $NS;
1172    global $JUMPTO;
1173  
1174    ptln('<div id="media__content">');
1175    if($_REQUEST['edit']){
1176      media_metaform($IMG,$AUTH);
1177    }elseif(is_array($INUSE)){
1178      media_filesinuse($INUSE,$IMG);
1179    }else{
1180      media_filelist($NS,$AUTH,$JUMPTO);
1181    }
1182    ptln('</div>');
1183  }
1184  
1185  /**
1186   * prints the namespace tree in the mediamanger popup
1187   *
1188   * Only allowed in mediamanager.php
1189   *
1190   * @author Andreas Gohr <andi@splitbrain.org>
1191   */
1192  function tpl_mediaTree(){
1193    global $NS;
1194  
1195    ptln('<div id="media__tree">');
1196    media_nstree($NS);
1197    ptln('</div>');
1198  }
1199  
1200  
1201  /**
1202   * Print a dropdown menu with all DokuWiki actions
1203   *
1204   * Note: this will not use any pretty URLs
1205   *
1206   * @author Andreas Gohr <andi@splitbrain.org>
1207   */
1208  function tpl_actiondropdown($empty='',$button='&gt;'){
1209      global $ID;
1210      global $INFO;
1211      global $REV;
1212      global $ACT;
1213      global $conf;
1214      global $lang;
1215      global $auth;
1216  
1217  
1218      echo '<form method="post" accept-charset="utf-8">'; #FIXME action
1219      echo '<input type="hidden" name="id" value="'.$ID.'" />';
1220      if($REV) echo '<input type="hidden" name="rev" value="'.$REV.'" />';
1221      echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />';
1222  
1223      echo '<select name="do" id="action__selector" class="edit">';
1224      echo '<option value="">'.$empty.'</option>';
1225  
1226      echo '<optgroup label=" &mdash; ">';
1227          // 'edit' - most complicated type, we need to decide on current action
1228          if($ACT == 'show' || $ACT == 'search'){
1229              if($INFO['writable']){
1230                  if(!empty($INFO['draft'])) {
1231                      echo '<option value="edit">'.$lang['btn_draft'].'</option>';
1232                  } else {
1233                      if($INFO['exists']){
1234                          echo '<option value="edit">'.$lang['btn_edit'].'</option>';
1235                      }else{
1236                          echo '<option value="edit">'.$lang['btn_create'].'</option>';
1237                      }
1238                  }
1239              }else if(actionOK('source')) { //pseudo action
1240                  echo '<option value="edit">'.$lang['btn_source'].'</option>';
1241              }
1242          }else{
1243              echo '<option value="show">'.$lang['btn_show'].'</option>';
1244          }
1245  
1246          echo '<option value="revisions">'.$lang['btn_revs'].'</option>';
1247          echo '<option value="backlink">'.$lang['btn_backlink'].'</option>';
1248      echo '</optgroup>';
1249  
1250      echo '<optgroup label=" &mdash; ">';
1251          echo '<option value="recent">'.$lang['btn_recent'].'</option>';
1252          echo '<option value="index">'.$lang['btn_index'].'</option>';
1253      echo '</optgroup>';
1254  
1255      echo '<optgroup label=" &mdash; ">';
1256          if($conf['useacl'] && $auth){
1257              if($_SERVER['REMOTE_USER']){
1258                  echo '<option value="logout">'.$lang['btn_logout'].'</option>';
1259              }else{
1260                  echo '<option value="login">'.$lang['btn_login'].'</option>';
1261              }
1262          }
1263  
1264          if($conf['useacl'] && $auth && $_SERVER['REMOTE_USER'] &&
1265               $auth->canDo('Profile') && ($ACT!='profile')){
1266              echo '<option value="profile">'.$lang['btn_profile'].'</option>';
1267          }
1268  
1269          if($conf['useacl'] && $auth && $ACT == 'show' && $conf['subscribers'] == 1){
1270              if($_SERVER['REMOTE_USER']){
1271                  if($INFO['subscribed']) {
1272                      echo '<option value="unsubscribe">'.$lang['btn_unsubscribe'].'</option>';
1273                  } else {
1274                      echo '<option value="subscribe">'.$lang['btn_subscribe'].'</option>';
1275                  }
1276              }
1277          }
1278  
1279          if($conf['useacl'] && $auth && $ACT == 'show' && $conf['subscribers'] == 1){
1280              if($_SERVER['REMOTE_USER']){
1281                  if($INFO['subscribedns']) {
1282                      echo '<option value="unsubscribens">'.$lang['btn_unsubscribens'].'</option>';
1283                  } else {
1284                      echo '<option value="subscribens">'.$lang['btn_subscribens'].'</option>';
1285                  }
1286              }
1287          }
1288  
1289          if($INFO['ismanager']){
1290              echo '<option value="admin">'.$lang['btn_admin'].'</option>';
1291          }
1292      echo '</optgroup>';
1293  
1294      echo '</select>';
1295      echo '<input type="submit" value="'.$button.'" id="action__selectorbtn" />';
1296      echo '</form>';
1297  }
1298  
1299  /**
1300   * Print a informational line about the used license
1301   *
1302   * @author Andreas Gohr <andi@splitbrain.org>
1303   * @param  string $img    - print image? (|button|badge)
1304   * @param  bool   $return - when true don't print, but return HTML
1305   */
1306  function tpl_license($img='badge',$imgonly=false,$return=false){
1307      global $license;
1308      global $conf;
1309      global $lang;
1310      if(!$conf['license']) return '';
1311      if(!is_array($license[$conf['license']])) return '';
1312      $lic = $license[$conf['license']];
1313  
1314      $out  = '<div class="license">';
1315      if($img){
1316          $src = license_img($img);
1317          if($src){
1318              $out .= '<a href="'.$lic['url'].'" rel="license"';
1319              if($conf['target']['external']) $out .= ' target="'.$conf['target']['external'].'"';
1320              $out .= '><img src="'.DOKU_BASE.$src.'" class="medialeft lic'.$img.'" alt="'.$lic['name'].'" /></a> ';
1321          }
1322      }
1323      if(!$imgonly) {
1324          $out .= $lang['license'];
1325          $out .= '<a href="'.$lic['url'].'" rel="license" class="urlextern"';
1326          if($conf['target']['external']) $out .= ' target="'.$conf['target']['external'].'"';
1327          $out .= '>'.$lic['name'].'</a>';
1328          $out .= '</div>';
1329      }
1330  
1331      if($return) return $out;
1332      echo $out;
1333  }
1334  
1335  //Setup VIM: ex: et ts=4 enc=utf-8 :
1336  


Generated: Thu Feb 19 01:30:02 2009 Cross-referenced by PHPXref 0.7
WikiForumIRCBugsDarcsXRefTranslate