00985: Same group link formatting
Description: For my website I wanted the sidebar to have links for each group and to further have specific CSS styling if the current page is of that group. Unfortunately, the current PmWiki only seems to offer 'selflink' and 'wikilink' classes. I wanted an additional class 'grouplink' to be added to any link that targets the same group as the current page.
I made the following changes to pmwiki.php, LinkPage function:
- new global variable $LinkGroupFmt.
- small code change -- $fmt now set as follows:
$tgtgroup = PageVar($tgtname, '$Group'); $pagegroup = PageVar($pagename, '$Group'); $fmt = ($tgtname == $pagename && $qf == '') ? $LinkPageSelfFmt : ($tgtgroup == $pagegroup) ? $LinkGroupFmt : $LinkPageExistsFmt;
- in local/config.php I added two lines:
$LinkPageSelfFmt = '<a class=\'selflink grouplink\' href=\'$LinkUrl\'>$LinkText</a>'; $LinkGroupFmt = '<a class=\'wikilink grouplink\' href=\'$LinkUrl\'>$LinkText</a>';
I have no idea if this is a good way of achieving my desired result, but it works for me. I'm adding it to PITS because I'd prefer not to have to patch every time I upgrade, and would like to know if there's a better way of achieving the same result.
You could achieve the same result without having to patch the core (see below):
- Define your own version of the
LinkPage
function into a separate source file (cookbook/linkpagegroup.php
for example), - Add your variable definitions to it,
- And register your function as the new link page handler.
You may then use it directly from local/config.php
with include_once("$FarmD/cookbook/linkpagegroup.php");
.
Related source code:
<?php if (!defined('PmWiki')) exit(); function LinkPageGroup($pagename,$imap,$path,$title,$txt,$fmt=NULL) { global $QueryFragPattern, $LinkPageExistsFmt, $LinkPageSelfFmt, $LinkPageCreateSpaceFmt, $LinkPageCreateFmt, $LinkTargets, $EnableLinkPageRelative, $LinkGroupFmt; if (!$fmt && $path{0} == '#') { $path = preg_replace("/[^-.:\\w]/", '', $path); return ($path) ? "<a href='#$path'>$txt</a>" : ''; } if (!preg_match("/^\\s*([^#?]+)($QueryFragPattern)?$/",$path,$match)) return ''; $tgtname = MakePageName($pagename, $match[1]); if (!$tgtname) return ''; $qf = @$match[2]; @$LinkTargets[$tgtname]++; if (!$fmt) { if (!PageExists($tgtname) && !preg_match('/[&?]action=/', $qf)) $fmt = preg_match('/\\s/', $txt) ? $LinkPageCreateSpaceFmt : $LinkPageCreateFmt; else { $tgtgroup = PageVar($tgtname, '$Group'); $pagegroup = PageVar($pagename, '$Group'); $fmt = ($tgtname == $pagename && $qf == '') ? $LinkPageSelfFmt : ($tgtgroup == $pagegroup) ? $LinkGroupFmt : $LinkPageExistsFmt; } } $url = PageVar($tgtname, '$PageUrl'); if (@$EnableLinkPageRelative) $url = preg_replace('!^[a-z]+://[^/]*!i', '', $url); $fmt = str_replace(array('$LinkUrl', '$LinkText'), array($url.PUE($qf), $txt), $fmt); return FmtPageName($fmt,$tgtname); } $LinkPageSelfFmt = '<a class=\'selflink grouplink\' href=\'$LinkUrl\'>$LinkText</a>'; $LinkGroupFmt = '<a class=\'wikilink grouplink\' href=\'$LinkUrl\'>$LinkText</a>'; $LinkFunctions['<:page>'] = 'LinkPageGroup';
BTW, you just come to write your own cookbook recipe. I'll let you release it as a real one ;)
Dfaure October 04, 2007, at 07:59 AM
Thanks! Of course, maintaining a whole function in a cookbook entry is actually more work than updating two lines in pmwiki.php when upgrading. Still, it's a bit cleaner I suppose. Do you happen to know if the solution is correct? I couldn't work out what $qf is used for in the original code.
- pjv
Improved Solution: Active Page Group Parents
I updated your suggestions and came up with the following solution which also adds extra information about the link. Here is an illustration, imagine a list of links possibly put in a Group header.
- Home Page
- Group 1
- Group 1 parent 1
- Group 1 parent 2
- Group 2
- Group 3
If we are currently viewing the Group 1 parent 2 then the following class names are applied to the links:
- Home Page -
wikilink
- Group 1 -
wikilink grouplink groupparentindex
- Group 1 parent 1 -
wikilink grouplink
- Group 1 parent 2 -
wikilink grouplink selflink
- Group 1 parent 1 -
- Group 2 -
wikilink
- Group 3 -
wikilink
Notice that only the group members of the currently selected page have grouplink
applied. Most important, however, is the groupparentindex
which is applied to the parent of the currently selected page. For example, the following pages:
- Vocation/Vocation
- Vocation/Flight
- Vocation/CarRental
The best way to achieve this is to overwrite the default LinkPage
function (as suggested above) using a Cookbook. Download the cookbook file and read more about it on my wiki konstruktors.com/Notes/PmWikiPageLinkClasses http://konstruktors.com/Notes/PmWikiPageLinkClasses
There is a working solution from some time -- you can have a different CSS class to links to other WikiGroups. Check it at Cookbook.ExternalLinks. --Petko November 15, 2007, at 06:18 PM