Advanced Category Action

Installed as an alpha feature on this server as of 2005-06-12.

This is the development page for a "more advanced" version of the category action. The version presented on this page is a further development of the beta version already running on this site (with as its main feature a more structural and readable columnar layout), borrows ideas from NilsLindenberg's PageAndCategoryDivisionInACategory, while adding new functionality and flexibility.

In fact, it takes the possibilities of the current category system to its practical limits in what it is capable of for category navigation. While a category system overhaul definitely will be needed to support new functionality, this should help to tide us over until we have designed and implemented a new system.
 

Improvements and new functionality


Features


Syntax

{{category [cat="categoryname"] [show="all|categories|pages|members"] [type="cols|list|related"] [cols="n"] [catnames="0|1"] [inctpl="0|1"] [class="class"] [head="main heading"]}}

Use cases


later


The code


This code completely replaces the current ./actions/category.php file (make a backup if you want to try it out). Although it uses some new parameters it is still completely compatible with the current (1.1.6.0) category action; the new parameters take precence over the old ones though.

Note that this is still 'somewhat' beta code and currently contains (commented out) some debug code; this will be cleaned up later.

  1. <?php
  2. /**
  3.  * Generates a list of pages belonging to the specified or top-level category.
  4.  *
  5.  * If no category page is specified, the current page is assumed to be a category (or the 'base' page
  6.  * for the 'related pages' feature).
  7.  *
  8.  * Features:
  9.  * - specify whether to show subcategories, pages, or both; separate or all together as "members"
  10.  * - specify whether to format the output as columns or as a "flat" list
  11.  * - list 'related pages': pages other than the current one that are in the same category or categories
  12.  *   (output will always be in the form of one or more lists)
  13.  * - specify a class name as 'hook' for styling
  14.  * - lists are generated as type 'menu' so they can be given "menu" styling
  15.  * - specify a (main) heading to override the built-in defaults
  16.  *
  17.  * There are two possible "contexts" for the action:
  18.  * - A category (either the current category page or specified with the cat parameter): used to list
  19.  *   members of that category. The action can be <b>used</b> on any page; if not a category page, the cat
  20.  *   parameter must be specified in order to list category members (otherwise the action will revert to
  21.  *   list the content of the top-level category).
  22.  * - a content page for the 'related pages' feature. To list related pages, specify type='related' and
  23.  *   (optionally) the category to list (other) member pages of. If no category is specified, all
  24.  *   categories of the current page are considered; if a category is specified, it will be considered
  25.  *   only if it is actually one of the categories the current page belongs to.
  26.  *
  27.  * Several features are dependent on a naming convention where each category ("category page") starts
  28.  * with 'Category'. While it's (technically) possible to have categories without this naming convention,
  29.  * this makes features like separating subcategories from content pages in a listing impossible.
  30.  * The default is to assume the naming convention is used; if not, override this behavior with a
  31.  * catnames="0" parameter: the action will then ignore any contradictory parameters and revert to just
  32.  * listing 'members' of the current or requested category.
  33.  *
  34.  * Template pages (created specifically to clone from) are normally not "real" content pages; the default
  35.  * is to filter these pages (so only actual content pages are listed), which will only work if the
  36.  * naming convention for them is followed by ending the page name with 'Template'. This behavior can
  37.  * be overridden by specifying an inctpl="1" parameter. One exception: page names that start with
  38.  * 'Category' and end with 'Template' are considered a proper category, intended to contain templates:
  39.  * all members of such a 'template category' are considered even when the 'inctpl' parameter is set to 0.
  40.  *
  41.  * Note: the list view (type='list' or type='related') is nice for a sidebar while the columnar view
  42.  * (type='cols') is more suited as content for a category page.
  43.  *
  44.  * Syntax:
  45.  *  {{category [cat="categoryname"] [show="all|categories|pages|members"] [type="cols|list|related"] [cols="n"] [catnames="0|1"] [inctpl="0|1"] [class="class"] [head="main heading"]}}
  46.  *
  47.  * Old (version 1) parameters are supported for compatibility but new ones take precedence.
  48.  *
  49.  * @todo        - possible? use a single list also for columns, using CSS to visually split up into columns - JW 2005-01-19
  50.  *
  51.  * @package     Actions
  52.  * @subpackage  SystemContent
  53.  * @name        Category
  54.  *
  55.  * @author      {@link http://wikka.jsnx.com/JsnX JsnX}
  56.  * @author      {@link http://wikka.jsnx.com/NilsLindenberg NilsLindenberg} (separation into subcategories and pages)
  57.  * @author      {@link http://wikka.jsnx.com/JavaWoman JavaWoman} (complete rewrite, filtering, table-less columns and 'related pages' functionality)
  58.  * @copyright   Copyright © 2005, Marjolein Katsma
  59.  * @license     http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  60.  * @since       Wikka 1.0.0
  61.  * @version     2.5beta
  62.  *
  63.  * @input       string  $cat        optional: category to list members of; default: current page or CategoryCategory
  64.  *                                  You can specify '/' as a shortcut for CategoryCategory
  65.  * @input       string  $show       optional: all|categories|pages|members; default: all; or members if $catnames
  66.  *                                  is 0.
  67.  * @input       string  $type       optional: cols|list|related; default: cols.
  68.  *                                  - cols: multi-column display, list everything. (Useful for category pages)
  69.  *                                  - list: single list, strips 'Category' from category (page) names.
  70.  *                                  (Useful for sidebar)
  71.  *                                  - related:  "related pages": list(s) with pages in the same categories as
  72.  *                                  the current page, or in requested category only; excluding the current page.
  73.  *                                  (useful for sidebar)
  74.  *
  75.  * @input       integer $catnames   optional: consider only category names (pages) that start with 'Category' as a
  76.  *                                  category (the name test is case-insensitive); default: 1
  77.  *                                  set to 0 if there is no naming convention for categories!
  78.  * @input       integer $inctpl     optional: include "template" pages (1) or not (0); default: 0.
  79.  * @input       integer $cols       optional: number of columns to use; default: 1 (only relevant for type"cols")
  80.  * @input       integer $class      optional: class(es) to determine styling of the output list or columns
  81.  * @input       string  $head       optional: override of built-in main heading; you can specify a '%s' placeholder
  82.  *                                  for the requested category in a category members listing (type="cols|list")
  83.  *
  84.  * @input       string  $page       DEPRECATED (optional): superseded by $cat (synonym)
  85.  * @input       integer $compact    DEPRECATED (optional): use columns (0) or list (1); superseded by $type
  86.  * @input       integer $col        DEPRECATED (optional): superseded by $cols
  87.  *
  88.  * @output      string  list of pages belonging to the specified or top-level category, formatted as a list
  89.  *                      or columns of items
  90.  *
  91.  * @uses        CheckMySQLVersion()
  92.  * @uses        getCatMembers()
  93.  * @uses        Link()
  94.  * @uses        makeId()
  95.  * @uses        makeMemberList()
  96.  * @uses        makeMemberCols()
  97.  */
  98.  
  99. // ----------------- utility functions ------------------
  100.  
  101. if (!function_exists('buildMemberList'))
  102. {
  103.     function buildMemberList($member,&$list,$cat,$bIncTpl)
  104.     {
  105.         global $wakka;
  106.         if (
  107.             (FALSE === $bIncTpl && preg_match('/(.+)Template$/',$member)) ||# template filter
  108.             ('CategoryCategory' == $member) ||                              # do not list top-level category as member
  109.             ($member == $cat)                                               # do not list requested category as member
  110.            )
  111.         {
  112. #echo '(Members) Filtered: '.$member.'<br/>';
  113.             // do nothing
  114.         }
  115.         else
  116.         {
  117.             $list[] = $wakka->Link($member);
  118.         }
  119.     }
  120. }
  121. if (!function_exists('buildCatList'))
  122. {
  123.     function buildCatList($member,&$list,$cat,$type)
  124.     {
  125.         global $wakka;
  126.         if (
  127.             (!preg_match('/^Category/',$member)) ||                         # only category pages count
  128.             ('CategoryCategory' == $member) ||                              # do not list top-level category as member
  129.             ($member == $cat)                                               # do not list requested category as member
  130.            )
  131.         {
  132. #echo '(Cats) Filtered: '.$member.'<br/>';
  133.             // do nothing
  134.         }
  135.         else
  136.         {
  137.             if ('cols' == $type)
  138.             {
  139.                 $list[] = $wakka->Link($member);
  140.             }
  141.             elseif ('list' == $type)
  142.             {
  143.                 $list[] = $wakka->Link($member,'',preg_replace('/^Category/','',$member));
  144.             }
  145.         }
  146.     }
  147. }
  148. if (!function_exists('buildPageList'))
  149. {
  150.     function buildPageList($member,&$list,$cat,$bIncTpl,$type,$page)
  151.     {
  152.         global $wakka;
  153.         if (
  154.             (preg_match('/^Category/',$member)) ||                          # categories filter (only pages count)
  155.             (FALSE === $bIncTpl && preg_match('/Template$/',$member)) ||    # template filter
  156.             ('related' == $type && $member == $page)                        # current page filter
  157.            )
  158.         {
  159. #echo '(Pages) Filtered: '.$member.'<br/>';
  160.             // do nothing
  161.         }
  162.         else
  163.         {
  164.             if ('related' == $type)
  165.             {
  166. #echo "adding member $member for cat $cat<br/>";
  167.                 $list[$cat][] = $wakka->Link($member);
  168.             }
  169.             else
  170.             {
  171. #echo 'adding '.$member.'<br/>';
  172.                 $list[] = $wakka->Link($member);
  173.             }
  174.         }
  175.     }
  176. }
  177.  
  178. // ----------------- constants and variables ------------------
  179.  
  180. // constants
  181. $aShow      = array('all','categories','pages','members');
  182. $aType      = array('cols','list','related');
  183. if (!defined('PAT_PAGENAME_CHARS'))     define('PAT_PAGENAME_CHARS','A-Za-z0-9ÄÖÜßäöü')# NOT within [] so we can use if for a negative class as well
  184.  
  185. // set defaults
  186. $lCat       = NULL;         # no predefined default
  187. $lShow      = 'all';        # both categories and pages
  188. $lType      = 'cols';       # default display type
  189. $bCatNames  = TRUE;         # only pages starting with 'Category' are considered category pages
  190. $bIncTpl    = FALSE;        # do not show template pages or treat a template as a category
  191. $lCols      = 1;            # one column for columnar layout
  192. $lClass     = '';           # no class
  193. $lHead      = NULL;         # specified heading (may contain place holder for category)
  194.  
  195. // initializations
  196. $bCatDefined = FALSE;
  197. $bCategoryPage = preg_match('/^Category/',$this->tag);
  198.  
  199. // User-interface strings
  200. if (!defined('HD_COL'))             define('HD_COL','Members of the %s Category');
  201. if (!defined('HD_LST'))             define('HD_LST','%s');
  202. if (!defined('HD_REL'))             define('HD_REL','Related pages');
  203.  
  204. if (!defined('COL_MEMBERS_FOUND'))  define('COL_MEMBERS_FOUND','Category %2$s consists of the following %1$d members:');
  205. if (!defined('COL_CATS_FOUND'))     define('COL_CATS_FOUND','The following %1$d categories belong to %2$s:');
  206. if (!defined('COL_PAGES_FOUND'))    define('COL_PAGES_FOUND','The following %1$d pages belong to %2$s:');
  207. if (!defined('HD_LST_MEMBERS'))     define('HD_LST_MEMBERS','Members');
  208. if (!defined('HD_LST_CATS'))        define('HD_LST_CATS','Categories');
  209. if (!defined('HD_LST_PAGES'))       define('HD_LST_PAGES','Pages');
  210. if (!defined('LST_MEMBERS_FOUND'))  define('LST_MEMBERS_FOUND','%d Members:');
  211. if (!defined('LST_CATS_FOUND'))     define('LST_CATS_FOUND','%d Categories:');
  212. if (!defined('LST_PAGES_FOUND'))    define('LST_PAGES_FOUND','%d Pages:');
  213. if (!defined('REL_PAGES_FOUND'))    define('REL_PAGES_FOUND','in %2$s (%1$d):');    # note (required) parameter order!
  214.  
  215. if (!defined('COL_NONE_FOUND'))     define('COL_NONE_FOUND','No items found for %s.');
  216. if (!defined('COL_NO_CATS_FOUND'))  define('COL_NO_CATS_FOUND','No subcategories found in %s.');
  217. if (!defined('COL_NO_PAGES_FOUND')) define('COL_NO_PAGES_FOUND','No pages found in %s.');
  218. if (!defined('LST_NONE_FOUND'))     define('LST_NONE_FOUND','No items found.');
  219. if (!defined('LST_NO_CATS_FOUND'))  define('LST_NO_CATS_FOUND','No subcategories found.');
  220. if (!defined('LST_NO_PAGES_FOUND')) define('LST_NO_PAGES_FOUND','No pages found.');
  221. if (!defined('REL_NONE_FOUND'))     define('REL_NONE_FOUND','None found.');
  222.  
  223. // --------------------------- processsing --------------------------
  224.  
  225. // --------------- get parameters ----------------
  226.  
  227. if (is_array($vars))
  228. {
  229.     foreach ($vars as $param => $value)
  230.     {
  231.         switch ($param)
  232.         {
  233.             // 1 - context
  234.             case 'cat':
  235.                 if ($this->existsPage($value)) $tCat = $value;
  236.                 break;
  237.             case 'page':
  238.                 if ($this->existsPage($value)) $tPage = $value;
  239.                 break;
  240.             // 2 - what
  241.             case 'show':
  242.                 if (in_array($value,$aShow)) $tShow = $value;
  243.                 break;
  244.             // 3 - display type
  245.             case 'type':
  246.                 if (in_array($value,$aType)) $tType = $value;
  247. #
  248. #if (isset($tType)) echo '(valid) input type: '.$tType.'<br/>';
  249. #
  250.                 break;
  251.             case 'compact':
  252.                 if ($value === (string)(int)$value) $tCompact = (int)$value;
  253.                 break;
  254.             // 4 - filters
  255.             case 'catnames':
  256.                 if ($value == 0) $tCatNames = FALSE;
  257. #
  258. #if (isset($tCatNames)) echo 'CatNames FALSE<br/>';
  259. #
  260.                 break;
  261.             case 'inctpl':
  262.                 if ($value == 1) $tIncTpl = TRUE;
  263. #
  264. #if ($value == 1) echo 'include template pages<br/>';
  265. #
  266.                 break;
  267.             // 5 - presentation
  268.             case 'cols':
  269.                 if ($value === (string)(int)$value) $tCols = abs((int)$value);
  270.                 break;
  271.             case 'col':
  272.                 if ($value === (string)(int)$value) $tCol = abs((int)$value);
  273.                 break;
  274.             case 'class':
  275.                 $tClass = trim(strip_tags($value));
  276.                 break;
  277.             case 'head':
  278.                 $tHead = trim(strip_tags($value));
  279.         }
  280.     }
  281. }
  282.  
  283. // ------------- process parameters --------------
  284.  
  285. // filters
  286. if (isset($tCatNames))  $bCatNames = $tCatNames;
  287. #
  288. #if ($bCatNames) echo 'catnames on<br/>'; else echo 'catnames not on: cannot distinguish pages from categories!!<br/>';
  289. #
  290.  
  291. // determine which category/categories to look at
  292. if (isset($tCat))
  293. {
  294.     $bCatDefined = TRUE;
  295.     $tempCat = ('/' == $tCat) ? 'CategoryCategory' : $tCat;     # '/' = shortcut for top-level category
  296. }
  297. elseif (isset($tPage))                                          # DEPRECATED
  298. {
  299.     $bCatDefined = TRUE;
  300.     $tempCat = ('/' == $tPage) ? 'CategoryCategory' : $tPage;   # '/' = shortcut for top-level category
  301. }
  302. else
  303. {
  304.     $tempCat = $this->tag;                                      # fallback current page for no specified category
  305. }
  306.  
  307. // derive display type
  308. if (isset($tType))
  309. {
  310.     if ('related' == $tType && (!$bCatNames))
  311.     {
  312.         $lType = 'list';                                        # fallback if category not defined or we have no naming convention
  313.     }
  314.     else
  315.     {
  316.         $lType = $tType;
  317.     }
  318. }
  319. elseif (isset($tCompact))                                       # DEPRECATED
  320. {
  321.     if (0 == $tCompact)
  322.     {
  323.         $lType = 'cols';
  324.     }
  325.     elseif (1 == $tCompact)
  326.     {
  327.         $lType = 'list';
  328.     }
  329. }
  330. //else default 'cols'
  331.  
  332. // final category (or array of categories) to consider
  333. // verify whether we have a valid category (page)
  334. if ($bCatNames && 'related' != $lType && !preg_match('/^Category/i',$tempCat))
  335. {
  336.     $lCat = 'CategoryCategory';                         # fallback category
  337. }
  338. // find categories to consider for 'related'
  339. elseif ($bCatNames && 'related' == $lType)
  340. {
  341.     $aCats = array();
  342.     if (!$bCatDefined)
  343.     {
  344. #
  345. #$relstart = getmicrotime();
  346. #
  347.         // replace every character not allowed in a page name by a space and build word array from the page
  348.         $aWords = preg_split('/\s/',preg_replace('/[^'.PAT_PAGENAME_CHARS.']/',' ',$this->page['body']));
  349.         // collect category names
  350.         foreach ($aWords as $word)
  351.         {
  352.             // a word is only a category name if 'Category' is followed by something (case-insensitive check)
  353.             if (preg_match('/^Category(.+)$/i',$word)) $aCats[] = $word;
  354.         }
  355.         $aCats = array_unique($aCats);
  356. #
  357. /*
  358. printf('Page categories found in %.6f seconds<br/>',(getmicrotime() - $relstart));
  359. echo 'categories for the current page:<pre>';
  360. print_r($aCats);
  361. echo '</pre>';
  362. */
  363. #
  364.     }
  365.     else
  366.     {
  367.         // one category defined: use (only) that IF the specified category occurs on the page!
  368.         if (preg_match('/\b'.$tempCat.'\b/',$this->page['body'])) $aCats[] = $tempCat;
  369.     }
  370. }
  371. else
  372. {
  373.     $lCat = $tempCat;
  374. }
  375.  
  376. // include templates? may depend on Category selected
  377. if (isset($tIncTpl))
  378. {
  379.     $bIncTpl = $tIncTpl;
  380. }
  381. elseif (preg_match('/^Category(.*)Template$/',$lCat))       # 'template category'
  382. {
  383.     $bIncTpl = TRUE;                                        # do show templates in a 'template category'
  384. }
  385. // else default FALSE (don't show templates)
  386.  
  387. // derive what to show
  388. if ($bCatNames)                                             # assume naming convention
  389. {
  390.     if ('related' == $lType)                                # overrides 'show' parameter for type 'related'
  391.     {
  392.         $lShow = 'pages';
  393.     }
  394.     elseif (isset($tShow))
  395.     {
  396.         $lShow = $tShow;
  397.     }
  398.     // else default 'all'
  399. }
  400. else                                                        # cannot distinguish between pages and categories!
  401. {
  402.     $lShow = 'members';
  403. }
  404. $bShowMixed = ('members' == $lShow);
  405. $bShowCats  = ('all' == $lShow || 'categories' == $lShow) ? TRUE : FALSE;
  406. $bShowPages = ('all' == $lShow || 'pages' == $lShow) ? TRUE : FALSE;
  407.  
  408. // --- presentation parameters
  409.  
  410. // columns
  411. if ('cols' == $lType)
  412. {
  413.     if (isset($tCols))                                      # overrides 'col' parameter
  414.     {
  415.         $lCols = $tCols;
  416.     }
  417.     elseif (isset($tCol))
  418.     {
  419.         $lCols = $tCol;
  420.     }
  421. }
  422. // class
  423. if (isset($tClass) && '' != $tClass) $lClass = $tClass;
  424. // main heading override
  425. if (isset($tHead) && '' != $tHead)
  426. {
  427.     $lHead = $tHead;
  428. }
  429. else
  430. {
  431.     switch ($lType)
  432.     {
  433.         case 'cols':
  434.             $lHead = HD_COL;
  435.             break;
  436.         case 'list':
  437.             $lHead = HD_LST;
  438.             break;
  439.         case 'related':
  440.             $lHead = HD_REL;
  441.             break;
  442.     }
  443. }
  444.  
  445.  
  446. // ---------------- gather data ------------------
  447.  
  448. // get the category content
  449. if ('related' == $lType)
  450. {
  451.     $pagelist = array();
  452.     foreach ($aCats as $cat)
  453.     {
  454. #
  455. #echo '- Looking at category: '.$cat.'<br/>';
  456. #
  457.         $results = $this->getCatMembers($cat);
  458.         if ($results)
  459.         {
  460.             foreach ($results as $cpage)
  461.             {
  462.                 $member = $cpage['tag'];
  463. #
  464. #echo 'considering member: '.$member.'<br/>';
  465. #
  466.                 buildPageList($member,$pagelist,$cat,$bIncTpl,$lType,$this->tag);
  467.             }
  468.         }
  469.     }
  470.     ksort($pagelist);
  471. }
  472. else
  473. {
  474. #
  475. #echo '- Looking at category: '.$lCat.'<br/>';
  476. #
  477.     $results = $this->getCatMembers($lCat);
  478.  
  479.     // gather what we show AS content of the requested category
  480.     $memberlist = array();
  481.     $catlist = array();
  482.     $pagelist = array();
  483.     if ($results)
  484.     {
  485.         foreach ($results as $cpage)
  486.         {
  487.             $member = $cpage['tag'];
  488. #
  489. #echo 'considering member: '.$member.'<br/>';
  490. #
  491.             if ($bShowMixed)
  492.             {
  493.                 buildMemberList($member,$memberlist,$lCat,$bIncTpl);
  494.             }
  495.             if ($bShowCats)
  496.             {
  497.                 buildCatList($member,$catlist,$lCat,$lType);
  498.             }
  499.             if ($bShowPages)
  500.             {
  501.                 buildPageList($member,$pagelist,$lCat,$bIncTpl,$lType,$this->tag);
  502.             }
  503.         }
  504.         sort($memberlist);
  505.         sort($catlist);
  506.         sort($pagelist);
  507.     }
  508. }
  509.  
  510. // ------------------ output ---------------------
  511.  
  512. // show resulting list(s) of items belonging to selected category/categories
  513. $str ='';
  514. switch ($lType)
  515. {
  516.     case 'cols':
  517.         $attrClass = ('' != $lClass) ? ' class="categorycols '.$lClass.'"' : ' class="categorycols"';
  518.         $head = ($bCatNames) ? sprintf($lHead,preg_replace('/^Category/','',$lCat)) : sprintf($lHead,$lCat);
  519.         // start wrapper
  520.         $str .= '<div'.$attrClass.'>'."\n";
  521.         $str .= '   <h5 id="'.$this->makeId('hn','category members').'">'.$head.'</h5>'."\n";
  522.         // members (undifferentiated)
  523.         if ($bShowMixed)
  524.         {
  525.             $hd   = sprintf(COL_MEMBERS_FOUND,count($memberlist),$lCat);
  526.             $str .= $this->makeMemberCols($memberlist,$lCols,$hd,'category members',sprintf(COL_NONE_FOUND,$lCat));
  527.         }
  528.         // categories
  529.         if ($bShowCats)
  530.         {
  531.             $hd   = sprintf(COL_CATS_FOUND,count($catlist),$lCat);
  532.             $str .= $this->makeMemberCols($catlist,$lCols,$hd,'category members',sprintf(COL_NO_CATS_FOUND,$lCat));
  533.         }
  534.         // pages
  535.         if ($bShowPages)
  536.         {
  537.             $hd   = sprintf(COL_PAGES_FOUND,count($pagelist),$lCat);
  538.             $str .= $this->makeMemberCols($pagelist,$lCols,$hd,'category members',sprintf(COL_NO_PAGES_FOUND,$lCat));
  539.         }
  540.         // end wrapper
  541.         $str .= "</div>\n";
  542.         break;
  543.     case 'list':
  544.         $attrClass = ('' != $lClass) ? ' class="categorylist '.$lClass.'"' : ' class="categorylist"';
  545.         $head = sprintf($lHead,$lCat);
  546.         // start wrapper
  547.         $str .= '<div'.$attrClass.'>'."\n";
  548.         $str .= '   <h5 id="'.$this->makeId('hn','category members').'">'.$head.'</h5>'."\n";
  549.         // members (undifferentiated)
  550.         if ($bShowMixed)
  551.         {
  552.             $hd   = LST_MEMBERS_FOUND;
  553.             $str .= $this->makeMemberList($memberlist,$hd,'category members','memberlist',LST_NONE_FOUND,'menu');
  554.         }
  555.         // categories
  556.         if ($bShowCats)
  557.         {
  558.             $hd   = LST_CATS_FOUND;
  559.             $str .= $this->makeMemberList($catlist,$hd,'category members','catlist',LST_NO_CATS_FOUND,'menu');
  560.         }
  561.         // pages
  562.         if ($bShowPages)
  563.         {
  564.             $hd   = LST_PAGES_FOUND;
  565.             $str .= $this->makeMemberList($pagelist,$hd,'category members','pagelist',LST_NO_PAGES_FOUND,'menu');
  566.         }
  567.         // end wrapper
  568.         $str .= "</div>\n";
  569.         break;
  570.     case 'related':
  571.         $attrClass = ('' != $lClass) ? ' class="categoryrel '.$lClass.'"' : ' class="categoryrel"';
  572.         $head = $lHead;
  573.         // start wrapper
  574.         $str .= '<div'.$attrClass.'>'."\n";
  575.         $str .= '   <h5 id="'.$this->makeId('hn','related pages').'">'.$head.'</h5>'."\n";
  576.         // data lists
  577.         if (count($pagelist) > 0)
  578.         {
  579.             foreach ($pagelist as $cat => $memberlist)
  580.             {
  581.                 sort($memberlist);
  582.                 $hd = sprintf(REL_PAGES_FOUND,count($memberlist),$cat);
  583.                 $str .= $this->makeMemberList($memberlist,$hd,'related pages','rellist',REL_NONE_FOUND,'menu');
  584.             }
  585.         }
  586.         else
  587.         {
  588.             $str .= '   <p>'.REL_NONE_FOUND.'</p>'."\n";
  589.         }
  590.         // end wrapper
  591.         $str .= "</div>\n";
  592.         break;
  593. }
  594.  
  595. echo $str;
  596. ?>



Supporting code


As can be seen from the docblock (and the rest of the code) this new category action requires several bits of supporting code, already posted on other pages:

Constants


The code makes use of a number of constants. See ArrayToList for the code and how to add it where.

getCatMembers()


This is used to build a list of members belonging to a particular category - see CompatibilityCode for the code and where to insert it.

makeId()


Used here to generate a unique id for headings; see GenerateUniqueId for the code and where to insert it. See also AdvancedFormatter for a bit of background an context for this method.

makeMemberCols()


Used to build a columnar display of category members - see ArrayToColumns for the code and further details.

makeMemberList()


Used to build a list of category members - see ArrayToList for the code and further details.



Minor code modifications


Thought I'd toss these changes up here just in case anyone else is trying to make similar adjustments.

I changed the code so it would remove "Category" when it appears in front of a category name for show="all|categories|pages" (it doesn't work yet for show="members", though I would like to adjust that as well):

line 139:
                $list[] = $wakka->Link($member);

to:
                $list[] = $wakka->Link($member,'',preg_replace('/^Category/','',$member));



Then, to put spaces in CamelCase words in category displays, I made these changes to the code (requires UrlBeautify changes):

line 117:
            $list[] = $wakka->Link($member);

to:
            $list[] = $wakka->Link($member,"",addspaceincamelcase($member));


lines 139 and 143:
                $list[] = $wakka->Link($member,'',preg_replace('/^Category/','',$member));

to:
                $list[] = $wakka->Link($member,'',preg_replace('/^Category/','',addspaceincamelcase($member)));


lines 167 and 172:
                $list[$cat][] = $wakka->Link($member);

to:
                $list[] = $wakka->Link($member,"",addspaceincamelcase($member));


--MovieLady



CategoryDevelopmentActions
There are 2 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki