[pmwiki-users] Pagelists, adjunct data pages & variable sort orders

Patrick R. Michaud pmichaud at pobox.com
Mon Oct 16 18:26:38 CDT 2006

On Mon, Oct 16, 2006 at 06:46:36PM -0400, Crisses wrote:
>    We're working on having pages like PageName-Talk as an adjunct page to
>    PageName.  PageName-Comments.  Data-Group.PageName or PageName-Data etc.
>    All these ways of having pages attached to each other, sharing data.
>    I put all the book/author information into Data-Group.PageName -- all the
>    relevant page variables are there.  And everything works except the
>    pagelist sort.  And works well.
>    Would it be a lot of trouble to fix the pagelist sorts?  Yes, says
>    Patrick.  And that's ok, this is only about one wiki.

The big reason I see it as being difficult is because I don't have a
good syntax for (:pagelist:) to be able to sort/select based on
values that are coming from pages other than the ones in the list.  If
we can solve that, it might not be so bad.

Also, the order= option to (:pagelist:) allows custom ordering functions
to be written.  So, even if order=$:Year,$:WAuthor,$:Work doesn't work,
it's entirely possible to write


and have a custom function do whatever sort you wish, including
grabbing page text variables from other related pages (where the
function defines the relation).

>    But what if I used these features for a shopping cart?  What if I used
>    these features to sort forums?  A business directory?  I'm really seeing
>    many instances where I want plain data in one place, where a user can't
>    alter it, versus a page where the user can alter what it comes out looking
>    like (formatting the data).  [...]
>    it's not far-fetched if we're looking to have
>    CMS-like abilities and want to sort *-Talk pages by their last modified
>    time and return the PageName of the threads by latest comment.
>    order={{$FullName}-Talk}$LastMod,{$FullName}$LastMod
>    Would return pages commented on last OR created/modified last -- assuming
>    it doesn't have any comments yet.

FWIW, I think that at some point we have to stop asking the PmWiki
markup syntax to solve every conceivable problem, and just say
"okay, this particular feature needs a custom PHP function to
do its work".  I'm not necessarily saying that we've reached that
point here, but for some things markup is a terribly inefficient way
of getting to our results.

>    I see a few ways this could be accomplished:
>    A setting that says "Share the variables from $BaseNamePatterns + $group
>    on this page" -- happens when the page variables are read.  This requires
>    a loop be added to the portion of PmWiki where the variables are read from
>    the page, and more than one page would have to be looped through to read
>    variables.  This gets messy fast if there are multiple groups (say
>    Data-Page and Page-Talk) and a pagelist!

I agree this gets very messy.

>    Move ordering to the format (fmt) area of the output -- the pagelist
>    stores the data in an array, passes the whole array of data to the output
>    formatting committee, and order is part of the format. The formatting code
>    already deals with other page variables as needed for formatting the
>    actual output, so it could process the output in memory, then spit it out
>    when done rather than spit it out line-per-line??  Frankly, from the
>    authoring point of view the order seems to go hand-in-hand with the format
>    of the pagelist to me... but on the programming end of pmwiki.php it goes
>    with the pagelist logic.

Not really.  Again, although everyone just loves pagelist templates, they're
not the way that the pagelist code was originally designed to work, nor are
they intended to be able to produce every conceivable output format.  

The output of pagelist is *completely* controlled by the fmt= option, and
this can also be a custom function, instead of using a pagelist template.
In fact, in 2.0 all pagelist output formats were handled by custom
functions, as pagelist templates weren't introduced into the core until 2.1 .
It has never been my intent to completely replace all pagelist output
using pagelist templates.

Significantly, the (:pagelist:) directive works by calling the fmt=
function _first_, and the it's the job of that function to call
MakePageList() to obtain the list of pages to be output.  Of course,
MakePageList() does handle a lot of the select and sorting options
if the fmt= function allows it to, but the fmt= function is completely
free to override whatever it gets back from MakePageList(), including
re-ordering the pages or making further modifications to the list
before generating the output.

Example:  handling of the count= parameter is currently handled by
formatting functions, as MakePageList() cannot know that the list it
sends back is going to be the exact list that is output.

>    A hack.  A total and complete hack.  I could probably make a hack if I had
>    to.  Custom markup.  Whatever.  It would stink.  It would be messy. Slow.
>    Complicated.  Not worth it.

I disagree.  A custom formatting function is entirely within PmWiki's
design spec, doesn't require any custom markup, would in many ways be
cleaner than what is currently being done, and (significantly) would be
a whole lot faster than using a pagelist template.  Pagelist templates
are slow -- because they have make additional calls to the markup engine
for the entire output sequence.  (Example:  If 1,000 pages come back
from the MakePageList function, then every page variable in the template
is evaluated at least 1,000 times-- once for each page, and every
conditional is evaluated 1,000 times, and this is done using the
relatively slow Markup rules.)

As an example -- I've been wanting to replace the Cookbook page
with a custom page generated using (:pagelist:).  I have an example
of this page at http://www.pmwiki.org/wiki/Cookbook/Cookbook-ByCategory .
You'll note that it's unusably slow, and the reason it's slow is
because of all of the extra processing that using a pagelist template
requires.  When I do this "for real", it's going to be done with
a custom fmt= function, and I guarantee it'll be many many times
faster with a custom function than trying to do it all through
the markup.

Again, just so I'm not misunderstood -- I'm very much in favor of
doing things that will make pagelist templates and (:pagelist:)
arguments able to solve large classes of problems.  But I also
want to avoid putting too much complexity into the system, and I
do think there are times when markup is the wrong tool for the job
at hand.


More information about the pmwiki-users mailing list