StirlingWestrup

This page proposes a syntax by Stirling Westrup as outlined at HierarchicalGroups-Proposals.

Stirling Westrup's Proposal

In order to make it easy to push content up and down the group hierarchy, the only distinction that should be made between a page and a group is that a group has pages below it. Both should be editable as wiki pages, sections should be as easy to set up as just creating pages below an existing page in the hierarchy and inserting an appropriate (:pagelist:) markup in the main page that includes all children.

We might then have Group.Page.Intro, Group.Page.Section-1, Group.Page.Section-2, etc and Group.Page itself (which is now also a group) might be blank except for an implicitly included pagelist in its header or footer. As the sections grow, they can easily become full pages and the Group.Page could have its pagelist modified to list its children, rather than including them. Blurring the distinction between groups and pages in this way would seem to be a good thing, so to emphasize this, from now on I shall only refer to pages and sub-pages, not to groups.

I've decided that I do want to worry about backwards compatibility in link semantics, or it may otherwise be very difficult to implement Hierarchical Pages on my existing wikis -- something I very much want to do. This would require that [[A]] be a relative link to sibling page A (a child of the current page's parent), [[A.B]] be an absolute link to sub-page B of topmost page A, and [[A.]] be a link to the default sub-page of topmost page A. On existing wikis this default page might be [[A.A]] or [[A.Home]] (as it is on mine), while on newer wikis we'll probably want it to be the topmost page A itself.

As well, in the current PmWiki implementation, the only distinction between . and / in links is how the resulting link is displayed. Thus, in what follows any . and / can be freely interchanged to result in identically functioning links. This did put certain constraints on the allowable syntaxes. To make matters worse, I decided not to introduce any new special characters.

Finally, it makes sense that there be a single distinguished topmost page that all existing top-level pages would be sub-pages of. This would allow for more easily inheriting properties down the page hierarchy. The distinguished page could also be useful for storing all of the information which is currently stored under Site. The name of the distinguished page would probably be configurable as $TopPage or something similar. PM (and others) might well prefer it have a default name like TOP or <PmWiki>, but I'm going to suggest it be called ^ (circumflex). This is the assumption I use in all my examples below. As a practical matter, the page name ^ would be stripped from page names saved in wiki.d/ so that ^.Main.HomePage would be saved as Main.HomePage as it currently is. The page ^ itself would (naturally) be immune to this, although it may be saved with some other special name in the actual wiki store.

To illustrate some of the properties (and problems) of this approach, I'm going to assume a slightly modified version of the hierarchy given above.

^
+-Kingdom
| +-Plant
| | +-Grass
| +-Animal
|   +-Canine
|   | +-Terrier
|   +-Feline
|     +-Cat
+-Mineral
  +-Gold
Path components
current page as starting group:.
parent page as starting group:..
main group as starting group:^ or {$TopPage}
go up:..
go to sibling X:X
go to child X:.X
Special rules
As a consequence of having any link that starts A. being interpreted as absolute, (actually, relative to $TopPage, but that works out the same) there is no markup explicitly corresponding to [[self over: down:]], and one has to use the equivalent of [[parent down: down:]] instead. Because $TopPage has no siblings, this will always work. Thus, if the current page is Kingdom.Plant then a relative link to Mineral.Gold would be [[..Mineral.Gold]].
^ is a distinguished name not a distinguished character. Thus one needs to write [[^.Foo]] to talk about a top-level page called Foo, not [[^Foo]]. The main effect of it being distinguished is that it is magic when it appears at the start of a link, and makes it absolute. [[{$TopName}]] is always an absolute link to the top of the heirarchy, even if there is a current sibling page with that identical name. (Reuse of the distinguished name is not recommended for that reason, but it can be referred to as [[..{$TopName}]] in that case.)
If the current HomePage is set to null (as would be likely in new setups) then trailing dots have almost no meaning. The one thing they provide is a trigger of the rule that paths not starting with dots but containing dots are relative to the $TopPage. Thus, [[Foo]] is a relative link to the sibling page Foo of the current page, and [[Foo.]] links to {$TopPage}.Foo and is absolute. There is no difference between [[Foo.Bar]], [[Foo.Bar.]] and [[Foo.Bar..]]. Of course, if there IS a defined homepage (say 'Home'), then [[Foo.]] would link to Foo.Home and [[Foo.Bar.] would link to Foo.Bar.Home, as would [[Foo.Bar..]]
Examples
^ (topmost)[[^]] or [[....]]
+-Kingdom (grandparent):[[...]] or [[Kingdom.]] or [[^.Kingdom]]
| +-Plant (uncle):[[...Plant]]
| | +-Grass (cousin):[[...Plant.Grass]]
| +-Animal (parent):[[..]]
|   +-Canine (self):[[.]]
|   | +-Terrier (child):[[.Terrier]]
|   +-Feline (sibling):[[Feline]] or [[..Feline]]
|     +-Cat (nephew):[[..Feline.Cat]]
+-Mineral (grand uncle):[[....Mineral]] or [[Mineral.]] or [[^.Mineral]]
  +-Gold (1st cousin, once removed):[[....Mineral.Gold]] or [[Mineral.Gold]] or [[^.Mineral.Gold]]]
Absolute link (to Canine):[[Kingdom.Animal.Canine]] or [[^.Kingdom.Animal.Canine]]
  • As you might guess from the above, one goes higher in the hierarchy by just prepending more dots to a path.
  • I find it somewhat counterintuitive that ..Foo (as well as just Foo) should be the relative path to a sibling page named Foo, but I do want .Foo to be a sub-page of the current page, and .. to be the parent page to the current page, so it would seem to be the logical choice. It could be made clearer, I suppose, by introducing other path characters, but I liked the fact that I could do everything I needed with just dot.
  • This markup is ambiguous in how to refer to "this page" vs "the default sub-page of the current page" as both would logically be [[.]]. Similarly [[..]] might logically refer to both "the parent page of this page" and "the default sub-page of the parent page". I propose we assume it to always be the former, and when the latter is desired, require explicit use of {$DefaultPage} in these ambiguous cases as in [[.{$DefaultPage}]] and [[..{$DefaultPage}]].
  • I've used . throughout these examples, although / might be used in several cases. Thus one might write [[.../Mineral.Gold]] to make a relative link to Mineral.Gold from Canine but have the link appear as just Mineral.Gold. I find it odd that this is identical in effect to [[////Mineral.Gold]], but I consider that a problem with the current use of / and . in PmWiki.

Proposal Comments

A couple of questions for this proposal. (I'll probably have more, but these are the ones that jump out at me at the moment.)

  • Where are group attributes stored? Or do we simply say that any passwords on a page automatically apply to all of its subpages except where overridden by a subpage?
  • How do we handle GroupHeader and GroupFooter?
- PM
I would like to say that any passwords on a page automatically apply to all its subpages except where overridden, but I also don't want to break working wikis where the attributes for SomeGroup are stored in SomeGroup.GroupAttributes.

Ideally GroupAttributes, GroupHeader and GroupFooter would eventually be migrated into the metadata for a page, and would apply to that page and all its subpages. During the transition though, we would probably say that any page named GroupAttributes, GroupHeader or GroupFooter would have its contents applied to its parent page and all its children, except where overridden in a subpage.

This would mean that when displaying the page at ^.Foo.Bar.Baz, it would be necessary to look for ^.Foo.Bar.Group*, ^.Foo.Group* and ^.Group* to know what headers, footers, and passwords applied.
- StirlingWestrup