<?php if (!defined('PmWiki')) exit();

/*
  Version 2.0    12/5/05  Author: Martin Fick

  Previous contributors: Daniel Scheibler

  To install this recipe, simply put this in your cookbook directory
  and add include_once("cookbook/pltemplates.php"); to your config.php.

  Suggestion:  this recipe is most usefull along with the PageVariables
  recipe.  Without it is rather limiting since you can no longer even
  get page groups.

  To make use of this recipe, set fmt=template in your pagelist and
  set the page option to the name of your template (page=<template>).

  Example:

  (:pagelist fmt=template page=PageList.Main group=Main:)


  Templates:

  To define a template, simply create a wiki page with standard wiki
  markup that will be included once for each page in the pagelist.
  This template can be used to define the layout of your pagelist
  output.

  Custom variables:

    Additional custom page variables are defined in this recipe which
    will get set appropriately on every page returned.  Use these
    variables to output the fullnames of the current, previous or
    next page.  With these fullnames and the PageVariables recipe you
    can get values such as the name and group of these pages.  You
    can also test for conditions using the names and groups which may
    influence your markup, such as at the beginning of a new group.

   {$Curr}            FullName of page from current iteration
   {$Prev}            FullName of page from previous iteration
   {$Next}            FullName of page from next iteration

   {$PageCount}       The current page count
   {$GroupPageCount}  The current page count within this group
   {$GroupCount}      The current group count

    Note: these variables have been kept to a minimum, due to the
          new PageVariables recipe.


  Additional Conditions:

  This recipe provides two additional conditions which are very
  valuable when using this recipe:

    equal         Test whether a value is equal to another value
    divisible     Test whether a number is divisible by another number


  Additional Markup:

  %omit-quest%

    Since it is common for pagelists to reference Group pages (such
    as Group.HomePage) that might not exist, this new markup has
    been included to suppress any questions marks for non-existing
    pages.  Simply use the markup before any link specification which
    may be to a non-existing wiki page.

  Blank page variables with {$Prev} and {$Next}:

    Since {$Prev} and {$Next} can be blank, there is markup causing
    page variables with blank {$Prev} and {$Next}s to also be blank.
    This is particularly usefull in conditional statements.  This
    makes {{$Prev}$Group} blank if {$Prev} is blank.  Without this
    markup, a blank {$Prev} would cause {{$Prev}$Group} to return
    the current group which is probably not what was desired.


  Blank links with [[{$Prev}]], [[{$Next}]] or blank page variables:

    There is also some additional markup defined to hide blank links
    which the {$Prev}, {$Next} or the ensuing blank page variables
    might create.  This means that [[{$Prev}]] will be invisible
    instead of outputting strange [[]] markups on the first iteration.



  Simple Examples:

  Most of these assume that you have the PageVariables recipe installed.

  -To test for the beginning of a pagelist (is {$Prev} blank?):

   (:if equal {$Prev} :)

  -To test for the beginning of a group:

    (:if ! equal {{$Curr}$Group} {{$Prev}$Group} :)


  -Sample template markup to create a fmt=byGroup like layout:

    (:if ! equal {{$Curr}$Group} {{$Prev}$Group} :)
    %omit-quest%[[{{$Curr}$Group}(.HomePage)]] /
    (:if:)
    ->[[({{$Curr}$Group}.){{$Curr}$Name}]]

    While this sets up layout info, the styling may be different
    from fmt=byGroup since this does not output any CSS classes.
    Also, non-existent groups will actually be linked with
    ?action=edit even though the question mark will be omitted
    (this might be an improvement).
*/


## $FPLFunctions is a list of functions associated with fmt= options
SDVA($FPLFunctions, array('template' => 'FPLTemplate'));


# This is used for {$Prev} and {$Next} so that they can
# simulate a blank output without the annoying sideeffects.
SDV($FPLTemplateBlank, '{$Blank}');
$FPLTemplateBlankPRE = preg_quote($FPLTemplateBlank);

# Substituye all variable substitution with pages named
# $FPLTemplateBlank, with $FPLTemplateBlank so that the
# pagevars recipe does not attempt to replace them and
# give erractic results.
#
#  I use [:alnum:] to identify a variable, will that work?
#  If I speciy the existing ones, than this won't catch them
#  if others add more variable definitions.
#
# Maybe this could be conditional on the existance of the pagevars
# recipe? Without it, it is useless right?  How?
#
Markup('{blankpage$fmt}','<{page$fmt}', "/\{$FPLTemplateBlankPRE".'\\$[[:alnum:]]*}/', "$FPLTemplateBlank");


# Make links with only $FPLTemplateBlank in them dissapear!
Markup('[[blank]]','<FPLTemplateBlank', "/\\[\\[$FPLTemplateBlankPRE\]\]/", "$FPLTemplateBlank");

# And lastly, Make $FPLTemplateBlank dissapear!
# if bad - Markup('FPLTemplateBlank','>[[blank]]', "/$FPLTemplateBlankPRE/", "");

# And lastly, Make $FPLTemplateBlank dissapear!
Markup('FPLTemplateBlank','<if', "/$FPLTemplateBlankPRE/", "");



# This is also in the extended conditional markup, but since it
#  is essential for even determining the begining of a new group,
#  it is included here.  Hoepfully without conflicting.
if (!array_key_exists('equal', $Conditions)) {
  $Conditions['equal'] = 'EqualCondition($condparm)';
}
if(! function_exists("EqualCondition")) {
  function EqualCondition($condparm) {
    $args = ParseArgs($condparm);
    return @($args[''][0] == $args[''][1]);
  }
}

# This is extremley usefull for tables.  You can use it to
# determine when to create a new row (ie. after every 4 pages)
# or even use it to create ledger style row coloring.
$Conditions['divisible'] = 'DivisibleCondition($condparm)';

function DivisibleCondition($condparm) {
  $args = ParseArgs($condparm);
  return @(($args[''][0] % $args[''][1]) == 0);
}



# This allows us to omit question marks on non-existant pages.
$HTMLStylesFmt['pltemplates'] =
      ' .omit-quest a.createlink { display:none; } ';



## FPLTemplate
function FPLTemplate($pagename, &$matches, $opt) {
  global $FPLTemplateOpt, $FPLTemplateBlank;

  SDVA($FPLTemplateOpt, array('readf' => 0, 'order' => 'name'));
  SDV($FullNameFmt, "\$FullName");
  SDV($GroupFmt,"\$Group");

  $matches = MakePageList($pagename, array_merge((array)$FPLTemplateOpt,
    $opt));
  if (@$opt['count']) {
    array_splice($matches, $opt['count']);
  }

  $ttext =  IncludeText($pagename, $opt['page']);

  $pages = array();
  $i = 0;
  foreach($matches as $page) {
    $pages[++$i] = $page;
  }
  $out = array();
  $i = 0;
  $n = count($matches);
  $vars['PageCount'] = 0;
  $vars['GroupCount'] = 0;
  $vars['Prev'] = $FPLTemplateBlank;
  foreach($pages as $page) {
    $i++;
    $vars['Curr'] = FmtPageName($FullNameFmt, $page['pagename']);

    $vars['Next'] = $FPLTemplateBlank;
    if ($i < $n) {
      $next = $pages[$i+1];
      $vars['Next'] = FmtPageName($FullNameFmt, $next['pagename']);
    }

    $group = FmtPageName($GroupFmt, $page['pagename']);
    if($i>1) {
      $prevgroup = FmtPageName($GroupFmt, $pages[$i-1]['pagename']);
    }
    if ($prevgroup != $group) {
      $vars['GroupPageCount'] = 0;
      $vars['GroupCount']++;
    }
    $vars['PageCount']++;
    $vars['GroupPageCount']++;

    $text = preg_replace('/\{\$(Curr|Next|Prev)\}/e',
      "\$vars['$1']", $ttext) ."\n";
    $out[] = preg_replace('/\{\$(Page|Group|GroupPage)Count\}/e',
      "\$vars['$1Count']", $text) ."\n";

    $vars['Prev'] = $vars['Curr'];
  }

  return implode('', $out);
}