[pmwiki-users] Unifying variables, attributes, properties, part 2 (attributes)

Patrick R. Michaud pmichaud at pobox.com
Thu Dec 15 11:35:13 CST 2005


The previous message on this subject talked about the syntax of
page variables, and concluded with the suggestion that we could
use {$...} for all page variables, both in markup and in PHP code.
I'm liking that idea more and more, and you'll see why in this
message or the next.

But first I think I need to describe what I mean by "page attributes".
First, page attributes include those things that are stored as part of the
page file separate from the markup.  These are things such as passwords, 
the name of the last author, the time of creation and last 
modification, page title, and other miscellaneous things that we 
need to know about a page that aren't part of the markup (passwords)
or that might be inefficient to extract from the markup without
processing it fully (titles).

But, we also have page attributes that aren't directly 
stored in the page file itself.  One of the biggest and most
important is the url of a page ($PageUrl).  Another is 
the time of last modification ($LastModified), which is a 
human-friendly way to display the value of a page's "time" attribute.

The way that authors have traditionally accessed page attributes
is through markup such as {$Title}, {$Group}, {$LastModified}, etc.
My previous messages in this thread propose that this syntax be
used in both markup and in PHP formatting strings, and that we
simply call them "page variables" (eliminating the concept of
"markup variables").  The list of page variables would include:

    {$PageUrl}, {$FullName}, {$Group}, {$Name}, {$Title},
    {$Groupspaced}, {$Namespaced}, {$Titlespaced},
    {$Created}, {$LastModified}, {$LastModifiedBy}, {$LastModifiedHost}

For completeness with the markup, I'd go ahead and call the 
following "page variables" even though they aren't technically 
associated with any particular page (the non-braced form for these
would work in PHP scripts, but not in markup):

    {$ScriptUrl}, {$Version}, {$VersionNum}, {$SiteGroup},
    {$Author}, {$AuthId}

And we might as well say that the page variable markup can be used
to obtain the value of any stored page attribute.  Thus:

    {$time}    - the time of last modification as a timestamp
    {$ctime}   - the time of page creation as a timestamp
    {$rev}     - the number of page revisions
    {$targets} - the pages this page links to

The password attributes might be a bit sensitive -- still, since
page variables can be virtual (like $LastModified and $PageUrl), we 
can reformat those to be human friendly, or to hide them if the 
browser doesn't have sufficient authorization:

    {$passwdread}   - "id:* ****")
    {$passwdedit}   - "@editors (set by group)"
    {$passwdattr}   - "@admin (set by site)"
    {$passwdupload} - "****"

This means it's possible for a page (or sidebar or other component)
to easily display the password settings of the current page.

So, now that we have some uniform mechanism for displaying
the attributes of the current page, how about other pages?
I think I like the ideas that led to the Cookbook.PageVariables
recipe -- namely that a page variable can be prefixed by a pagename
to obtain the value for that page:

    {OtherPage$PageUrl}  -- url of OtherPage in the same group
    {Group.Page$Title}   -- title of Group.Page

Here's the critical insight:  if we adopt the convention of using
{$...} for page variables even in PHP code, then this means that
we can use the above page-qualified forms even in PHP strings and
recipes, and that nearly all page variable substitutions take 
place in FmtPageName instead of special-purpose markup rules.  
FmtPageName can also take care of reading and caching any
page attributes as they are needed, instead of it being spread
throughout the codebase as it is now (on the expectation that
FmtPageName *might* use them).

But let's go a bit further.  We sometimes need a "page cursor",
for example when walking through a list of pages, or when
processing an include file.  The PageListTemplates recipe
handles this with {$Curr}, {$Prev}, and {$Next} markup, but I 
think I'd like to embed a cursor directly into page variables,
using =, <, and > to represent current, previous, and next.
With that in mind, we get the following:

    {=$Name}      - name of the page at the cursor position
    {<$Group}     - group of the previous page
    {>$PageUrl}   - url of the next page

If there is no current, previous, or next page, the page 
variable returns an empty string.  

This makes it possible to directly lead to pagelist formats
specified in wiki pages (a la PageListTemplates), which makes
it easy to create and distributed custom formatting options
for other applications (e.g. blogs).  Combined with the 
{$passwdread}, {$passwdedit}, etc. markups above, it also makes
it easy to create lists of protected pages in various formats.

But there's more:  the (:include:) markup and 'wiki:' template
directives can set the cursor to the name of the included page. 
Then {=$FullName} is the always full name of the included page,
unlike {$FullName} which is the full name of the currently browsed
page.  Thus a page can use {=$FullName} to always refer to itself
even if it's being included from another page.  Same goes for
{=$Title}, {=$LastModified}, etc.

And there may be still more:  since we can include page variables
and cursors in format string settings, this means we *might* be able
to get links in included pages to be relative to the included page 
(instead of the browsed page) by setting:

    $PagePathFmt = array(
       '{$Group}.$1',       # Name in browsed page's group
       '{=$Group}.$1',      # Name in included page's group
       '$1.$1',             # Name.Name
       '$1.$DefaultPage');  # Name.HomePage

Wow, that's cool.

Pm




More information about the pmwiki-users mailing list