00908: Enhance the link parameter of [[PmWiki/page list(s)]] (multiple and exclusions)
See Cookbook:PageListMultiTargets for an implementation. --Petko April 14, 2013, at 09:39 AM
Description:
Feature request:
Add/allow multiple and exclusions in link parameter of page list, in the same form, style and idea as pagelist's group and name parameters.
Example
Take for instance Category.Skins.
Currently we are limited to listing only backlinks, I.e. link=Category.Skins
which is wonderful, however if we have multiple links and exclusions similar to the group
and name
params, then we gain a lot of power.
For instance, let us presume that we wish to know all of the skins that NEED updating, this then becomes a simple matter of link=Category.Skins,Category.UpdateMe
Or perhaps that do NOT need updating link=Category.Skins,-Category.UpdateMe
, etc.
In my work with feralblog2 I am finding such a feature would be REALLY handy for allowing the user to really be able to display what they want to see. In my case currently if we say do NOT want all of the 'blog' related (I.e. tagged) entries, well we are out of luck. An if we wish to know about er stories and fancy cars then we need two separate pagelists, one with link=Category.Stories and another for link=Category.Fancycars
. With the above proposed addition we could simply say link=Category.Stories,Category.Fancycars
. An in the example of not wanting to see a category, link=-Category.Blog
By allowing group/name style parameters we can do something like link=Category.Stories,-Category.Fancycars
, i.e. stories that presumably have nothing to do with fancy cars.
To a small extent we should be able to achieve this via search style "apple -pie", however in regards to categories this is far too limited. As we may mention fancy cars in passing in a page that has nothing to do with them and everything to do with stories and a link=Category.Stories -Fancycars
style listing would leave us in the dark. Where as the above proposed would allow this and do exactly what we wish.
In essence this feature is useful in particular for a nested web of categories, such that a page is in multiple categories, and when we wish to view only a particular subset of a given category, or perhaps multiple categories.
Addendum/Clarification
Er, my brain went south on me when I wrote the above didn't it?
link=Category.Skins,Category.UpdateMe
is saying all of the links to Category.Skins AND Category.UpdateMe, which is NOT at all what I was thinking.
I believe the link=Category.Skins,-Category.UpdateMe
notation is correct (pages in Category.Skins that are NOT in Category.UpdateMe.)
- sigh* This base idea even if I have the semantics confused...
I am not sure where to comment about this feature so I am putting it here. This feature would provide a great way to extend the Category feature by providing a good way to produce a list of pages based on the intersection and exclusion of pages marked with multiple categories. Currently I have to use Categories and hidden PageVariables (is hard for novice users to understand) to try and mark pages in a way that I can then automaticlly select via a pagelist command. This still falls short of what can be selected and increases, in my opinion, the complexity of the procedure needed to create a usefully marked page. It would be nice to be able to markup pages like this:
Using Multiple Categories *Monday night basketball [[!Activity]] [[!Teen]] [[!Adult]] or *ROCK Around the Clock [[!Activity]] [[!Teen]] or *Bingo at the park [[!Activity]] [[!Adult]] or *Video night [[!Activity]] [[!Single]] or *Coloring Corner Hour [[!Activity]] [[!Preschool]]
Then list pages like so:
!All adult and teen activities (:pagelist link=Category/Activity,Category/Adult,Category/Teen :) PRODUCES\\ * Monday night basketball !All teen activities (:pagelist link=Category/Activity,Category/Teen :) PRODUCES\\ * Monday night basketball * ROCK Around the Clock
Rather than using Categories and page variables (I don't know how to make the first one work)
(:Agegroup: Adult, Teen:) *Monday night basketball [[!Activity]] or (:Agegroup: Teen:) *ROCK Around the Clock [[!Activity]] or (:Agegroup: Adult:) *Bingo at the park [[!Activity]] ...
My two cents.
I'd simply like to be able to ask "give me all the categories used in the Cookbook group, eg
(:pagelist group=Cookbook link=Category.* list=normal:)
Also (or)
(:pagelist group=Cookbook link=Category/ list=normal:)
(groups)
(:pagelist group=Cookbook link=Category.w* list=normal:)
(wildcards)
Here's my implementation:
--- before.txt Wed Aug 03 14:24:23 2011 +++ after.txt Wed Aug 03 14:27:15 2011 @@ -345,9 +345,17 @@ $opt['=exclp'][] = '$'.implode('|', array_map('preg_quote',$excl)).'$i'; if (@$opt['link']) { - $link = MakePageName($pn, $opt['link']); - $opt['=linkp'] = "/(^|,)$link(,|$)/i"; - $indexterms[] = " $link "; + foreach (explode(',', $opt['link']) as $link) { + $excl = ($link[0] == '-'); + if ($excl) $link = substr($link, 1); + $link = MakePageName($pn, $link); + if ($excl) { + $opt['=linkp'][] = "-/(^|,)$link(,|$)/i"; + } else { + $opt['=linkp'][] = "/(^|,)$link(,|$)/i"; + $indexterms[] = " $link "; + } + } } if (@$opt['=cached']) return 0; @@ -365,8 +373,14 @@ case PAGELIST_ITEM: if (!$page) { $page = ReadPage($pn, READPAGE_CURRENT); $opt['=readc']++; } if (!$page) return 0; - if (@$opt['=linkp'] && !preg_match($opt['=linkp'], @$page['targets'])) - { $reindex[] = $pn; return 0; } + if (@$opt['=linkp']) { + foreach ($opt['=linkp'] as $pat) { + $excl = ($pat[0] == '-'); + if ($excl) $pat = substr($pat, 1); + if (!preg_match($pat, @$page['targets']) xor $excl) + { $reindex[] = $pn; return 0; } + } + } if (@$opt['=inclp'] || @$opt['=exclp']) { $text = $fold($pn."\n".@$page['targets']."\n".@$page['text']); foreach((array)@$opt['=exclp'] as $i)
It does not support OR operations:
link=Foo,Bar
lists pages that link to bothlink=Foo,-Bar
lists pages linking to Foo but not Bar- spreading between multiple link= statements makes no difference
I hereby release this as free for anyone to use - I'd be happy to see it in PmWiki. Maxim? August 03, 2011, at 08:53 AM
See also