array('fn' => 'FPLTemplate2', 'fmt' => '#default'), 'bygroup' => array('fn' => 'FPLTemplate2', 'template' => '#bygroup', 'class' => 'fplbygroup'), 'simple' => array('fn' => 'FPLTemplate2', 'template' => '#simple', 'class' => 'fplsimple'), 'group' => array('fn' => 'FPLTemplate2', 'template' => '#group', 'class' => 'fplgroup'), 'title' => array('fn' => 'FPLTemplate2', 'template' => '#title', 'class' => 'fpltitle', 'order' => 'title'), 'count' => array('fn' => 'FPLCountA'), )); ## Default chain of functions called by FPLTemplate2 (defined below) SDV($FPLTemplateFunctions, array( 'FPLTemplateLoad','FPLTemplateDefaults','FPLTemplatePageList','FPLTemplateSliceList','FPLTemplateFormat')); /* Comment: The original FPLTemplate function has been broken into five logical parts, each becoming a seperate function called in sequence as defined in array $FPLTemplateFunctions by main FPLTemplate2() function. Each function called can return HTML formatted output, but only the last, FPLTemplateFormat(), does so. Each function changes relevant arrays passed by reference: pagelist $matches; pagelist options $opt; template parts $tparts. */ ## Main function: call each of $FPLTemplateFunctions in turn function FPLTemplate2($pagename, &$matches, $opt) { global $FPLTemplateFunctions; StopWatch("FPLTemplate: Chain begin"); $fnlist = $FPLTemplateFunctions; $out = array(); foreach((array)$fnlist as $fn) { StopWatch("FPLTemplate: $fn"); $out[] = $fn($pagename, $matches, $opt, $tparts); } StopWatch("FPLTemplate: Chain end "); return implode('',$out); } //}}} ## load pagelist template from page function FPLTemplateLoad($pagename, $matches, $opt, &$tparts) { global $Cursor, $FPLTemplatePageFmt, $RASPageName, $PageListArgPattern, $FmtV, $FmtPV; $template = @$opt['template']; if (!$template) $template = @$opt['fmt']; $ttext = RetrieveAuthSection($pagename, $template, $FPLTemplatePageFmt); $ttext = PVSE(Qualify($RASPageName, $ttext)); ## save any escapes $ttext = MarkupEscape($ttext); ## remove any anchor markups to avoid duplications $ttext = preg_replace('/\\[\\[#[A-Za-z][-.:\\w]*\\]\\]/', '', $ttext); ## extract portions of template $tparts = preg_split('/\\(:(template)\\s+(\\w+)\\s*(.*?):\\)/i', $ttext, -1, PREG_SPLIT_DELIM_CAPTURE); } //}}} ## extract args from (:template defaults .....:) and merge with options from (:pagelist :) function FPLTemplateDefaults($pagename, $matches, &$opt, &$tparts) { global $PageListArgPattern; $i = 0; while ($i < count($tparts)) { if ($tparts[$i] != 'template') { $i++; continue; } if ($tparts[$i+1] != 'defaults' && $tparts[$i+1] != 'default') { $i+=4; continue; } $opt = array_merge(ParseArgs($tparts[$i+2], $PageListArgPattern), $opt); array_splice($tparts, $i, 3); } SDVA($opt, array('class' => 'fpltemplate', 'wrap' => 'div')); } //}}} /* Comment: Added capability of merging pagelist with any list supplied previously by custom function. */ ## get list of pages by calling MakePageList; ## merge lists if any $matches are supplied previously function FPLTemplatePageList($pagename, &$matches, $opt, $tparts) { $matches = array_unique(array_merge($matches, MakePageList($pagename, $opt, 0))); } //}}} /* Comment: Added a start= parameter for (:pagelist .. :) Added a {$$PageListCount} template variable, for total $matches count before any slicing of $matches. */ ## slice matches according to count= and start= function FPLTemplateSliceList($pagename, &$matches, &$opt, $tparts) { ## count matches before any slicing and save value as template var {$$PageListCount} $opt['PageListCount'] = $pagelistcount = count($matches); ## extract page subset according to 'start=' parameter if (@$opt['start']) { if ($opt['start'] >= 0) $matches = array_slice($matches, $opt['start']-1); else $matches = array_slice($matches, $pagelistcount+$opt['start']); } ## further extract page subset according to 'count=' parameter if (@$opt['count']) { list($r0, $r1) = CalcRange($opt['count'], $pagelistcount); if ($r1 < $r0) $matches = array_reverse(array_slice($matches, $r1-1, $r0-$r1+1)); else $matches = array_slice($matches, $r0-1, $r1-$r0+1); } } //}}} /* Comment: Added of (:template none:) optional template section. The control structure for the main loop has been changed to allow handling of 'no matches' cases. */ ## format items according to template function FPLTemplateFormat($pagename, &$matches, &$opt, &$tparts) { global $Cursor; $savecursor = $Cursor; $pagecount = 0; $groupcount = 0; $grouppagecount = 0; $pseudovars = array('{$$PageCount}' => &$pagecount, '{$$GroupCount}' => &$groupcount, '{$$GroupPageCount}' => &$grouppagecount); foreach(preg_grep('/^[\\w$]/', array_keys($opt)) as $k) if (!is_array($opt[$k])) $pseudovars["{\$\$$k}"] = htmlspecialchars($opt[$k], ENT_NOQUOTES); $vk = array_keys($pseudovars); $vv = array_values($pseudovars); $lgroup = ''; $out = ''; $mcount = count($matches); for($i=0; $i <= $mcount; $i++) { if($i>0 && $i==$mcount) break; $pn = $matches[$i]; $group = PageVar($pn, '$Group'); if ($group != $lgroup) { $groupcount++; $grouppagecount = 0; $lgroup = $group; } $grouppagecount++; $pagecount++; $t = 0; while ($t < count($tparts)) { if ($tparts[$t] != 'template') { if ($mcount!=0) $item = $tparts[$t]; $t++; } elseif ($mcount==0) { if ($tparts[$t] == 'template' && $tparts[$t+1] == 'none') $item = $tparts[$t+3]; $t+=4; } else { list($when, $control, $item) = array_slice($tparts, $t+1, 3); $t+=4; if (!$control) { if ($when == 'none') continue; if ($when == 'first' && $i != 0) continue; if ($when == 'last' && $i != $mcount - 1) continue; } else { if ($when == 'none') continue; if ($when == 'first' || !isset($last[$t])) { $Cursor['<'] = $Cursor['<'] = (string)@$matches[$i-1]; $Cursor['='] = $pn; $Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+1]; $curr = str_replace($vk, $vv, $control); $curr = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e', "PageVar(\$pn, '$2', '$1')", $curr); if ($when == 'first' && $i > 0 && $last[$t] == $curr) continue; $last[$t] = $curr; } if ($when == 'last') { $Cursor['<'] = $Cursor['<'] = $pn; $Cursor['='] = (string)@$matches[$i+1]; $Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+2]; $next = str_replace($vk, $vv, $control); $next = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e', "PageVar(\$pn, '$2', '$1')", $next); if ($next == $last[$t] && $i != count($matches) - 1) continue; $last[$t] = $next; } } } $Cursor['<'] = $Cursor['<'] = (string)@$matches[$i-1]; $Cursor['='] = $pn; $Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+1]; $item = str_replace($vk, $vv, $item); $item = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e', "PVSE(PageVar(\$pn, '$2', '$1'))", $item); $out .= MarkupRestore($item); } } $class = preg_replace('/[^-a-zA-Z0-9\\x80-\\xff]/', ' ', @$opt['class']); if ($class) $class = " class='$class'"; $wrap = @$opt['wrap']; if ($wrap != 'inline') { $out = MarkupToHTML($pagename, $out, array('escape' => 0, 'redirect'=>1)); if ($wrap != 'none') $out = "$out"; } $Cursor = $savecursor; return $out; } //}}}