[pmwiki-users] (:includefieldpage:)

Henrik Bechmann henrik at bechmannsoftware.com
Sun Nov 20 18:25:44 CST 2005


Re: (:includefieldpage:) - a cookbook directive to include pages in a 
wiki farm field from other fields of the same farm. Generally works the 
same as (:include:) but requires an extre "field=MyFieldName" parameter, 
entries in farmmap.txt, and conventions for link writing in included 
pages so that they will work in "foreign" fields.

As a general note: the experience my dominatrix dishes out PALES in 
comparison to learning PHP (I'm a newbie to the language) by creating a 
directive extension of PmWiki<grin - kidding>

However, I have something working at (see code below)

Questions:

1. I am using some PmWiki internals ($Imap, $FmtV, ParseArgs(), 
LinkIMap()). Is this legitimate?

2. Is this whole exercise legitimate? Right direction? Right approach? 
(I'm guessing it's just a workaround for what Pm has planned, perhaps 
(:include FieldName=>FieldGroup.GroupPage :), and perhaps some way of 
marking pages to universalize links within the page to work throughout 
the Farm).

3. Is the inluded text, including the licencing text appropriate 
(borrowed in general from the includewikipage cookbook directive)

4. Any and all feedback is welcome

5. Should I add this to the cookbook?

Best,

- Henrik


Here's the code:

-------------------------

<?php if (!defined('PmWiki')) exit();
/*  Copyright 2005
   
    Version: includefieldpage 1.0.0, November 20, 2005
   
    *Contributors*
    Henrik Bechmann (Henrik at BechmannSoftware.com)
   
    *License*
    You can redistribute this file and/or modify it under the terms of the
    GNU General Public License as published by the Free Software 
Foundation;
    either version 2 of the License, or at your option) any later version. 
   
    *Description*
    Permits wiki field syndication by allowing wiki pages from one 
PmWiki 2.0 field page
    to be included in another PmWiki 2.0 field page.  
       
    *Installation*
    Simply copy this file into the 'cookbook/' subdirectory or some other
    suitable place and then add (with the address modified appropriately):
        include_once('cookbook/includefieldpages.php');
       
    *Use*
    Add the directive
        (:includefieldpage field=MyHoliday 
SomeGroup.SomePage[#startlink#endlink]|[ line=x..y] :)
    where the start and end links, and the line count are optional.
      Generally works the same as the (:include:) directive, but 
requires the additional 'field=SomeFieldName' expression
    to point to a specified field data directory.

    *Notes*
    - The farmmap.txt file must include the statement
    <SomeFieldName>Field    <local path beginning with site root, eg. 
/mysiteroot/fieldwiki/wiki.d/>
    for each field being accessed, eg:
    MyHolidayField    /holidays/wiki/wiki.d/
    so that the directive can find the field page file to load. Note 
that the field name used in the directive
    is appended with the suffix "Field" to find the InterMap listing.
    - Keep in mind that intra-site links in included pages must work in 
other field contexts, so prepend them with
    InterMap entries, eg:
    MyHolidayAttach:    /holidays/wiki/uploads/
    Then the wikilink in the included page text would be
    MyHolidayAttach:MyGroup/mypicture.jpg
    rather than just Attach:
    - All wiki authorization is bypassed in including a page; the 
included page is read directly from the source file.
    - This cookbook extension uses the globals $Imap, $FmtV, and the 
functions ParseArgs(), and LinkIMap(),
    which may change over versions
    
    *Attention*
    This script works only with PmWiki 2.0!
   
*/
# returns the original directive statement if it fails, otherwise 
returns appropriate wikitext
function IncludeFieldPageText($pagename, $inclspec) { # generally 
borrowed and modified from IncludeText() in pmwiki.php
  global $MaxIncludes, $InclCount, $IMap, $FmtV;
  SDV($MaxIncludes,50);
  $namepattern = '[[:alpha:]][-\\w]*';
  if ($InclCount++>=$MaxIncludes) return Keep($inclspec);
  $args = ParseArgs($inclspec);
  if (array_key_exists('field', $args)) {
    $fieldname = $args[field];
    $fieldintermapname = $fieldname . 'Field:';
    if (!isset($IMap[$fieldintermapname])) return (Keep($inclspec));
  } else {
    return (Keep($inclspec));
  }
  while (count($args['#'])>0) {
    $lvalue = array_shift($args['#']); $rvalue = array_shift($args['#']);
    if ($lvalue=='') { # should be a page name
      preg_match('/^([^#\\s]*)(.*)$/', $rvalue, $match);
      if ($match[1]) {                                 # include a page
        if (isset($itext)) continue;
        $result = LinkIMap('',$fieldintermapname,$match[1],'',''); #to 
get side effect in $FmtV, next line
      $iname = $FmtV['$LinkUrl'];
        if ($iname=='') continue;
        $filespec = $_SERVER['DOCUMENT_ROOT'] . $iname;
        if (!fileexists($filespec)) continue;
        $ipage = readpagefile($filespec);
        $itext = @$ipage['text'] . "\n"; # \n added to allow pickup of 
last line with lines=
      }
      if (preg_match("/^#($namepattern)?(\\.\\.)?(#($namepattern)?)?$/", 
$match[2], $match2)) {
        @list($x, $aa, $dots, $b, $bb) = $match2;
        if (!$dots && !$b) $bb = $namepattern;
        if ($b == '#') $bb = $namepattern;
        if ($aa)
#          
$itext=preg_replace("/^.*?([^\n]*\\[\\[#$aa\\]\\])/s",'$1',$itext,1);
          
$itext=preg_replace("/^.*?(\\[\\[#$aa\\]\\])/s",'$1',$itext,1); # allow 
name tags embedded in paragraphs
        if ($bb)
#          
$itext=preg_replace("/(.)[^\n]*\\[\\[#$bb\\]\\].*$/s",'$1',$itext,1);
          $itext=preg_replace("/(.)\\[\\[#$bb\\]\\].*$/s",'$1',$itext,1);
      }
      continue;
    }
    if (isset($itext) && in_array($lvalue, array('lines'))) {
      preg_match('/^(\\d*)(\\.\\.(\\d*))?$/', $rvalue, $match);
      @list($x, $a, $dots, $b) = $match;
      $upat = ($lvalue{0} == 'p') ? ".*?(\n\\s*\n|$)" : "[^\n]*\n";
      if (!$dots) { $b=$a; $a=0; }
      if ($a>0) $a--;
      $itext=preg_replace("/^(($upat)\{0,$b}).*$/s",'$1',$itext,1);
      $itext=preg_replace("/^($upat)\{0,$a}/s",'',$itext,1);
      continue;
    }
  }
  if (!isset($itext)) return Keep($inclspec);
  return PVS(htmlspecialchars(@$itext, ENT_NOQUOTES));

}

function readpagefile($pagefile, $since=0) { # generally borrowed and 
modified from read() in pmwiki.php
  $newline = '';
  $urlencoded = false;
  if ($pagefile && ($fp=@fopen($pagefile, "r"))) {
    while (!feof($fp)) {
      $line = fgets($fp, 4096);
      while (substr($line, -1, 1) != "\n" && !feof($fp))
        { $line .= fgets($fp, 4096); }
      $line = rtrim($line);
      if ($urlencoded) $line = urldecode(str_replace('+', '%2b', $line));
      @list($k,$v) = explode('=', $line, 2);
      if (!$k) continue;
      if ($k == 'version') {
        $ordered = (strpos($v, 'ordered=1') !== false);
        $urlencoded = (strpos($v, 'urlencoded=1') !== false);
        if (strpos($v, 'pmwiki-0.')) $newline="\262";
      }
      if ($k == 'newline') { $newline = $v; continue; }
      if ($since > 0 && preg_match('/:(\\d+)/', $k, $m) && $m[1] < $since) {
        if ($ordered) break;
        continue;
      }
      if ($newline) $v = str_replace($newline, "\n", $v);
      $page[$k] = $v;
    }
    fclose($fp);
  }
  return @$page;
}

function fileexists($pagefile) {
  return ($pagefile && file_exists($pagefile));
}

## (:includefieldpage:) - generally borrowed and modifed from (:include:)
Markup('includefieldpage', '>if',
  '/\\(:includefieldpage\\s+(\\S.*?):\\)/ei',
  "PRR().IncludeFieldPageText(\$pagename, '$1')");
?>

-- 

Henrik Bechmann
www.osscommons.ca
www.bechmannsoftware.com
Webmaster, www.dufferinpark.ca





More information about the pmwiki-users mailing list