<?php if (!defined('PmWiki')) exit(); define(WPCATEGORIES_VERSION, '1.6'); $RecipeInfo['WPCategories']['Version']='2007-10-07 - v1.6'; /* Copyright 2005-2007 Mateusz Czaplinski (mateusz@czaplinski.pl) This file is WPCategories.php; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This script partially implements Wikipedia-like (Wikipedia is a free encyclopedia located at http://wikipedia.org) categories functionality. It collects all links to pages in Category group on a page and displays them all in one place in the page footer. To use this script, simply copy it into the cookbook/ directory and add the following line to config.php (or a per-page/per-group customization file). include_once('cookbook/WPCategories.php'); From then on, every page in the Category group (or other you configured - see http://pmwiki.org/wiki/Cookbook/WPCategories for configuration details) you'll see a list of all pages belonging to that category (that is, linking to it). For more details, visit http://pmwiki.org/wiki/Cookbook/WPCategories ---- History: ---- * 2007-10-07 - v1.6 - modified for compatibility with Cookbook:MarkupExpressions * 2007-09-30 - v1.5 - $EnableWPCategoriesInline to collect links not only from line beginning - duplicates in the categories box are removed */ ## The group, links to which are collected. SDV( $WPCategoriesGroup, 'Category' ); ## Making internationalisation easier. ## This string is used in the categories-box at the bottom of the page. SDV( $WPCategoriesPlural, 'Categories' ); ## This string is used on every Category-group page, above the ## category pages listing. SDV( $WPCategoriesListingHeader, '!! Articles in category "$Namespaced"' ); ## Whether to automatically add backlinks-listing to all ## Category-group pages. SDV( $WPCategoriesAutoBacklinks, 1 ); ## These variables form the HTML markup for a categories-box ## rendered in page footer. ## The box is rendered as: ## $WPCategoriesPre CategoryLink1 $WPCategoriesBetween CategoryLink2 ... ## $WPCategoriesPost ## SDV( $WPCategoriesPre, '<div class="WPCategoriesBox">' . $WPCategoriesPlural . ': ' ); SDV( $WPCategoriesBetween, ' | ' ); SDV( $WPCategoriesPost, '</div>' ); SDV( $HTMLStylesFmt['WPCategories'], '.WPCategoriesBox { border: 1px solid #aaa; background-color: #f9f9f9; margin-top: 1em; clear: both; padding: .5em 5px .6em 5px; line-height: 1.5em; } '); ## internal. Here we'll collect the links. $WPCategoriesStack = array(); ## Markup for finding links to categories. Sample links are: ## [[Category:Something]] ## [[Category.Foo bar]] ## [[Category/BarFoo]] ## Note, that other link formats (like [[(Category.)Foobar]], ## [[Category.Foobar]], [[Category/Foobar]] ) are not ## recognised (or at least that's what I aimed for...)! Markup( 'CollectCategoryLinks', '<links', '/^\\[\\[' . $WPCategoriesGroup . '[\\.\\/:]([^\\|]*?)\\]\\]/e', "WPCategoriesCollect('\$1')" ); ## Markup for collecting 'PmWiki native category links' of the ## form: [[!Name of category]] ## (equivalent of: [[Category.Name of category]]) Markup( 'Collect!CategoryLinks', '>CollectCategoryLinks', '/^\\[\\[!([^\\|]*?)\\]\\]/e', "WPCategoriesCollect('\$1')" ); if( IsEnabled($EnableWPCategoriesInline,0) ) { Markup( 'CollectCategoryLinks-inline', '>CollectCategoryLinks', '/(\\[\\[' . $WPCategoriesGroup . '[\\.\\/:]([^\\|]*?)\\]\\])/e', "WPCategoriesCollect('\$2','\$1')" ); Markup( 'Collect!CategoryLinks-inline', '>Collect!CategoryLinks', '/(\\[\\[!([^\\|]*?)\\]\\])/e', "WPCategoriesCollect('\$2','\$1')" ); } ## internal. ## A (:WPCategoriesList:) markup variable. It will be substituted ## with the Category-box. See also the "Implementation note" below, ## and WPCategoriesShow(). Markup( 'DisplayCategoryLinks', '>Collect!CategoryLinks', '/\\(:WPCategoriesList:\\)/e', 'WPCategoriesShow()' ); ## Add a backlinks-listing to all Category-group pages. if( $WPCategoriesAutoBacklinks ) $WPCategoriesListPages = '(:if group ' . $WPCategoriesGroup . ":)\n" . FmtPageName( $WPCategoriesListingHeader, $pagename ) . "\n" . '(:pagelist link={$Group}.{$Name} list=normal:)' . '(:if:)'; else $WPCategoriesListPages = ''; ## Showing the Categories-box in the page footer. ## ## Implementation note: ## We're doing that by using a new markup directive. $GroupFooterFmt = $WPCategoriesListPages . '(:WPCategoriesList:)' . $GroupFooterFmt; ## internal. ## This function is invoked when Category-link markup is found. ## It removes the link from the page, stacking it for later usage. function WPCategoriesCollect( $category, $keep=FALSE ) { global $WPCategoriesStack, $WPCategoriesGroup; global $LinkTargets; $WPCategoriesStack[] = '[[' . $WPCategoriesGroup . '/' . $category . ']]'; ## We have removed the link from the page above; the (not so) side ## effect is, that PmWiki engine won't know there's a certain link in ## the page at all, and thus it won't be saved in a special attribute of ## the page, named 'targets' (*). That'd result in the page not showing ## in Category's backlinks, what is certainly bad. Therefore, we must ## take the hacky way and add it to said attribute ourselves: @$LinkTargets[ MakePageName( $pagename, $WPCategoriesGroup . '/' . $category ) ]++; ## (*) That's because PmWiki collects page links information when ## saving the page, by running Markup-substitution, results of ## which are then ignored, apart from a special global variable ## $LinkTargets, which is set by link-parsing Markup handlers. return $keep ? $keep : ''; } ## internal. ## This function renders the Categories box when a special (:WPCategoriesList:) ## markup is found. function WPCategoriesShow() { global $WPCategoriesStack, $WPCategoriesPre, $WPCategoriesBetween, $WPCategoriesPost; if( $WPCategoriesStack ) { ## array_keys(array_flip($a)) returns unique values ## (reference: http://www.php.net/manual/en/function.array-unique.php) return FmtPageName( $WPCategoriesPre . implode($WPCategoriesBetween, array_keys(array_flip($WPCategoriesStack))) . $WPCategoriesPost, $pagename ); } else return ''; }