Recent Changes - Search:

PmWiki

pmwiki.org

PmWikiDirectories

This article is under development, and until completed shouldn't be taken seriously. Working Notes holds my working notes; please use Talk for comments.

- Henrik

Author: Henrik Bechmann

Status: Draft MagazineArticleUpcoming

Shepherds: (need three)

PublishedOn:YYYY-YY-YY

ProposedOn:2006-10-06


PmWiki Directories

Introduction

At its simplest, a software application's directory structure is a convenient repository for the code and data files required to run the application. That's the static view, and is useful for installation, setup, and basic administration.

The dynamic view is more interesting. PmWiki can be viewed as a kind of data-driven application, responding as it does to the contents of certain structured text data files, or the presence or absence of certain files in particular directories. An investigation of this dynamic view begins to reveal some of the more sophisticated capabilities of the product.

Taken together, the static and dynamic views comprise a kind of topography of PmWiki: a view of the reach and capabilities of the application.

At a practical level, analysis of the details of directory configuration and contents provides guidance for administration of the product.

This article is based on a roundup of information gleaned from the pmwiki.org website relating to PmWiki's directory structures and their contents. The analysis examines

  • the core directory structure and contents when freshly installed
  • the interaction between the files in the directory structure and the application (the dynamic view)
  • reconfiguring the directory structure
  • extending the directory structure

The substance of the article focuses on the basic one-wiki application, but we conclude with an analysis of a farm (multi-wiki) installation.

The Directory Structure

./
(root directory - launch script and/or driver script)

Application

local/
cookbook/
scripts/

PHP scripts

Database

wiki.d/
wikilib.d/
(work.d/)
(shared.d/)

wiki page text files; work.d and shared.d are optionally created by the administrator

Public

pub/

skins/
css/
guiedit/

public resource files (for browsers)

Uploads

uploads/

directories created by PmWiki per Group as needed (by default)

files, such as image files, uploaded to Group directories by authors

Not run-time

docs/

not accessed at run-time

See Appendix A for details.

Core Directories: The Static View

When Freshly Installed

Directory Structure

The core directory structure is created when installing PmWiki. We have grouped the directories by general function:

  • directories containing primarily script files (Application);
  • directories containing the database of page data (Database);
  • directories containing files used to control the presentation of web pages (Public); and
  • directories used by authors to upload files, such as pictures to be resourced by the web pages (Uploads).

The local root directory of the structure is the directory that contains the launch script of the application, and is the reference point for the other local directories, which should all typically be subdirectories of the root directory as noted in the sidebar. The Farm root directory is the directory that contains the driver script (pmwiki.php). In single site installations, these two are the same; in multi-site installations, the Farm root directory is located centrally, and the launch script includes (points to) the driver script.

Path Variables listed in Appendix A and File Variables in Appendix C can be used to modify certain application behaviors with respect to searching or writing to the directories, or to using relocated or renamed directories. For new installations, the Path and File Variables do not have to be modified because PmWiki sets default values. As with most configuration settings, path and file variables are customized using simple PHP statements in local/config.php or local/farmconfig.php.

Fundamentally, PmWiki processes, merges, and links

  • page data from the database directories
  • public presentation directory files (such as template files)
  • uploaded files (such as images),

to generate html pages for rendering by browsers.

Directory Permissions

The wiki.d, work.d, and upload directories (and any subdirectories) need to be writable by PmWiki (PHP). If shared.d is configured to be updatable then it too needs to be writable by PHP. Resources required by browsers are grouped by convention under the public (pub/) directory, which therefore need public permissions. Upload directories also need public permissions, as they typically contain resources such as images which are accessed by browsers. All directories (except doc/) need to be readable by the webserver. Of course all files need to be owned by the account holder so that they can be managed. See File Permissions for details. Specific configurations vary according to web server permission schemes.

Directories: The Dynamic View

Using a classic dispatch approach, PmWiki is always invoked with an action request, which is routed to a corresponding action handler (see Appendix E). The implicit "browse" action is the default, when no other action is specified.

During the course of this action handling, when PmWiki is looking for a resource (ie. some file) in the directory structure, in certain cases it will search several directories for that resource in some specified order. Also individual directories are often searched for files in some specified order. This cascade can allow for

  • clear separation of native and custom directories and files, making installation of PmWiki upgrades easy, almost trivial
  • a concept of default resources, with the more specific context being searched before the more general context, or the more specific context being applied after the more general context.
  • a concept of priorities, with one location being searched before another

We will return to this list after examining standard PmWiki setup processes in relation to dynamic file searching.

What's interpolation?

Variable interpolation is the substitution or expansion of variables within quoted strings. A description of PmWiki: "interpolation on steroids".

Mainstream Cascading Search through Directories

Cascading search and variable interpolation is employed in several situations. In preparation for passing of control to action handlers, the following searches are performed with each call to PmWiki (with a couple of exceptions) to populate the standard memory environment.

Standard setup servicing
customizations (from pmwiki.php by $LocalDir,$FarmD/local)
Both are invoked
configuration (from stdconfig.php)
diag and phpinfo actions preempt the remaining standard configuration. Typically invoked by control variables (see "Enable Method" in Appendix D)
page and group customizations (scope local, from pgcust.php in $LocalDir)
Both per group and per page customizations are inviked; default.php is invoked if neither are found.
css search (scope local, from skin.php by $PageCSSListFmt)
All found files are loaded
skin search (scope local and farm, from skin.php by $SkinLibDirs, $Skin)
The first found skin is used.
intermap file search (scope local and farm, from pmwiki.php by $InterMapFiles)
All found files are merged

Once the standard setup has been accomplished, PmWiki invokes a HandleDispatch() controller, which invokes the called action handler through a HandleActions array. These action handlers continue resource search operations according to their requirements.

Action Handler Servicing
Standard rendering

For the standard HTML rendering (action=browse) several things happen: searches for customization files, skin and css files, intermap files, wiki pages, and uploads.

page searches (scope local and farm, from pmwiki.php by $WikiLibDirs,$PagePathFmt)
The first found file is used
upload searches (scope local, by $UploadFileFmt)
File is used if found.
Edit
Posting

$RecentChangesFmt $DraftRecentChangesFmt

Upload

$UploadFileFmt

Extended Searches

pagelist

Cascading Search through Wiki Pages

$InterMapFiles

$RecentChangesFmt

$PagePathFmt

$FPLTemplatePageFmt

Directives: wiki, include, pagelist (and family), file

Files as Triggers

File Contents as Control Data

File Contents as Format Data

Reconfiguring the Directory Structure

Extending the Directory Structure

Wiki Farms

Final Observations and Musings

context-switching; event driven programming


Appendix A

Directory Structure (single instance installation)

Directory
Description
Contents
Path Variables

Application and Customization Scripts

.(application root)

Contains the driver script

pmwiki.php

$ScriptUrl
$FarmD

    local/

directory for customization scripts and files

config.php, Group.php, Group.Page.php, intermap.txt

$LocalDir

    cookbook/

application extensions, normally downloaded from the cookbook group of the pmwiki website, but could be custom written. Empty to begin with.

Application extension scripts

    scripts/

the core script files

see Appendix D

(must be subdirectory of $FarmD/application root)

Database Files

    wiki.d/

or

    work.d/

- As working directory. wiki.d created by pmwiki after install and used as working directory by default; work.d created by administrator as an alternative.

temporary files used to build merged edits, caching for notifications (?), last modification time of the site, other types of cache, etc.

$WorkDir
$PageListCacheDir

    wiki.d/

- As website page database. Created by pmwiki after install.

Wiki data for pages, and associated attributes, in files named Group.Page. For wiki pages created by authors.

$WikiDir
$WikiLibDirs

    shared.d/

- (Optional) As repository for modified and custom core wiki pages. Created by administrator after install. No default is provided.

Wiki data for pages, and associated attributes, in files named Group.Page. For wiki pages created by administrators.

$WikiLibDirs

    wikilib.d/

Database of wiki page data, consisting of a couple of default website pages, PmWiki generic help pages, and much default site-wide configuration data.

Main.*
PmWiki.*
Site.*
SiteAdmin.*

$WikiLibDirs

Presentation Resources - Public Files

    pub/

Publicly available files (required by browsers, and therefore not protected from public read operations), except uploaded files (see Resources in this table below).

Contains only subdirectories to begin with.

$PubDirUrl
$FarmPubDirUrl

    pub/skins/

Files required to control the structure and appearance of the website pages

One subdirectory for each skin. These in turn contain *.tmpl (template), *.css (style sheet), *.php (script), graphics (*.jpg, *.gif), and potentially other kinds of files used in page construction and presentation.

$Skin
$SkinDir
$SkinDirUrl
$SkinLibDirs
$PageLogoUrl

    pub/css/

Cascading style sheet files that are automatically included in the skins above, by naming rules

local.css, Group.css, or Group.Page.css files.

$PageCSSListFmt

    pub/guiedit/

graphics files for edit buttons on wiki edit forms

.gif files as referenced in the $GUIButtons array, used to specify the edit button links included edit forms

$GUIButtonDirUrlFmt

Uploaded Files

    uploads/

Created after install: contains author-uploaded files

By default, contains subdirectories named by the Groups to which files were uploaded. These subdirectories in turn contain the uploaded files.

$UploadDir
$UploadUrlFmt
$UploadPrefixFmt

Administration

    docs/

Contains basic documentation for the application, in text files, plus a sample customization file. Not used during runtime.

A few short text files (4) and a sample customization file to get administrators started with new installations.


Appendix B

Path Variables:

Variable = default value

Initialization Script

Description

Scope

Search Lists

$InterMapFiles =
array("$FarmD/scripts/intermap.txt", "$FarmD/local/farmmap.txt",'$SiteGroup.InterMap', 'local/localmap.txt');
$WikiLibDirs =
array(&$WikiDir,new PageStore('$FarmD/wikilib.d/{$FullName}'))
$SkinLibDirs =
array("./pub/skins/\$Skin" => "$PubDirUrl/skins/\$Skin", "$FarmD/pub/skins/\$Skin" => "$FarmPubDirUrl/skins/\$Skin"))
$PageCSSListFmt =
array('pub/css/local.css' => '$PubDirUrl/css/local.css','pub/css/{$Group}.css' => '$PubDirUrl/css/{$Group}.css', 'pub/css/{$FullName}.css' => '$PubDirUrl/css/{$FullName}.css'))

Loads any of the files found.

Initialized Values

$FarmD=
dirname(__FILE__)
$FarmPubDirUrl=
$PubDirUrl
$GUIButtonDirUrlFmt=
$FarmPubDirUrl/guiedit
$LocalDir=
'local'
$PageLogoUrl=
"$FarmPubDirUrl/skins/pmwiki/pmwiki-32.gif"
$PageListCacheDir=
(empty)

Setting this variable enables caching for pagelists.

$PubDirUrl =
preg_replace('#/[^/]*$#', '/pub', $ScriptUrl, 1)
$ScriptUrl=
$UrlScheme.'://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']
$Skin=
'pmwiki'
$SkinDir=
(set in skins.php to found skin directory)
$SkinDirUrl
(set in skins.php to found skin directory)

$UploadDir => 'uploads'

$UploadPrefixFmt => '/$Group' (interpolated)

$UploadFileFmt => "$UploadDir$UploadPrefixFmt" (interpolated)

$UploadUrlFmt => preg_replace('#/[^/]*$#', "/$v", $PubDirUrl, 1)

$WikiDir=
new PageStore('wiki.d/{$FullName}'

Appendix C

File variables

Variable => default value

Initialization Script

Description

Scope

Search Lists

$BlocklistPages
=> array('$SiteAdminGroup.Blocklist','$SiteAdminGroup.Blocklist-Farm')
$BlocklistDownload
=> (an array of external sources)
$DraftRecentChangesFmt
=> (empty array)
$EditTemplatesFmt
=> array(),

Searches through array items for first template file that exists. Allows interpolation.

$FPLTemplatePageFmt
=> array('{$FullName}','{$SiteGroup}.LocalTemplates', '{$SiteGroup}.PageListTemplates')
$PagePathFmt
=> array('{$Group}.$1','$1.$1','$1.{$DefaultName}')
$PageSearchForm
=> array('$Group.Search', '$[$SiteGroup/Search]')
$RecentChangesFmt
=> array( '$SiteGroup.AllRecentChanges' => '* [[{$Group}.{$Name}]] . . . $CurrentTime $[by] $AuthorLink: $ChangeSummary', '$Group.RecentChanges' => '* [[{$Group}/{$Name}]] . . . $CurrentTime $[by] $AuthorLink: $ChangeSummary')
(in skins.php) =
search for $Skin.php, skin.php, $Skin.tmpl, skin.tmpl, *.tmpl (if unique)

Search for skin files

(in pgcust.php) = :search for $Group.php plus $FullName.php, then default.php if neither are found.

Interpolated Values

$AuthUserPageFmt
=> $SiteAdminGroup.AuthUser
$DefaultPageTextFmt
=> $SiteGroup.PageNotFound
$EditRedirectFmt
=> {$FullName}
$GroupAttributesFmt
=> $Group/GroupAttributes
$GroupFooterFmt
=> '(:nl:)(:include {$Group}.GroupFooter self=0 basepage={*$FullName}:)'
$GroupHeaderFmt
=> '(:include {$Group}.GroupHeader self=0 basepage={*$FullName}:)(:nl:)'
$LogoutRedirectFmt
= {$FullName}
$NotifyListPageFmt
=> $SiteAdminGroup.NotifyList
$PageEditForm
= $SiteGroup.EditForm,
$VarPagesFmt
=> PmWiki.Variables

Initialized Values

$SiteAdminGroup.ApprovedUrls
$SiteAdminGroup.AuthUser
$SiteAdminGroup.BlockList
$SiteAdminGroup.BlockList-Farm
$SiteAdminGroup.NotifyList
$SiteAdminGroup.Status
$SiteGroup.AuthForm
$SiteGroup.EditForm
$SiteGroup.LocalTemplates
$SiteGroup.PageListTemplates
$SiteGroup.PageNotFound
$SiteGroup.Search
$SiteGroup.UploadQuickReference

Appendix D

Core Script Files

The gold standard in open source applications for finding out what's going on is to examine the source code. Here's a list of the script files in the PmWiki core.

The table lists the pmwiki.php driver script file and the files in the /scripts/ directory, as found in the product distribution. The table shows the name of the file (Script), a brief Description, whether it is Loaded by default by the driver script (for typical browsing operations), how it is invoked (Enable method), and an entry point or two into the documentation for the file (References).

The Enable method refers to typical entries in config files. the $Enable... flag method typically involves setting the control variable to 1 (for true) which causes the stdconfig.php controller to load the script. The include_once method involves directly loading the module from the config file. The ?action=... method causes the script to be invoked in response to a parameter sent to the server.

The References are not exhaustive, but rather just entry points into the documentation.

In version 2.2 there are 36 core script files (pmwiki.php plus 35 script files in the scripts/ directory - four added and two removed from version 2.1), and 2 ancillary files (in the scripts/ directory).

Script (approx lines of code)
Description
Loaded by default
Enable method
References
(2039)

Main (driver) script

pmwiki.php*fw (2039)

(located in the directory above /scripts/) Acts as driver for the wiki application, calling in other scripts as needed. Handles initialization, and through helper functions, handles much of the rendering of returned web pages.

Direct call (eg. mydomain.ca/pmwiki.php), or commonly in a wrapper, as in index.php as include('pmwiki.php');

PmWiki.Installation; PmWiki.InitialSetupTasks

(801)

Security and Permissions

author.php (56)

This script handles author tracking. Author name in Cookies, author profile, author signature, require author

Yes

$EnableAuthorTracking

PmWiki.Passwords; PmWiki.PasswordsAdmin

authuser.phpf (211)

From PmWiki.org: AuthUser is PmWiki's identity-based authorization system that allows access to pages to be controlled through the use of usernames and passwords

No

include_once( "$FarmD/ scripts/authuser.php" )

PmWiki.AuthUser

blocklist.phpf (240)

From the documentation: A blocklist is a list of IP addresses, phrases, and expressions which are prevented from being added into pages on the website

No

$EnableBlocklist

PmWiki.Blocklist

crypt.php* (41)

Returns encrypted strings

No

?action=crypt

PmWiki.PasswordsAdmin

httpauth.php (50)

Use the browser's HTTP Basic protocol prompt instead of the form-based authorization prompt

No

include_once( "$FarmD/ scripts/httpauth.php" ), $EnableHTTPBasicAuth

Cookbook.SingleSign-On

robots.php (77)

This file provides various features to allow PmWiki to control what web crawlers (robots) see when they visit the site

Yes

$EnableRobotControl

$MetaRobots, source file comments

urlapprove.php* (126)

This script provides a URL-approval capability

No

include_once( "$FarmD/ scripts/urlapprove.php" )

PmWiki.UrlApprovals

(1405)

Wiki Markup support

forms.php (325)

Generic markup definition and management for form components: forms and fields. Also contains predefined form components for edit and authorization forms used by PmWiki.

Yes

$EnableForms

Category.Forms; Cookbook.Forms; Cookbook.Input

markupexpr.php (127)

A subset of wiki syntax which allows for string and formatting operations to be performed within wiki markup.

No

$EnableMarkupExpressions

PmWiki.MarkupExpressions

stdmarkup.php (491)

This script defines PmWiki's standard markup (except wikistyles)

Yes

$EnableStdMarkup

PmWiki.MarkupMasterIndex, PmWiki.CustomMarkup, PmWiki.MarkupCharacters

trails.php (127)

The WikiTrails feature allows wiki authors to create "trails" through sequences of pages in the wiki

Yes

$EnableWikiTrails

PmWiki.WikiTrails

vardoc.php (79)

This script provides special handling for WikiWords that are preceded by a $, treating them as PmWiki variables to be looked up in the variable documentation pages if such documentation exists

Yes

$EnableVarMarkup

See comments in the source code file

wikistyles.php (186)

WikiStyles allow authors to modify the color and other styling attributes of a page's contents. A wikistyle is written using percent-signs, as in or

Yes

$EnableWikiStyles

PmWiki.WikiStyles

wikiwords.php (70)

CamelCase (embedded capital letters) words are no longer (as of version 2.1) automatically interpreted as words which indicate a link to another wiki page. This script allows the automatic linking behavior to be turned on and supported.

No

$LinkWikiWords

PmWiki.WikiWord

(2141)

User Services

draft.php (64)

Management of saving, recalling, and listing wiki page drafts.

No

$EnableDrafts

$EnableDrafts

feeds.php* (545)

From the script annotation: This script provides a number of syndication feed and xml-based metadata options to PmWiki, including Atom, RSS 2.0, RSS 1.0 (RDF), and the Dublin Core Metadata extensions.

No

include_once( "$FarmD/ scripts/feeds.php" ), ?action=rss, atom, rdf, or dc

PmWiki.WebFeeds

guiedit.php (83)

Adds a graphical button bar to the edit form. The buttons provide text insertion help, including ability to embed highlighted text in inserted text. Custom links or buttons can be added.

No

?action=edit and $EnableGUIButtons

$EnableGUIButtons

notify.phpfw (195)

From the documentation: The notify.php script allows a site administrator to configure PmWiki to send email messages whenever pages are changed on the wiki site.

No

$EnableNotify

PmWiki.Notify

pagelist.php*fw (797)

This script contains logic for listing page content, and names, by various criteria. Also supports search.

Yes

$EnablePageList

PmWiki.PageLists

pagerev.php* (144)

Procedures for listing page differences, notably differences between versions of pages.

No

?action=diff

PmWiki.PageHistory

upload.php*f (313)

Support for uploading files to the wiki environment. Used to upload pictures and documents for "attachments" to pages.

No

$EnableUpload

PmWiki.UploadsAdmin, PmWiki.Uploads

(327)

Administrative support

pgcust.php (40)

This script enables per-page and per-group customizations in the local/ subdirectory (or whatever directory is given by $LocalDir)

Yes

$EnablePGCust

$EnablePGCust, PmWiki. GroupCustomizations

prefs.php (48)

Support for per-browser preferences. Preferences can be stored on a page (in the form of array elements), and set by the user with a ?setprefs=<pagename> call, and are then stored in the users' cookie.

Yes

$EnablePrefs; ?setprefs=

PmWiki.SitePageActions; Site.Preferences

skins.phpf (148)

This file implements the skin selection code for PmWiki

Yes

$EnableSkinLayout

Source file comments, PmWiki.Skins

stdconfig.php (90)

This controller script allows features to be easily enabled/disabled in config.php

Yes

$EnableStdConfig

Source code comments

version.php (1)

Sets the $Version and $VersionNum variables for each instance of PmWiki, for use in presenting versions to users, and allowing scripts to interrogate PmWiki for version number.

Yes

(913)

System support

caches.php (59)

Browser cache-control for If-Modified-Since browser requests

Yes

$EnableCaches

$EnableIMSCaching

creole.php (67)

This script adds Creole v0.4 markup (http://www.wikicreole.org/) to PmWiki. An alternate wiki syntax.

No

include_once('scripts/creole.php')

Cookbook.Creole

phpdiff.php (117)

This file implements a diff function in native PHP, to generate change records

Yes

No custom $DiffFunction

See Page History on PmWiki.PmWikiFeatures

simuledit.phpw (68)

This file enables merging of concurrent edits, using the "diff3" program available on most Unix systems to merge the edits.

Yes

$EnableSimulEdit

PmWiki.SimultaneousEdits

xlpage-utf-8.php (602)

UTF-8 allows for support of Asian languages and their character depth. It is a widely supported and flexible character encoding, used for Chinese, Japanese and Korean

No

include_once( "$FarmD/ scripts/xlpage-utf-8.php" )

PmWiki.UTF-8, Wikipedia:UTF-8

(537)

Integration and Upgrade support

diag.php* (54)

This file adds "?action=diag" and "?action=phpinfo" actions to PmWiki. This produces lots of diagnostic output that may be helpful to the software authors when debugging PmWiki or other scripts

No

$EnableDiag, ?action=ruleset, phpinfo, or diag

$EnableDiag

refcount.php* (122)

RefCount performs link reference counts on pages in the PmWiki database (i.e., counts of links between pages)

No

include_once( "$FarmD/ scripts/refcount.php" ), ?action=refcount

PmWiki.RefCount

transition.php (262)

This script handles various "fixup transitions" that might need to occur to help existing sites smoothly upgrade to newer releases of PmWiki

No

$EnableTransitions

PmWiki.ChangeLog, source code comments

upgrades.php* (99)

This script handles various upgrade tasks (such as renaming files from older versions) that might need to occur to help existing sites smoothly upgrade to newer releases of PmWiki

Yes, if version update has not occurred.

$EnableUpgradeCheck

See PmWiki.Version

(approx lines of distributed code: 8163)
*=defines action handler(s), f=reads configuration or data file(s) - file(), fgets(),fread(), PageStore::read(), file_get_contents(), w=writes to data files - fputs(), PageStore::write()

Counts of lines of code are approximate (and include annotation and white space); counts were taken at version 2.20beta65.


Appendix E

Action Handlers

Action Handlers

action

handler

defined in

Main (driver) script

browse, print

HandleBrowse

pmwiki.php

edit

HandleEdit

pmwiki.php

source

HandleSource

pmwiki.php

attr

HandleAttr

pmwiki.php

postattr

HandlePostAttr

pmwiki.php

login

HandleLoginA

pmwiki.php

logout

HandleLogoutA

pmwiki.php

Security and Permissions

crypt

HandleCrypt

crypt.php

approveurls, approvesites

HandleApprove

urlapprove.php

User Services

atom, rss, rdf

HandleFeed

feeds.php

search

HandleSearchA

pagelist.php

diff

HandleDiff (history)

pagerev.php

upload

HandleUpload

upload.php

download

HandleDownLoad

upload.php

postupload

HandlePostUpload

upload.php

Integration and Upgrade Support

diag

(direct code - preempts further processing)

diag.php

ruleset

HandleRuleset

diag.php

phpinfo

(direct code - preempts further processing)

diag.php

refcount

HandleRefCount

refcount.php

upgrade

HandleUpgrade

upgrades.php

Edit - History - Print - Recent Changes - Search
Page last modified on September 10, 2011, at 05:03 PM