[pmwiki-users] New Hierarchical Groups Recipe...

Patrick R. Michaud pmichaud at pobox.com
Sat Feb 3 23:04:30 CST 2007


On Sat, Feb 03, 2007 at 09:20:53PM -0500, The Editor wrote:
> If I change it to
> 
> $FmtPV['$PageUrl'] = "'" . $ScriptUrl . "?n=" . hgURL("$hggroup.$hgname") . 
> "'";
> 
> It takes the current pagename and converts it from hyphens-dot to
> slashes properly, but then every link on the page has that url.  So
> the function works, but it needs to get the text of the link input
> used for each instance of a link...

Your $FmtPV entry is acting like a constant instead of a function 
for whatever page is being evaluated.  I've noticed this in several
of the "page variable" definitions of the Hg recipe, so let's see if
I can explain the difference...

Page variables are computed based on a variable name (e.g., $Name)
and a pagename (which often isn't the page that the global $pagename
is referring to).  The evaluation of page variables is done by
the PageVar() function.  It is called with the name of a page
(again, not necessarily the one being displayed) and the name
of a page variable to get for that page.

In other words, page variables produce different values for
different pages:

    PageVar("XYZ.Alpha", '$Name')     --> 'Alpha'
    PageVar("XYZ.Beta', '$Name')      --> 'Beta'
    PageVar("XYZ.Gamma", '$Name')     --> 'Gamma'
    PageVar("PmWiki.Alpha", '$Name')  --> 'Alpha'

The entries in the $FmtPV array have to be expressions that
describe how to go from a given pagename (providied by the 
$pn, $group, and $name local variables in PageVar) to the 
desired value.  For example, here's the $FmtPV definition for $Name:

    $FmtPV['$Name'] = '$name';

Note that it's literally a dollar sign ($) plus "name" here, and not
a substituted value of $name.  It's incorrect to define a $Name
page variable using code like:

    $name = ComputeName($pagename);
    $FmtPV['$Name'] = "'" . $name . "'";

because then the $Name page variable will end up with the same
(constant) value regardless of the actual page being passed to
PageVar().  (For those "page variables" that aren't associated
with a particular pagename, such as $Version, $VersionNum, $Author,
etc., a constant entry in $FmtPV is okay.)

A somewhat more complex example is $Namespaced:

    $FmtPV['$Namespaced'] = 'AsSpacedFunction($name)';

Once again, this uses the value of $name inside the PageVar()
function, and not a value at the time the page variable is
being defined.  This says to get $Namespaced for a particular page,
call AsSpacedFunction and pass it the page's name (held in $name
at the time of the call).  If we had defined $FmtPV in a 
configuration file as:

    $spacedname = AsSpacedFunction($pagename);
    $FmtPV['$Namespaced'] = "'" . $spacednamed . "'";

then we're once again defining $Namespaced only in terms of
the current page instead of whatever pagename is being passed
to PageVar().

So, if you want to redefine $PageUrl such that any hyphens in
the group portion of the name are converted to slashes, you
could start with:

    $FmtPV['$PageUrl'] = 
      '$ScriptUrl . "/" . str_replace("-", "/", $group) . "/" . $name';

This says that $PageUrl for a given page consists of $ScriptUrl,
followed by a slash, followed by the group for the page with
hyphens converted to slashes, followed by another slash,
followed by the page's name.

Note that the "variables" here are actually part of the string,
and not substituted.  In other words, if we were to print out
the value of $FmtPV['$PageUrl'], we would see literally the
string above with '$group' and '$name' still in it.
(Try it:  browse to http://www.pmwiki.org/wiki?action=diag and
take a look at the values in the [FmtPV] array -- they still
have the variable names in them.)

Now then, the above works as long as the webserver understands
PATH_INFO style links (e.g., if $EnablePathInfo = 1, producing
.../wiki/Group/Name).  Unfortunately, many sites can't use this
style, so our definition of $PageUrl needs to be able to
produce the ?n=Group.Page style of links when 
account as well

The above will work as long as the webserver understands PATH_INFO-style
links (e.g., $EnablePathInfo = 1).  But many sites can't use those links,
so for sites where $EnablePathInfo is not set we need to produce
the ?n=Group.Page style of links instead:

    $FmtPV['$PageUrl'] =
      '($EnablePathInfo)
        ? $ScriptUrl . "/" . str_replace("-", "/", $group) . "/" . $name
        : "$ScriptUrl?n=$group.$name"';

Again, nothing is actually evaluated here until $PageUrl
is being evaluated for a given page.

And, there's more to it... if any part of a page's name contains
non-ascii characters in it, we have to url-encode them.  Fortunately
PmWiki's PUE() function handles this encoding for us, thus we end
up with:

    $FmtPV['$PageUrl'] =
      'PUE(($EnablePathInfo)
           ? $ScriptUrl . "/" . str_replace("-", "/", $group) . "/" . $name
           : "$ScriptUrl?n=$group.$name")';

Hope this helps,

Pm



More information about the pmwiki-users mailing list