Sisterly

Summary: Lets wikis on a farm access each other as easily as accessing other pages within a wiki
Version: 2008-10-14
Prerequisites: PmWiki 2.2.0-beta series, untested on 2.1.27 and earlier
Status: beta
License: GPL2
Maintainer: Eemeli Aro
Discussion: Sisterly-Talk?

Questions answered by this recipe

  • How can I read a page in another wiki?
  • How can I search across a wiki farm?
  • How can I add another layer of hierarchy to the PmWiki Group.Page system?

Description

Sisterly extends the way PmWiki parses page names by enabling wiki: prefixes, which let you refer to pages on other wikis hosted on the same server. Additionally, It enables page lists to access these other wikis and allows you to include pages from them as well as reading their page variables.

To install this recipe:

  • download sisterly.phpΔ to your cookbook directory
  • Define a $SisterFmt array in your configuration file
  • add the following after the $SisterFmt definition:
    include_once("$FarmD/cookbook/sisterly.php");

Overview

Sisterly adds a new, extended read-only PageStore to the end of the $WikiLibDirs array that can hold references to other wikis on the same server. The pages of these wikis may be accessed by prefixing a page name with wiki: where wiki is the case-insensitive name of such a wiki.

Writing or uploading files to pages accessed via Sisterly isn't possible; for that you'll need to access them via their own wiki.

In the following, the source wiki is the one you're directly accessing and the sister wikis are those accessed via Sisterly.

$SisterFmt

To use sisterly, you'll need to define an array $SisterFmt before including the recipe's PHP file. This array has the following structre:

$SisterFmt = array(
	'Name1' => array(
		'dirfmt' => '[...]/wiki.d/{$FullName}',
		'scripturl' => 'http://[...]',
		'attachurlprefix' => 'http://[...]',
		'passwdread' => '' ),
	'Name2' => array( [...] ),
	[...]
);

Where :

  • Name1 and Name2 are used as the shorthand names for the wikis — these ought to have the first character as an upper-case letter and the rest from [a-zA-Z0-9_-]
  • 'dirfmt' is a directory path to the wiki's main PageStore — this should probably be an absolute path, as it's relative to the source wiki's path
  • 'scripturl' matches the $ScriptUrl value for the wiki — note that if your wikis are on more than one domain, you'll need to disable $EnableLinkPageRelative
  • 'attachurlprefix' is the part of the path before $PageName/filename.ext for extensions — note that no trailing slash or anything else will be added before $PageName/filename.ext.
  • 'passwdread' is an optional default read password for accessing the wiki

As an example, here's the definition for one of my own sites:

$SisterFmt = array(
	'En' => array(
		'dirfmt' => '/path/to/pmwiki/en/wiki.d/{$FullName}',
		'scripturl' => 'http://autsys.tkk.fi/en',
		'attachurlprefix' => 'http://autsys.tkk.fi/en/attach/' ),
	'Fi' => array(
		'dirfmt' => '/path/to/pmwiki/fi/wiki.d/{$FullName}',
		'scripturl' => 'http://autsys.tkk.fi',
		'attachurlprefix' => 'http://autsys.tkk.fi/attach/' ),
	'Intranet' => array(
		'dirfmt' => '/path/to/pmwiki/intranet/wiki.d/{$FullName}',
		'scripturl' => 'http://autsys.tkk.fi/intranet',
		'attachurlprefix' => 'http://autsys.tkk.fi/intranet/attach/',
		'passwdread' => '@edit' ),
);

Here I've got two different language versions of the site and an intranet, for which read access is limited.

(:include 'wiki:page':)

To include a page from another wiki, you should surround its name in single or double quotes. This is due to the way PmWiki's ParseArgs function interprets ':' as a special character. Including sections or specific lines works as well; (:include 'wiki:page#section#' lines=3:) for example shouldn't pose any difficulties.

By default, Sisterly will fix links and attachments in a page included from another wiki to point to pages and files in that other wiki. To disable this, add the following to your config file before including sisterly.php:

$EnableSisterFixIncluded = 0;

[[wiki:page|links]]

In general, links work as they should, including [[wiki:page|+]]. If you've been previously using InterMap links to refer to pages on other wikis, you may want to remove those definitions. Everything should work fine even with them, but the target URLs may be generated slightly differently.

{wiki:page$Variable}

Page variables and page text variables work as they should. Sisterly adds a new page variable {$Wiki} that holds the name of the wiki to which the page belongs, or is blank for pages from the source wiki.

The value of {$Group} is different for pages accessed via Sisterly, as they also include the Wiki: prefix. Hence the value of {wiki:AGroup.APage$Group} will be Wiki:AGroup.

Sisterly also overwrites the value of {$PageUrl}. If you need to modify this, currently you'll need to change the return line of the pageurl method of SisterStore (defined in sisterly.php).

Search results and (:pagelist list=farm:)

By default, in order to include pages from Sisterly in a pagelist or search results, you'll need to set the value of the "list=" option to farm. This will include all pages from the source wiki as well as all those defined in $SisterFmt in the results.

In order to include pages from all wikis by default, add the following to your config file:

$SearchPatterns['default']['farm'] = '';

In order to not include pages from the source wiki when using list=farm, add the following to your config file:

$SearchPatterns['farm']['farm'] = "/^\w[\w-]*:/";

Authentication

All pages accessed via Sisterly will have their attr, edit and upload passwords set to @lock and the SisterStore write and delete methods don't allow any modification. However, note that while read password requirements are read from the sister wiki (GroupAttributes pages are parsed correctly, sitewide settings need to be set it SisterFmt) they are evaluated in the context of the source wiki.

This means that for example, if you're using AuthUser and the source and sister wikis use separate SiteAdmin.AuthUser pages that use the same user or group name (eg. a group @edit), someone belonging to that group in the context of the source wiki will have read access to pages that require membership of the group with the same name in the sister wiki.

Notes

Sisterly assumes that the ':' character isn't an otherwise valid page name character. If it is, odd things might happen. Also, links that include the ':' character in the page name but don't target a valid other wiki will by default render as links to pages that haven't been created yet but lead to a page stating "invalid page name".

Since each sister wiki is only referred to by a single PageStore directory format, pages that are accessible via a sister wiki but are not in its main PageStore (such as pages in the PmWiki group, which reside in the wikilib.d directory) aren't directly accessible via Sisterly. In order to link to them, you'll need to define another entry in $SisterFmt that has a different name and a reference to the appropriate PageStore, but possibly the same scripturl value.

If your PageStore dirfmt uses other variables than {$FullName} or {$Group} you'll need to change to return of the pagefile method of SisterStore (defined in sisterly.php) to pass it through FmtPageName.

If your wikis are on more than one domain, you'll need to disable $EnableLinkPageRelative in order to have links between them work.

If you've been previously using InterMap links to refer to pages on other wikis, you may want to remove those definitions. Everything should work fine even with them, but the target URLs may be generated slightly differently.

I haven't verified that the attachurlprefix format is sufficient to access attached files if $EnableDirectDownload is disabled. On my own sites I do use PmWiki's authentication for attachments, but a bit of Apache magix maps requests for /attach/Group/file.ext to index.php?n=Group&action=download&upname=file.ext.

Release Notes

See Also

Contributors

Comments

Trouble with recipe

I'm trying to start this recipe on pmwiki-2.2.4 under Windows XAMPP. After installing clean pmwiki-2.2.4, the only thing I did was adding

$EnableLinkPageRelative = 0;
$SisterFmt = array(
	'Test' => array(
		'dirfmt' => '$FarmD/wiki.d/{$FullName}',
		'scripturl' => "http://localhost/",
		'attachurlprefix' => "http://localhost/" ),
);
include_once("$FarmD/cookbook/sisterly.php");

to my config.php (I took the values pointing to wiki itselt just to see if it can work. Any other values also does not work)

Immediately after this I get these two warnings in all my pages: "Warning: Invalid argument supplied for foreach() in W:\S(serving).@exc\pmwiki.php on line 406"

"Warning: Cannot modify header information - headers already sent by (output started at W:\S(serving).@exc\pmwiki.php:406) in W:\S(serving).@exc\pmwiki.php on line 1084"

Could you please help me to find how do to solve this problem? Thanks!

Finar, 2009-08-18

Ah, found the bug. I'll need to verify this later (no server access just now), but it should get fixed either by patching sisterly.php's line 40 from

SDVA( $SearchPatterns['farm'], $SearchPatterns['default'] );

to

if (!empty($SearchPatterns['default'])) SDVA($SearchPatterns['farm'], $SearchPatterns['default']);

or by including the following line in your config.php before including Sisterly:

SDV($SearchPatterns['default'], array());

It's a matter of Sisterly incorrectly assuming that some default search pattern has been set, which obviously isn't the default case. —Eemeli Aro August 18, 2009, at 03:52 PM


I installed this on my wikifarms with two wikis, but somehow it only works on one of the wikis. The main wiki (ie with the pmwiki installation) is able to show pages from the other wiki, but not the other way around? Could this be a permissions issue? Or could it have anything to do with using the CleanUrls recipe? Bergwitz March 14, 2009, at 09:35 PM

User notes? : If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.