=====Division between Pages and categories in a Category===== >>Working for 1.3.6 (latest)>>''03/31/2016:version 2.1 (see below).'' this version builds on the beta-version from JavaWoman (running on this wiki) and has in total the following cchanges to the official action: - pages belong to categories if you use the following markup: ""[[(cat)Name]]"". ""[[(cat)Name Alternative name for the link]]"" does work, too - pages only need the category-action inside them, no more need for a name starting with "Category" - template-pages , i.e. page-names ending with "template" are not shown, unless you force it or their name starts with "Category" - output can be shown as a single list, or in a number of columns - it is possible to show only (sub)"categories" or "pages" or "all" (both). In the last case, categories and pages are shown seperate and not in one list/column Todo: - extra css-class for ""[[(cat)..."" - TESTING - upgrade-script - code redundancies into a function? - making name for main-category customizable - possibility to show the alternative name in the markup in the categorylist instead of the page-name?? - possibility to show the pages belonging to the subcategories, too? Which depth? Problem of recursion! What if a page belongs to a category and a subcategory? - possible? use a single list also for columns, using CSS to visually split up into columns - JW 2005-01-19 - update the todo-list in the action ;-) ===Explanations=== The new search-method uses two queries instead of one: one search for subcategories (searching for the category-action) and another for pages (searching for the new link version) belonging to a category (they only load the name, since we know from the search if its a category or not). This allows any page to become a category, their names don't have to start with "Category" anymore. For this reason, i took the "forcecat" param out (if you put the action, for example, on the SandBox without "categorylinking" any page it will simply show that nothing could be found). ===Comments?=== ===Installation=== Three things have to be changed: ==1. addition to formatters/wakka.php== right before %%(php) // forced links // \S : any character that is not a whitespace character // \s : any whitespace character %% add the following: %%(php) //links to category pages else if (preg_match("/^\[\[\(cat\)(\S+)(\s(.+))*\]\]$/si", $thing, $matches)) { list(, $categorylink, $text) = $matches; if ($categorylink) { return $result.$wakka->Link($categorylink, "", $text); } else { return ""; } } %% ==2. library/common/showarray.php== The following file has to be saved as ##library/common/showarray.php##: %%(php;1) '."\n"; //how many lines with an entry in every column do we have? while ($entries / $colnumber > 1) { $lines++; $entries = $entries - $colnumber; } //prepare output for ($i=0;$i<$colnumber;$i++) { $str .='
'."\n"; for ($j=0;$j<$lines;$j++) { $str .= ' '.$array[$a].'
'."\n"; $a++; } //the rest of the entries (less then the number of cols) if ($entries) { $str .= ' '.$array[$a].'
'."\n"; $entries--; $a++; } $str .="
\n"; } $str .= '
'."\n"; return ($str); } $str .= 'The data delivered to the function ShowArrayInColumns was no array.'; return ($str); } /** * Sorts a given array as a list. * * @package Library * @subpackage Common * @name ShowArray * * @author {@link http://wikka.jsnx.com/JsnX JsnX} (list) * @author {@link http://wikka.jsnx.com/NilsLindenberg NilsLindenberg} (function and "divison" of the array) * @copyright Copyright © 2004, * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @since Wikka 1.0.0 * * @input array $array necessary: the data to be shown * @input string $class optional: class(es) to determine styling of the output list of table; default: none. * @output list of data from an array, formatted as a list * */ function ShowArrayAsList($array,$class="") { $str = ""; if (is_array($array)) { $entries = count($array); $str .= ''."\n"; $str .= "\n\n"; return ($str); } $str .= "The data delivered to the function ShowArrayAsList was no array."; return ($str); } ?> %% ==3. Plugin this in plugins/actions/category/category.php== %%(php) htmlspecialchars_ent($vars['col']); # 'compact' option $compact = 0; if(isset($vars['compact'])) $compact = $this->htmlspecialchars_ent($vars['compact']); # 'class' option $class = 0; if(isset($vars['class'])) $class = $this->htmlspecialchars_ent($vars['class']); # 'sort' option $sort = 'ASC'; if(isset($vars['sort'])) { $val_sort = strtoupper($this->htmlspecialchars_ent($vars['sort'])); if(in_array($val_sort, ['ASC','DESC'])) $sort = $val_sort; } # 'inctpl' option $inctpl = FALSE; if(isset($vars['inctpl'])) $inctpl = TRUE; # 'show' option $show = 'all'; if(isset($vars['all'])) { $val_show = $this->htmlspecialchars_ent($vars['class']); if(in_array($val_show, ['all','pages','categories'])) $show = $val_show; } # 'page' option if(isset($vars['page'])) $page = $this->htmlspecialchars_ent($vars['page']); else { #232 : if page is not given, and if this action is called from an included page, use the name of the page that is included # and not the caller's PageTag. if (isset($this->config['includes']) && is_array($this->GetConfigValue('includes'))) { $count = count($this->GetConfigValue('includes')) - 1; $page = $this->config['includes'][$count]; echo $page.":"; print_r($this->config['includes']); } else { $page=$this->GetPageTag(); } } if ($page=="/") $page="CategoryCategory"; if (!$inctpl && preg_match('/Template$/',$page)) { if (!preg_match('/^Category/',$page)) $page = 'CategoryCategory'; # exception for a category that contains templates } //searching for categories belonging to the requested category, if necessary, and preparing the output if ($show == 'all' || $show == 'categories') { $categorySearchphrase = " SELECT tag AS page_tag FROM ".$this->GetConfigValue('table_prefix')."links INNER JOIN ".$this->GetConfigValue('table_prefix')."pages ON from_tag = tag AND latest = 'Y' AND body LIKE '%[[(cat)".$page."]]%' AND body LIKE '%{{category%' GROUP BY tag ORDER BY tag ".strtoupper($sort); $results = $this->LoadAll($categorySearchphrase); // filter what we show AS content of the requested category if($keys = array_keys(array_column($results, 'page_tag'), ['CategoryCategory', $page])) foreach($keys as $key) unset($results[$key]); $errmsg = ''.sprintf(T_("No categories found for %s"), $page).''; $list_pages_option = array( 'nopagesText' => $errmsg, 'class' => $class, 'columns' => $col, 'sort' => 'no', 'compact' => $compact ); $str = $this->ListPages($results, $list_pages_option); print($this->Format(T_("=====Categories====="))); if ($str != $errmsg) { if(1 < count($results)) printf(T_("The following %d categories belong to %s").'

', count($results), $page); else printf(T_("The following category belongs to %s").'

', $page); } print($str); } //if necessary, a division between the categories and the pages if ($show == 'all') print('

'); if ($show == 'all' || $show == 'categories') { $categorySearchphrase = " SELECT tag AS page_tag FROM ".$this->GetConfigValue('table_prefix')."links INNER JOIN ".$this->GetConfigValue('table_prefix')."pages ON from_tag = tag AND latest = 'Y' AND body LIKE '%[[(cat)".$page."]]%' AND body NOT LIKE '%{{category%' GROUP BY tag ORDER BY tag ".strtoupper($sort); $results = $this->LoadAll($categorySearchphrase); // filter what we show AS content of the requested category if($keys = array_keys(array_column($results, 'page_tag'), ['CategoryCategory', $page])) foreach($keys as $key) unset($results[$key]); $errmsg = ''.sprintf(T_("No pages found for %s"), $page).''; $list_pages_option = array( 'nopagesText' => $errmsg, 'class' => $class, 'columns' => $col, 'sort' => 'no', 'compact' => $compact ); $str = $this->ListPages($results, $list_pages_option); print($this->Format(T_("=====Pages====="))); if ($str != $errmsg) { if(1 < count($results)) printf(T_("The following %d pages belong to %s").'

', count($results), $page); else printf(T_("The following page belongs to %s").'

', $page); } print($str); } ?> %% ====Older Versions==== >>Working for 1.1.6.0 to 1.1.6.4 (latest)>>''04/04/2005:version 2.0 (see below).'' ===Installation=== Three things have to be changed: ==1. addition to formatters/wakka.php== right before %%(php) // forced links // \S : any character that is not a whitespace character // \s : any whitespace character %% add the following: %%(php) //links to category pages else if (preg_match("/^\[\[\(cat\)(\S+)(\s(.+))*\]\]$/si", $thing, $matches)) { list(, $categorylink, $text) = $matches; if ($categorylink) { if (!$help) $help = $categorylink; return $result.$wakka->Link($categorylink, "", $text); } else { return ""; } } %% ==2. library/common/showarray.php== The following file has to be saved as ##library/common/showarray.php##: %%(php;1) '."\n"; //how many lines with an entry in every column do we have? while ($entries / $colnumber > 1) { $lines++; $entries = $entries - $colnumber; } //prepare output for ($i=0;$i<$colnumber;$i++) { $str .='
'."\n"; for ($j=0;$j<$lines;$j++) { $str .= ' '.$array[$a].'
'."\n"; $a++; } //the rest of the entries (less then the number of cols) if ($entries) { $str .= ' '.$array[$a].'
'."\n"; $entries--; $a++; } $str .="
\n"; } $str .= '
'."\n"; return ($str); } $str .= 'The data delivered to the function ShowArrayInColumns was no array.'; return ($str); } /** * Sorts a given array as a list. * * @package Library * @subpackage Common * @name ShowArray * * @author {@link http://wikka.jsnx.com/JsnX JsnX} (list) * @author {@link http://wikka.jsnx.com/NilsLindenberg NilsLindenberg} (function and "divison" of the array) * @copyright Copyright © 2004, * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @since Wikka 1.0.0 * * @input array $array necessary: the data to be shown * @input string $class optional: class(es) to determine styling of the output list of table; default: none. * @output list of data from an array, formatted as a list * */ function ShowArrayAsList($array,$class="") { $str = ""; if (is_array($array)) { $entries = count($array); $str .= ''."\n"; $str .= "\n\n"; return ($str); } $str .= "The data delivered to the function ShowArrayAsList was no array."; return ($str); } ?> %% ==3. Replacement of actions/category.php== %%(php) tag; # current page is default category $lCol = 1; # one column for table $lCompact = FALSE; # use table, not list $lClass = ''; # no class $lShow = 'all'; # show pages and categories $lOutput = ''; # the final output // get parameters if (is_array($vars)) { foreach ($vars as $param => $value) { switch ($param) { case 'inctpl': if ($value) $lIncTpl = TRUE; break; case 'page': if ($this->existsPage($value)) $lPage = $value; break; case 'col': if ($value === (string)(int)$value && (int)$value > 0) $lCol = (int)$value; break; case 'compact': if ($value) $lCompact = TRUE; break; case 'class': if ('' != $value) $lClass = $value; break; case 'show': if ($value == 'pages' || $value == 'categories') $lShow = $value; break; } } } // filter WHICH category we (may) show the content OF if ($lPage == '/') { $lPage = 'CategoryCategory'; } if (!$lIncTpl && preg_match('/Template$/',$lPage)) { if (!preg_match('/^Category/',$lPage)) $lPage = 'CategoryCategory'; # exception for a category that contains templates } //searching for categories belonging to the requested category, if necessary, and preparing the output if ($lShow == 'all' || $lShow == 'categories') { $lCategorySearchphrase = "SELECT tag FROM ".$this->config['table_prefix']."pages WHERE latest = 'Y' AND body LIKE '%[[(cat)".$lPage."%' AND body LIKE '%{{category%'"; $categoryresults = $this->LoadAll($lCategorySearchphrase); //print_r($categoryresults); //DEBUG if ($categoryresults) { $categorylist = array(); // filter what we show AS content of the requested category foreach ($categoryresults as $ccategory) { // do not list top-level category as member if ('CategoryCategory' == $ccategory['tag']) { continue; } // do not list requested category as member if ($ccategory['tag'] == $lPage) { continue; } // we have a valid result: add to the list if ($lCompact) { $categorylist[] = $this->Link($ccategory['tag'],'',preg_replace( "/Category/", "",$ccategory['tag'])); } else { $categorylist[] = $this->Link($ccategory['tag'],'',preg_replace( "/Category/", "",$ccategory['tag'])); } } sort($categorylist); // make simple list (useful for sidebar) if ($lCompact) { $lOutput .= ShowArrayAsList($categorylist,$lClass); } // make columnar overview (useful for category pages) else { $categorycount = count($categorylist); $lOutput .= 'The following '.$categorycount.' categories belong to '.$lPage.':

'."\n"; #i18n $lOutput .= ShowArrayInColumns($categorylist, $lCol, $lClass); } } else { $lOutput .= 'No categories found for '.$lPage.".\n"; #i18n } } //if necessary, a division between the categories and the pages if ($lShow == 'all') $lOutput .= '

'; //searching for pages belonging to the requested category, if necessary, and preparing the output if ($lShow == 'all' || $lShow == 'pages') { $lPageSearchphrase = "SELECT tag FROM ".$this->config['table_prefix']."pages WHERE latest = 'Y' and body LIKE '%[[(cat)".$lPage."%' AND body NOT LIKE '%{{category%'"; $pageresults = $this->LoadAll($lPageSearchphrase); //print_r($pageresults); //DEBUG if ($pageresults) { $pagelist = array(); // filter what we show AS content of the requested category foreach ($pageresults as $cpage) { // do not list requested category as member if ($cpage['tag'] == $lPage) { continue; } // unless inctpl is set, do not list template pages elseif (!$lIncTpl && preg_match('/Template$/', $cpage['tag'])) { continue; } // we have a valid result: add to the list if ($lCompact) { $pagelist[] = $this->Link($cpage['tag'],'',$cpage['tag']); } else { $pagelist[] = $this->Link($cpage['tag']); } } sort($pagelist); // make simple list (useful for sidebar) if ($lCompact) { $lOutput .= ShowArrayAsList($pagelist,$lClass); } // make columnar overview (useful for category pages) else { $pagecount = count($pagelist); $lOutput .= 'The following '.$pagecount.' pages belong to '.$lPage.':

'."\n"; #i18n $lOutput .= ShowArrayInColumns($pagelist, $lCol, $lClass); } } else { $lOutput .= 'No pages found for '.$lPage.".\n"; #i18n } } echo $lOutput; ?> %% ---- CategoryDevelopmentActions