, Copyright 2007. * see http://www.pmwiki.org/wiki/Cookbook/Hg * Modified by: Kathryn Andersen * Further mods by Hans Bracker * An mangled again by Feral, 2007-03-20, 2007-03-21 */ $RecipeInfo['Cluster']['Version'] = '2007-03-21'; /* ================================================================ * Customisation Variables for use in local config file */ SDV($ClusterSeparator, '-'); SDV($ClusterMaxLevels, 7); SDV($ClusterBreadCrumbSeparator, " $ClusterSeparator "); SDV($EnableBreadCrumbName, 1); SDV($EnableBreadCrumbTitles, 0); /* ================================================================ * script Setup */ $pagename = ResolvePageName($pagename); $EnablePGCust = 0; $m = preg_split('/[.\\/]/', $pagename); $group = $m[0]; $name = $m[1]; $FmtPV['$g0'] = 'ClusterCountLevels($group)'; $FmtPV['$n0'] = 'ClusterCountLevels($name)'; ClusterHelper_ConstructG1N1PageVars($group, 'g', $name, 'n'); $FmtPV['$BreadCrumbsDepth'] = 'ClusterCountLevels($group)'; /* ================================================================ * Page Variables */ $FmtPV['$BreadCrumb'] = '"'.ClusterBreadCrumb($pagename, "").'"'; $FmtPV['$BreadCrumbTitle'] = '"'.ClusterBreadCrumb($pagename, "title=1").'"'; $FmtPV['$GroupTitle'] = '"'.ClusterGroupTitle($pagename, "").'"'; $FmtPV['$GroupTitleSpaced'] = '"'.ClusterGroupTitle($pagename, "space=true").'"'; $FmtPV['$ClusterSideBar'] = '"'.ClusterPageName($group, "SideBar").'"'; $FmtPV['$ClusterRightBar'] = '"'.ClusterPageName($group, "RightBar").'"'; $FmtPV['$CS'] = '"'.$ClusterSeparator.'"'; $FmtPV['$ClusterFirst1'] = '"'.ClusterSlice($pagename, "first=1").'"'; $FmtPV['$ClusterFirst2'] = '"'.ClusterSlice($pagename, "first=2").'"'; $FmtPV['$ClusterFirst3'] = '"'.ClusterSlice($pagename, "first=3").'"'; $FmtPV['$ClusterFirst4'] = '"'.ClusterSlice($pagename, "first=4").'"'; $FmtPV['$ClusterFirst5'] = '"'.ClusterSlice($pagename, "first=5").'"'; $FmtPV['$ClusterFirst6'] = '"'.ClusterSlice($pagename, "first=6").'"'; $FmtPV['$ClusterFirst7'] = '"'.ClusterSlice($pagename, "first=7").'"'; $FmtPV['$ClusterLast1'] = '"'.ClusterSlice($pagename, "last=1").'"'; $FmtPV['$ClusterLast2'] = '"'.ClusterSlice($pagename, "last=2").'"'; $FmtPV['$ClusterLast3'] = '"'.ClusterSlice($pagename, "last=3").'"'; $FmtPV['$ClusterLast4'] = '"'.ClusterSlice($pagename, "last=4").'"'; $FmtPV['$ClusterLast5'] = '"'.ClusterSlice($pagename, "last=5").'"'; $FmtPV['$ClusterLast6'] = '"'.ClusterSlice($pagename, "last=6").'"'; $FmtPV['$ClusterLast7'] = '"'.ClusterSlice($pagename, "last=7").'"'; /* ================================================================ * Set up clustered configurations */ $found_config = false; $found_grouphead = false; $found_groupfoot = false; $found_attr = false; if (file_exists("$LocalDir/$group.$name.php")) { include_once("$LocalDir/$group.$name.php"); $found_config = true; } $PageCSSListFmt["pub/css/$group.$name.css"] = "$PubDirUrl/css/$group.$name.css"; $groups = explode($ClusterSeparator, $group); while (count($groups) != 0) { $cluster_group = implode ($ClusterSeparator, $groups); if (!$found_config && file_exists("$LocalDir/$cluster_group.php")) { include_once("$LocalDir/$cluster_group.php"); $found_config = true; } if (!$found_grouphead && PageExists("$cluster_group.GroupHeader")) { $GroupHeaderFmt = "(:nl:)(:include $cluster_group.GroupHeader:)(:nl:)"; $found_grouphead = true; } if (!$found_groupfoot && PageExists("$cluster_group.GroupFooter")) { $GroupFooterFmt = "(:nl:)(:include $cluster_group.GroupFooter:)(:nl:)"; $found_groupfoot = true; } if (!$found_attr && PageExists("$cluster_group.GroupAttributes")) { $GroupAttributesFmt = "$cluster_group.GroupAttributes"; $found_groupfoot = true; } $PageCSSListFmt["pub/css/$cluster_group.css"] = "$PubDirUrl/css/$cluster_group.css"; array_pop($groups); } // set the defaults for those that haven't been found if (!$found_config && file_exists("$LocalDir/$default.php")) { include_once("$LocalDir/$default.php"); } if (!$found_grouphead && PageExists("$SiteGroup.GroupHeader")) { $GroupHeaderFmt = "(:nl:)(:include $SiteGroup.GroupHeader:)(:nl:)"; } if (!$found_groupfoot && PageExists("$SiteGroup.GroupFooter")) { $GroupFooterFmt = "(:nl:)(:include $SiteGroup.GroupFooter:)(:nl:)"; } $PageCSSListFmt["pub/css/local.css"] = "$PubDirUrl/css/local.css"; $PageCSSListFmt = array_reverse($PageCSSListFmt, true); /* ================================================================ * Functions */ function ClusterCountLevels($name) { global $ClusterSeparator; $parts = explode($ClusterSeparator, $name); return count($parts); } # return the pagename of the closest ancestor function ClusterPageName($group, $name) { global $ClusterSeparator; global $SiteGroup; $groups = explode($ClusterSeparator, $group); while (count($groups) != 0) { $cluster_group = implode ($ClusterSeparator, $groups); if (PageExists("$cluster_group.$name")) { // short-circuit return! return "$cluster_group.$name"; } array_pop($groups); } return "$SiteGroup.$name"; } /* ================================================================ * Markup for link shortcuts */ Markup('[[cluster',' $item, 'path' =>$path); $index++; } // print_r($groups); // var_dump($groups); // die; return $groups; } // }}} // ------------------------------------------------------------------------ function ClusterHelper_FetchGroupTitle($group) { // {{{ global $DefaultName; $pagepossibles = array( "$group.GroupAttributes", "$group.GroupHeader", "$group.GroupFooter", "$group.$group", "$group.$DefaultName", ); $group_title=null; foreach($pagepossibles as $try) { if ( PageExists($try) ) { $page = ReadPage($try, READPAGE_CURRENT); if ( $page['title']) { $group_title = $page['title']; break; } } } return $group_title; } // }}} // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ Markup('breadcrumb', 'directives', '/\\(:breadcrumb\\s*(.*?):\\)/ei', "ClusterBreadCrumb(\$pagename, PSS('$1'))" ); // return a "breadcrumb trail" from the Cluster elements function ClusterBreadCrumb($pagename, $opt) { // {{{ // For $usetitles = true; // In pmwiki.php: $PagePathFmt = array('{$Group}.$1','$1.$1','$1.{$DefaultName}'); global $DefaultName; global $AsSpacedFunction; global $ClusterSeparator, $ClusterBreadCrumbSeparator, $EnableBreadCrumbName, $EnableBreadCrumbTitles, $FmtPV; $defaults = array( 'left' => 0, // Num elements to remove from left side of group 'right' => 0, // Num elements to remove from right side of group 'separator' => $ClusterBreadCrumbSeparator, 'title' => $EnableBreadCrumbTitles, 'name' => $EnableBreadCrumbName, ); $opt = array_merge($defaults, ParseArgs($opt)); $groups = ClusterHelper_FetchGroups($pagename); # Remove right side first; $trim = abs($opt['right']); if ( $trim >= count($groups) ) { $trim = count($groups)-1; } $index = 0; while ($index < $trim) { array_pop($groups); $index++; } # Remove left side second, but leave at least 1 element (right most); $trim = abs($opt['left']); if ( $trim >= count($groups) ) { $trim = count($groups)-1; } $index = 0; while ($index < $trim) { array_shift($groups); $index++; } $index = 0; foreach($groups as $item) { if ( $index != 0) { $out.= $opt['separator']; } $out.= '[['; $out.= $item['path'].'/|'; if ( $opt['title']) { $path_name = ClusterHelper_FetchGroupTitle($item['path']); if ( !$path_name) { if ( $opt['title']==1) { $path_name = $AsSpacedFunction($item['name']); } else { $path_name = $item['name']; } } $out.= $path_name; } else { $out.= $item['name']; } $out.= ']]'; $index++; } # Page Name if ( $opt['name']) { $out .= $opt['separator']."[[$pagename|+]]"; } return $out; } // }}} // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ Markup('feralclustergrouptitle', 'directives', '/\\(:clustergrouptitle\\s*(.*?):\\)/ei', "ClusterGroupTitle(\$pagename, PSS('$1'))" ); // return the title of an element. function ClusterGroupTitle($pagename, $opt) { // {{{ global $ClusterSeparator; global $AsSpacedFunction; $defaults = array( 'space' => false, 'index' => 'last', 'onebasedindex' => true, 'link' => false, ); $opt = array_merge($defaults, ParseArgs($opt)); $groups = ClusterHelper_FetchGroups($pagename); $index_wanted = $opt['index']; if ( $index_wanted == 'last') { $group_piece = array_pop($groups); } else { // [Feral:079/07@02:59] we presume $index_wanted is a number; convert it to such. $index_wanted=abs($index_wanted); if ( $opt['onebasedindex']) { $index_wanted--; } if ( $index_wanted < count($groups) ) { $group_piece = $groups[$index_wanted]; } else { // [Feral:079/07@03:13] out of bounds; *shrug* return ''; } } $group_title=ClusterHelper_FetchGroupTitle($group_piece['path']); if ( !$group_title) { $group_title = $group_piece['name']; } if ( $opt['space']) { $group_title = $AsSpacedFunction($group_title); } $out = $group_title; if ( $opt['link']) { $out = "[[{$group_piece['path']}/|$group_title]]"; } return $out; } // }}} // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ Markup('clusterslice', 'directives', '/\\(:clusterslice\\s*(.*?):\\)/ei', "ClusterSlice(\$pagename, PSS('$1'))" ); // return a 'slice' of the cluster trail; function ClusterSlice($pagename, $opt) { // {{{ // For $usetitles = true; // In pmwiki.php: $PagePathFmt = array('{$Group}.$1','$1.$1','$1.{$DefaultName}'); global $DefaultName; global $AsSpacedFunction; global $ClusterSeparator, $EnableBreadCrumbName, $EnableBreadCrumbTitles, $FmtPV; $defaults = array( 'left' => 0, // Num elements to remove from left side of group 'right' => 0, // Num elements to remove from right side of group 'first' => null, // EXCLUSIVE to last, synonym to firstlast=+ 'last' => null, // EXCLUSIVE to first, synonym to firstlast=- 'firstlast' => null, // return this many + first, - last elements. 'separator' => $ClusterSeparator, 'return' => 'names', ); $opt = array_merge($defaults, ParseArgs($opt)); // 'first' => 0, // EXCLUSIVE to last, synonym to firstlast=+ // 'last' => 0, // EXCLUSIVE to first, synonym to firstlast=- // 'firstlast' => 0, // return this many + first, - last elements. if ( isset($opt['last'])) { $firstlast = -abs($opt['last']); } if ( isset($opt['first'])) { $firstlast = +abs($opt['first']); } if ( isset($opt['firstlast'])) { $firstlast = (int)$opt['firstlast']; } $groups = ClusterHelper_FetchGroups($pagename); # Remove right side first; $trim = abs($opt['right']); if ( $trim >= count($groups) ) { $trim = count($groups)-1; } $index = 0; while ($index < $trim) { array_pop($groups); $index++; } # Remove left side second, but leave at least 1 element (right most); $trim = abs($opt['left']); if ( $trim >= count($groups) ) { $trim = count($groups)-1; } $index = 0; while ($index < $trim) { array_shift($groups); $index++; } if ( $firstlast and $firstlast != 0) { if ( $firstlast > 0) { // Positive; I.e. first $firstlast = abs($firstlast); $groups = array_slice($groups, 0, $firstlast); } else { // Negitive; I.e. last $firstlast = abs($firstlast); $groups = array_slice($groups, -$firstlast); } } // Return links; $index = 0; foreach($groups as $item) { if ( $index != 0) { $out.= $opt['separator']; } if ( $opt['return'] == 'links' ) { $out.= '[['; $out.= $item['path'].'/|'; $out.= $item['name']; $out.= ']]'; } elseif ( $opt['return'] == 'groups' ) { $out.= $item['path']; } elseif ( $opt['return'] == 'names' ) { $out.= $item['name']; } else { return ("Error:ClusterSlice:Unknown return style: ".$opt['return']); } $index++; } return $out; } // }}} // ------------------------------------------------------------------------