return parse_template(file_get_contents($filename));
}
-# We parse the template string into a tree of strings and sub-templates.
+# We parse the template string into a tree of strings and sub-templates.
# A template is a hash with a name string, a pieces array, and possibly
# an args array.
function parse_template($string) {
$tem =& tem_push();
$tem['pieces'] = array();
- # note: for some reason this captures '<!--' but not '-->'.
- $matches = preg_split("/(<!--)?(~[^~]*~)(?(1)-->)/", $string, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $matches = preg_split('/(<!--)?(~[^~]*~)(?(1)-->)/', preg_replace('/<!--(~[^~]*~)-->/', '$1', $string), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
foreach($matches as $match) {
if($match == '~~') $match = '~';
if(substr($match,0,1) == '~' and strlen($match) > 2) {
array_pop($args); # drop '}'
$cur = $tem['name'];
if($name && $name != $cur) {
- die("Invalid template: tried to close '$name', but '$cur' is current.");
+ die("Invalid template: tried to close '$name', but '$cur' is current.");
}
$tem =& $tem['parent'];
} else { # value slot
$tem['pieces'][] = array('name' => $name, 'args' => $args);
}
- } elseif($match and $match != '<!--') { # static string
+ } else { # static string
$tem['pieces'][] = $match;
}
}
if(count($tem['args'])) {
$auto_func = "tem_auto_" . $tem['args'][0];
function_exists($auto_func)
- or die("ERROR: template auto function '$auto_func' not found.<br>\n");
+ or die("ERROR: template auto function '$auto_func' not found.<br>\n");
}
if($auto_func) $value = $auto_func($scope['data'][$key], $key, $scope);
else $value = $scope['data'][$key];
$subs = array();
foreach($tem['pieces'] as $piece) {
if($is_sub($piece)) {
- $subs[$piece['name']] = $piece;
+ $subs[$piece['name']] = $piece;
}
}
return $subs;
function tem_auto_sep(&$value, $key, $context) {
$rows =& $context['parent']['parent'];
if($rows['cur'] != count($rows['rows'])-1) # last row?
- return $value = true; # show once
+ return $value = true; # show once
+}
+
+# auto-show once, only when this is the first row of the parent
+function tem_auto_last(&$value, $key, $context) {
+ $rows =& $context['parent']['parent'];
+ if($rows['cur'] == count($rows['rows'])-1) # last row?
+ return $value = true; # show once
+}
+
+# auto-show once, only when this is the last row of the parent
+function tem_auto_first(&$value, $key, $context) {
+ $rows =& $context['parent']['parent'];
+ if($rows['cur'] == 0) # first row?
+ return $value = true; # show once
}
# 'show' sections will be shown unless the corresponding data value
function tem_auto_evenodd(&$values) {
$even = true;
- foreach($values as &$value) {
+ if($values) foreach($values as &$value) {
$value['evenodd'] = $even ? 'even' : 'odd';
$even = !$even;
}
function tem() {
$this->template = array('pieces' => array());
$this->data = array();
- }
+ }
function set($key, $value) {
$this->data[$key] = $value;