<?xml version="1.0" encoding="utf-8"?>
<!--
	/**************************************************************************\
	* Simple Groupware 0.724                                                   *
	* http://www.simple-groupware.de                                           *
	* Copyright (C) 2002-2011 by Thomas Bley                                   *
	* ------------------------------------------------------------------------ *
	*  This program is free software; you can redistribute it and/or           *
	*  modify it under the terms of the GNU General Public License Version 2   *
	*  as published by the Free Software Foundation; only version 2            *
	*  of the License, no later version.                                       *
	*                                                                          *
	*  This program is distributed in the hope that it will be useful,         *
	*  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
	*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
	*  GNU General Public License for more details.                            *
	*                                                                          *
	*  You should have received a copy of the GNU General Public License       *
	*  Version 2 along with this program; if not, write to the Free Software   *
	*  Foundation, Inc., 59 Temple Place - Suite 330, Boston,                  *
	*  MA  02111-1307, USA.                                                    *
	\**************************************************************************/
-->
<simple_cms>
<asset>
<pagename>Category.GroupFooter</pagename>
<data><![CDATA[(:Summary:content generated for Category list pages:)
----
[--'''{*$:Summary}'''--]
(:pagelist link={*$FullName} list=normal:)
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>HomePage</pagename>
<data><![CDATA[Welcome to PmWiki!

A local copy of PmWiki's
documentation has been installed along with the software,
and is available via the [[PmWiki/documentation index]].  

The [[PmWiki/basic editing]] page describes how to create pages
in PmWiki.  You can practice editing in the [[wiki sandbox]].

More information about PmWiki is available from http://www.pmwiki.org .

You can open this page with the web layout at: http://<sgs-server>/<sgs-dir>/cms.php
	]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>HaganFox</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.AccessKeys</pagename>
<data><![CDATA[(:Summary:Access keys are keyboard shortcuts for tasks that would otherwise require a mouse:)
(:Audience: visitors (intermediate) :)

Access keys (See also [[Wikipedia:access keys]]) are keyboard shortcuts for tasks that would otherwise require a mouse.   
They are part of markup that may exist on any webpage.
On PmWiki steps have been taken to make it easier to use access keys throughout a site, and to make it possible to adjust key assignments to accommodate different languages and preferences.

!! Using access keys in different operating systems and browsers
Access keys require you to hold down two or more keys.
* on Windows with Internet Explorer, press ALT + the access key
* with Firefox, press SHIFT + ALT + the access key
* on a Macintosh, press Ctrl + the access key (applies to Firefox, Safari, Omniweb, Internet Explorer)
* with [[http://opera.com/support/tutorials/nomouse/#access | Opera]] press Shift+Esc to enter (or exit) access-key mode.

Exceptions exist for specific browsers, and specific versions.  For example, 
* Internet Explorer requires that the Enter key be pressed at the end of the sequence for versions 5 and up under Windows, but not under Macintosh (where access keys were not supported until after version 4.5).  
* Firefox versions 1.5 and earlier simply use Alt, while Firefox version 2.0 uses Shift+Alt.  

Note, in cases of conflicts between the keyboard shortcuts assigned by browsers and access keys assigned by links and other markup on webpages, many browsers, including Mozilla, Netscape and Internet Explorer, allow access keys to override the browser defaults and require a different sequence to continue using overridden browser assignments (typically, by pressing and releasing the Alt key, instead of holding it down).   

!! Access key assignments in this PmWiki installation
The following is a list of the currently defined access keys for built-in actions. Remember that the letters identified below must be used together with the combination listed above (depending on your operating system and browser). Note that some actions do not have a corresponding access key by default.

||width=
||! Key ||!Function ||
|| $[ak_edit]          ||edit||
|| $[ak_history]       ||history||
|| $[ak_recentchanges] ||recent changes||
|| $[ak_save]          ||save page||
|| $[ak_saveedit]      ||save and keep editing||
|| $[ak_savedraft]     ||save draft||
|| $[ak_preview]       ||preview page||
|| $[ak_print]         ||print||
|| $[ak_view]          ||view||
|| $[ak_em]            ||''emphasized'' text||
|| $[ak_strong]        ||'''strong''' text||
|| $[ak_textedit]      ||jump to edit textarea (when in edit modes)||  

%audience% admins (intermediate)
!! [[#customkeys]] Customizing access keys
PmWiki uses the same "phrase translation" methods for access key mappings as it does for [[internationalization(s)]].  This makes it possible for administrators, skins, language translators, and visitors to all influence the way that specific keys are mapped to actions.

See [[SitePreferences]] and [[Site.Preferences]] for more information and a template.

Note that some skins (e.g., [[Cookbook:LeanSkin | Lean]]) don't use the translation mechanism. In this case one must edit the template file itself in order to change the access keys.

By convention, the translation phrases for all of the access key actions start with the characters "ak_", so that the page variable "[@$[ak_edit]@]" is replaced by the access key for editing as defined by the current preferences, language, skin default, or site default.

!!  Implementation of access keys
Access keys are implemented in html as optional parameters that can be added to links and many other types of markup.

'''Example:'''  [@<a href="http://example.com" accesskey="x">Example</a>@] would create a link to example.com that could be triggered by clicking on the linked word "example" or using the access key Akey+x.  That same action key link could be created in PmWiki markup by typing [@%item accesskey="x"%[[http://example.com|Example]]@], like this: %item accesskey="x"%[[http://example.com|Example]].  Try it and see if it works.  Note that this AKey+x access key only works this way on this page, because it is simply a shortcut for accessing the link that exists only on this page.

The list of access key assignments in default PmWiki installations generally work throughout a site because links have been created in PmWiki skins and editing screens that incorporate access key parameters using the access key translation phrases.  One location where those links can be viewed is [[Site.PageActions]].  That page contains the links that the default PmWiki skin, and many other skins, use to generate links such as "View" "Edit" and "History" that appear on most pages (other than editing screens).  Each of the links in that page also has an [@%accesskey=$[ak_xxx]%@] declaration in front of it, which enables a specific access key for that link.

>>faq<< [[#faq]]

Q: How can I change the keyboard shortcuts for editing and saving a page?

A: See [[#customkeys | Customizing access keys]].

Q: I have a Wikisite Site.Sidebar which is embedded in the skin template. The use of  @@[=%item accesskey="x"%[[Groupname/Sitename]]=]@@ doesn't work here. Has anyone an idea why, and what I could do?

A: Use just @@[=%accesskey="x"%[[PmWiki.PmWiki]]%%=]@@ (no "item", closed with [=%%=]).
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Audiences</pagename>
<data><![CDATA[(:Summary:Patrick Michaud's comments regarding the "audiences" for which PmWiki was designed:)
This page contains Patrick Michaud's comments regarding the "audiences" for which PmWiki was designed. As such, many people are reluctant to modify the page, because it is a statement of his opinions and describes some of the thought that went into creating PmWiki. (And we all thank him for that!) 

!!Patrick's comments
I think of PmWiki in terms of two audiences: 
* ''Authors'' are the people who generate web content using PmWiki, and 
* ''[[wiki administrator]]s'' are the folks who install, configure, and maintain a PmWiki installation on a web server. 
In some senses it could be claimed that as the primary developer of PmWiki I should only have wiki administrators as my target audience, and that authors are the target audience for the administrators.  But what really makes PmWiki useful to wiki administrators is that I've put a lot of consideration into creating a tool that is usable by authors, so I have to keep the needs of both audiences in mind as I'm designing and adding new features to PmWiki. 

Within the authoring audience I see that there are "naive authors" and "experienced authors". 

"Naive authors" are the folks who use wiki to generate content but may know next-to-nothing about HTML, much less style sheets or PHP or the like. Naive authors are easily discouraged from generating web content if they have to wade through markup text that has lots of funny and cryptic symbols in them. So, if we want a site with lots of contributors, we have to be very careful not to do things that will cause this group to exclude themselves from participating.

"Experienced authors" are the folks who know a lot about HTML and could write their content as HTML, but have chosen to use wiki because of its other useful features (ease of linking, collaboration, ease of updates, revision histories, etc.) or because they want to collaborate with naive authors. Experienced authors usually don't have any problem with documents with lots of ugly markup in them; after all, they already know HTML.  Experienced authors are sometimes frustrated with wiki because it doesn't have markup that would let them do something they know they can do in HTML (e.g., tables, stylesheets, colored text, etc.). And, they sometimes have difficulty understanding why naive authors would turn away from documents that have lots of markup sequences in them.  

For the wiki administrator audience--the folks who install and may want to [[PmWiki/InitialSetupTasks|customize]] PmWiki--their backgrounds and goals are often quite diverse. PmWiki is designed so that it can be installed and be useful with minimal HTML/PHP knowledge, but it doesn't restrict people who know HTML/PHP from doing some fairly complex things. For one, PmWiki allows a site administrator to build-in markup sequences and features customized to his/her needs (and the needs of his/her audiences). 

The separate needs of these audiences are behind most of the [[PmWikiPhilosoph(y)]]ies.  The people who develop PmWiki software must continually keep naive authors in mind as new features are requested and proposed by expert authors and Wiki Administrators.  Sometimes it may seem to these latter groups that it's okay to implement the complex features because "naive authors don't have to use them", but the truth is that if complex/ugly markup sequences are available then they will eventually be used by someone, and once used they become a barrier to the naive authors. So, if I see that a feature could become a barrier to a naive author I don't include it in the base implementation of PmWiki, but instead find ways to let Wiki Administrators include it as a [[local customization(s)]]. 
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.AuthUser</pagename>
<data><![CDATA[(:Summary:Authorization system that uses usernames and passwords:)
(:Audience: administrators (intermediate) :)
AuthUser is PmWiki's identity-based authorization system that allows access to pages to be controlled through the use of usernames and passwords.  AuthUser can be used in addition to the [[Passwords | password-based]] scheme that is PmWiki's default configuration.

AuthUser is a very flexible system for managing access control on pages, but flexibility can also bring complexity and increased maintenance overhead to the wiki administrator.  This is why PmWiki defaults to the simpler password-based system.  For some thoughts about the relative merits of the two approaches, see [[PmWiki:ThoughtsOnAccessControl]].

See also:  [[Cookbook:Quick Start for AuthUser]].

!! Activating AuthUser
To activate PmWiki's identity-based system, add the following line
to ''local/config.php'':

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

Ensure that you have [[PasswordsAdmin | set a site wide admin password]], otherwise you will not be able to edit [[SiteAdmin.AuthUser]].

->%note% Note: Older versions of PmWiki (before 2.2.0-beta58) use ''Site.AuthUser''.

PmWiki caches some group and page authorization levels when a page is accessed. For this reason, it is better to include @@authuser.php@@ quite early in config.php, notably
* after any recipe which inserts some custom writable PageStore class (MySQL, SQLite, Compressed PageStore or other)
* and after any internationalization (UTF-8 and XLPage).

(If you don't use a custom PageStore class and i18n, include @@authuser.php@@ first thing in @@config.php@@.)

All other recipes should be included after these.

!! Creating user accounts
Most of AuthUser's configuration is performed via the [[SiteAdmin.AuthUser]] page.  To change the AuthUser configuration, simply edit this page like any other wiki page (you'll typically need to use the site's admin password for this).

To create a login account, simply add lines to SiteAdmin.AuthUser that look like:

    username: [=(:=]encrypt ''password'':)

For example, to create a login account for "alice" with a password of "wonderland", enter:

    alice: [=(:=]encrypt wonderland:)

When the page is saved, the "@@[=(:=]encrypt wonderland:)@@" part of the text will be replaced by an encrypted form of the password "wonderland".  This encryption is done so that someone looking at the SiteAdmin.AuthUser page cannot easily determine the passwords stored in the page.  

To change or reset an account's password, simply replace the encrypted string with another @@[=(:=]encrypt:)@@ directive.

!! Controlling access to pages by login

Pages and groups can be protected based on login account by using "passwords" of the form [@id:username@] in the password fields of [@?action=attr@] (see [[PmWiki.Passwords]]).  For example, to restrict a page to being edited by Alice, one would set the password to "[@id:alice@]".

It's possible to use multiple "id:" declarations and passwords in the [@?action=attr@] form, thus the following setting would allow access to Alice, Carol, and anyone who knows the password "quick":

    quick id:alice,carol

To allow access to anyone who has successfully logged in, use "[@id:*@]".

One can also perform site-wide restrictions based on identity in the $DefaultPasswords array: e.g.

    # require valid login before viewing pages
    $DefaultPasswords['read'] = 'id:*';
    # Alice and carol may edit
    $DefaultPasswords['edit'] = 'id:alice,carol';
    # All admins and Fred may edit
    $DefaultPasswords['edit'] = array('@admins', 'id:Fred');

You can change the $DefaultPasswords array in local customization files such as:
* local/config.php (for entire wiki)
* farmconfig.php (for entire wikifarm)

!! [[#auth_groups]] Organizing accounts into groups

AuthUser also makes it possible to group login accounts together into authorization groups, indicated by a leading "@" sign.  As with login accounts, group memberships are maintained by editing the SiteAdmin.AuthUser page.  Group memberships can be specified by either listing the groups for a login account (person belongs to groups) or the login accounts for a group (group includes people).  You can repeat or mix-and-match the two kinds as desired:

    @writers: alice, bob
    carol: @writers, @editors
    @admins: alice, dave
    
Then, to restrict page access to a particular group, simply use "[@@group@]" as the "password" in [@?action=attr@] or the $DefaultPasswords array, similar to the way that "[@id:username@]" is used to restrict access to specific login accounts.

!!! Excluding individuals from password groups

Group password memberships are maintained by editing the SiteAdmin.AuthUser page. To specify a password group that allows access to anyone who is authenticated, you can specify:

    @wholeoffice: *

If you need to keep "Fred" out of this password group :

    @wholeoffice: *,-Fred

To allow all users except Fred to change page attributes, for example, you can add to config.php :
    $DefaultPasswords['attr'] = array('id:*,-Fred');

(:if authid:)
>>clip<<
!!!!!Wiki Debug
* %newwin% [[Diagnostics -> {$Name}?action=diag]]
* %newwin% [[PHPInfo -> {$Name}?action=phpinfo]]
(:ifend:)

!! Getting account names and passwords from external sources

The AuthUser script has the capability of obtaining username/password pairs from places other than the SiteAdmin.AuthUser page, such as passwd-formatted files (usually called '.htpasswd' on Apache servers), [[#LDAP|LDAP]] servers, or even the ''local/config.php'' file.

!!! Passwd-formatted files (.htpasswd/.htgroup)

Passwd-formatted files, commonly called ''.htpasswd'' files in Apache, are text files where each line contains a username and an encrypted password separated by a colon.  A typical ''.htpasswd'' file might look like:

    alice:vK99sgDV1an6I
    carol:Q1kSeNcTfwqjs

To get AuthUser to obtain usernames and passwords from a ''.htaccess'' file, add the following line to SiteAdmin.AuthUser, replacing "/path/to/.htpasswd" with the filesystem path of the ''.htpasswd'' file:

    htpasswd: /path/to/.htpasswd

Creation and maintenance of the ''.htpasswd'' file can be performed using a text editor, or any number of other third-party tools available for maintaining ''.htpasswd'' files.  The Apache web server typically includes an ''htpasswd'' command for creating accounts in .htpasswd:

    $ htpasswd /path/to/.htpasswd alice
    New password:
    Re-type new password:
    Adding password for user alice
    $

Similarly, one can use ''.htgroup'' formatted files to specify group memberships.  Each line has the name of a group (without the "@"), followed by a colon, followed by a space separated list of usernames in the group.

    writers: carol
    editors: alice carol bob
    admins: alice dave

Note that the groups are still "@writers", "@editors", and "@admins" in PmWiki even though the file doesn't specify the @ signs.  To get AuthUser to load these groups, use a line in SiteAdmin.AuthUser like:

    htgroup: /path/to/.htgroup

!!! Configuration via ''local/config.php''

AuthUser configuration settings can also be made from the ''local/config.php'' file in addition to the SiteAdmin.AuthUser page.  Such settings are placed in the $AuthUser array, and ''must be set prior to including the ''authuser.php'' script''. Some examples:

    # set a password for alice
    $AuthUser['alice'] = crypt('wonderland');
    # set a password for carol
    $AuthUser['carol'] = '$1$CknC8zAs$dC8z2vu3UvnIXMfOcGDON0';
    # define the @editors group
    $AuthUser['@editors'] = array('alice', 'carol', 'bob');
    # Use local/.htpasswd for usernames/passwords
    $AuthUser['htpasswd'] = 'local/.htpasswd';
    # Use local/.htgroup for group memberships
    $AuthUser['htgroup'] = 'local/.htgroup';

[[#LDAP]]
!!! Configuration via LDAP

Authentication can be performed via an external LDAP server -- simply set an entry for "ldap" in either SiteAdmin.AuthUser or the ''local/config.php'' file.

    # use ldap.airius.com for authentication
    $AuthUser['ldap'] = 'ldap://ldap.airius.com/ou=People,o=Airius?cn?sub';

Make sure to include AuthUser below the entry for the ldap server:

    # Want to use AuthUser so we can use ldap for passwords
    include_once("$FarmD/scripts/authuser.php");

And remember to assign the Security Variables for edit and history (or whatever):

    #Security Variables set login for edit & history page
    # to let anyone edit that has an ldap entry:
    $HandleAuth['diff'] = 'edit';
    $DefaultPasswords['edit'] = 'id:*';
    $Author = $AuthId;

LDAP authentication in AuthUser closely follows the model used by Apache 2.0's [[http://httpd.apache.org/docs/2.0/mod/mod_auth_ldap.html|mod_auth_ldap]] module; see especially the documentation for  [[http://httpd.apache.org/docs/2.0/mod/mod_auth_ldap.html#authldapurl|AuthLDAPUrl]] for a description of the url format.

For servers that don't allow anonymous binds, AuthUser provides $AuthLDAPBindDN and $AuthLDAPBindPassword variables to specify the binding to be used for searching.

See also [[Cookbook:AuthUser via Microsoft LDAP]]

!! Setting the Author Name
By default, PmWiki will use a login name in the Author field of the edit form, but allows the author to change this value prior to saving.  To force the login name to always be used as the author name, use the following sequence in config.php to activate AuthUser:

    include_once("$FarmD/scripts/authuser.php");
    $Author = $AuthId; # after include_once()

To allow more flexibility, but still enable changes to be linked to the authorized user, one can give the author name a prefix of the $AuthId instead:
[@
    include_once("$FarmD/scripts/author.php");
    include_once("$FarmD/scripts/authuser.php");
    if ($Author) {
	if (strstr($Author, '-') != false) {
	    $Author = "$AuthId-" . preg_replace('/^[^-]*-/', '', $Author);
	} else if ($Author != $AuthId) {
	    $Author = $AuthId . '-' . $Author;
	} else {
	    $Author = $AuthId;
	}
    } else {
	$Author = $AuthId;
    }
    $AuthorLink = "[[~$Author]]";
@]
The above will allow the user to put in the author name of their choice, but that will always be replaced by that name prefixed with "$AuthId-".
The reason why $AuthorLink needs to be set is that, if it isn't, the RecentChanges page will have the wrong link in it.

!!! Removing the "Author" edit field
To force users to edit with their AuthID instead of having a field they can place any name in. This enables administration to keep track of who is doing what better. This line also links the Author name to their Profile.\\
Go to Site.EditForm, remove the line\\
[@$[Author]: (:input e_author:)@]\\
or replace it with\\
[@$[Author]: [[Profiles/{$Author}]]@]\\

!! Authorization, Sessions, and WikiFarms [[#sessions]]

PmWiki uses PHP sessions to keep track of any user authorization information.  By default PHP is configured so that all interactions with the same server (as identified by the server's domain name) are treated as part of the same session.

What this means for PmWiki is that if there are multiple wikis running within the same domain name, PHP will treat a login to one wiki as being valid for all wikis in the same domain.  The easiest fix is to tell each wiki to have use a different "session cookie".  Near the top of a wiki's ''local/config.php'' file, before calling authuser or other recipes, add a line like:

-->[@session_name('XYZSESSID');@]

The XYZSESSID can be any unique name (letters only is safest).

!! See Also

* [[PmWiki.Passwords]]
* [[PmWiki.PasswordsAdmin]]
* [[Cookbook:AuthUser]] for tips and tricks
* [[SiteAdmin.AuthUser]]

>>faq<< [[#faq]]
Q:  I get http error 500 "Internal Server Error" when I try to log in. What's wrong?

A:  This can happen if the encrypted passwords are not created on the web server that hosts the PmWiki.
The crypt function changed during the PHP development, e.g. a password encrypted with PHP 5.2 can not be decrypted in PHP 5.1, but PHP 5.2 can decrypt passwords created by PHP 5.1.
This situation normally happens if you prepare everything on your local machine with the latest PHP version and you upload the passwords to a webserver which is running an older version.
The same error occurs when you add encrypted passwords to local/config.php.

Solution: Create the passwords on the system with the oldest PHP version and use them on all other systems.

Q:  Can I specify authorization group memberships from with ''local/config.php''?

A:  Yes -- put the group definition into the $AuthUser array (in config.php):

        $AuthUser['@editors'] = array('alice', 'carol', 'bob');

Q:  I'm running multiple wikis under the same domain name, and logins from one wiki are appearing on other wikis.  Shouldn't they be independent?

A:  This is caused by the way that PHP treats sessions.  See [[PmWiki.AuthUser#sessions]] for more details.

Q: Is there any way to record the time of the last login for each user when using AuthUser?  I need a way to look for stale accounts.

A: See [[Cookbook:UserLastAction]].

Q: Though every settings seem correct, authentication against LDAP is not working, and there is nothing in ldap log. What's wrong ?

A: Be sure ldap php module is installed ( on debian apt-get install php(4|5)-ldap ; apache(2)ctl graceful )

Q: The login form asks for username and password, but only password matters.  
-> Username can be left blank and it still signs in under the account.  Is this intentional and if so, can I change it so that the username and password must both be entered?  - X 1/18/07  Never mind I think this has something to do with using the admin password.  I created a test account and it's working ok.

A: Make sure you are not entering the admin password when testing the account because, if the password is equal to the admin password, it will authenticate directly through the config.php file and skip any other system.

A: Do note that even with AuthUser activated you can still log in with a blank username and only entering the password.  In that case any password you enter will be "accepted" but only passwords which authenticate in the given context will actually give you any authorization rights.  Using this capability AuthUser comfortably coexists with the default password-based system.

If you want to require both username and password, then you need to set an admin id '''before''' including authuser.php:

[@
## Define usernames and passwords.
$AuthUser['carol'] = '$1$CknC8zAs$dC8z2vu3UvnIXMfOcGDON0';

## Enable authentication based on username.
include_once('scripts/authuser.php');

# $DefaultPasswords['admin'] = crypt('secret');
$DefaultPasswords['admin'] = 'id:carol';
@]

A username and password will then be required before login is successful.

Q: Is there any way to hide IP addresses once someone has logged in so that registered users can keep their IP addresses invisible to everyone except administrators?  - X 1/18/07

A: Not yet.

Q: Is there a way that people could self-register through AuthUser?  

A: You can see [[Cookbook:AuthUserSignup]] for a recipe about this problem. 

Q: I would like it that after I have AuthUser turned and a user is authenticated to get on my site, that if I have a password put on a particular page or group that they don't get the AuthUser form to show up (username and password), but only the typical field for password?

A: See [[this thread of the mailing list -> http://article.gmane.org/gmane.comp.web.wiki.pmwiki.user/52420]].
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.AvailableActions</pagename>
<data><![CDATA[(:Summary: All PmWiki page actions (?action=):)
(:div class="rfloat frame" style="font-size:smaller; clear:right;" :)
!!!! Table of contents
* [[#defaultactions| Default actions]]
* [[#enablediag| Enable diag actions]]
* [[#scriptactions | Script actions]]
* [[#cookbook | Cookbook actions]]
(:divend:)

[[#defaultactions]]
!! Default Actions

[[#attr]]
:?action='''attr''': displays dialog for setting/changing password of the specified page, see [[PmWiki/passwords]], see also $EnablePostAttrClearSession if you do not want to have the session cleared after validating change [- {PmWiki/Passwords$:Summary} -]

[[#browse]]
:?action='''browse''': display the specified page (default action if no [@?action=@] is present)

[[#crypt]]
:?action='''crypt''': displays a form for generating hashed [[Passwords | passwords]] out of clear text for usage in your config.php

[[#diff]]
:?action='''diff''': show a change history of the specified page, see [[PmWiki/page history]] [- {PmWiki/PageHistory$:Summary} -]

[[#download]]
:?action='''download'''&upname=''file.ext'': retrieve the page's attachment named ''file.ext'', see $EnableDirectDownload

[[#edit]]
:?action='''edit''': edit the specified page, see [[PmWiki/basic editing]] [- {PmWiki/BasicEditing$:Summary} -]

[[#login]]
:?action='''login''': prompt visitor for username/password

[[#logout]]
:?action='''logout''': remove author, password, and login information

[[#print]]
:?action='''print''': display the specified page using the skin specified by $ActionSkin['print']

[[#refcount]]
:?action='''refcount''': bring up the reference count form, which allows the user to generate a list of links (all, missing, existing or orphaned) in or from specified groups.  See [[Ref Count]]  [- {PmWiki/RefCount$:Summary} -].  Part of the core distribution but must be enabled by the administrator.

[[#search]]
:?action='''search''': displays searchbox on current page, see [[PmWiki/search]] [- {PmWiki/Search$:Summary} -]

:?action='''search'''&q=''searchterm'': performs search with ''searchterm'' and displays results on current page

[[#source]]
:?action='''source''': show page source

[[#feed]]
:?action='''atom''':
:?action='''rdf''':
:?action='''rss''':
:?action='''dc''': If [[web feeds]] are enabled, returns a syndication feed based on the contents of the page or other options provided by the url, see [[PmWiki/web feeds]] [- {PmWiki/WebFeeds$:Summary} -]

[[#setprefs]]
:?'''setprefs'''=SomeGroup.CustomPreferences: sets cookie to custom preferences page. See [[PmWiki/site preferences]] [- {PmWiki/SitePreferences$:Summary} -]

[[#upload]]
:?action='''upload''': display a form to upload an attachment for the current group, see [[PmWiki/uploads]] [- {Cookbook/Uploads$:Summary} -]
[[#defaultactionsend]]
----
[[#enablediag]]
!! Actions enabled by $EnableDiag
[[#BEGENABLEDIAG]]
The following actions are available only if you set @@$EnableDiag = 1;@@ in your configuration file. They can be used for debugging and should not be set in a production environment.

:?action='''ruleset''': displays a list of all markups in 3 columns:
** column 1 = markup-name (1. parameter of markup() )
** column 2 = when will rule apply (2. parameter of markup() )
** column 3 = PmWiki's internal sort key (derived from #2)
->(see [[Custom Markup]] [- {PmWiki/CustomMarkup$:Summary} -]).
->To see more than what [@?action=ruleset@] gives you, apply the [[Cookbook:MarkupRulesetDebugging]] recipe: it can also show the pattern and the replacement strings.
** doesn't make use of PmWiki's authorization mechanisms.

[[#phpinfo]]
:?action='''phpinfo''': displays the output of phpinfo() and exits. no page will be processed
** doesn't make use of PmWiki's authorization mechanisms.

[[#diag]]
:?action='''diag''': displays a dump of all global vars and exits. no page will be processed
** doesn't make use of PmWiki's authorization mechanisms.

[[#ENDENABLEDIAG]]
----
[[#scriptactions]]
!! Actions enabled by PmWiki Scripts

[[#analyse]]
:?action='''analyze''': see [[(PmWiki:)Site Analyzer]] and [[(PmWiki:)Analyze Results]]

[[#approvesites]]
:?action='''approvesites''': see [[PmWiki/Url approvals]] [- {PmWiki/UrlApprovals$:Summary} -]
** doesn't make use of PmWiki's authorization mechanisms.

[[#analyseend]]
----
[[#cookbook]]
!! Actions enabled by [[Cookbook(:.)]] recipes
(more information about [[(PmWiki:)Custom Actions]])

:?action='''admin''': see [[Cookbook:UserAuth2]] [- {Cookbook/UserAuth2$:Summary} -]

:?action='''backup''': see [[Cookbook:BackupPages]] [- {Cookbook/BackupPages$:Summary} -]

:?action='''clearsky''': see [[Cookbook:SearchCloud]] [- {Cookbook/SearchCloud$:Summary} -]

:?action='''comment''': see [[Cookbook:CommentBox]] [- {Cookbook/CommentBox$:Summary} -]

:?action='''comments''': see [[Cookbook:Comments]] [- {Cookbook/Comments$:Summary} -]

:?action='''comment-rss''': see [[Cookbook:CommentDb]] [- {Cookbook/CommentDb$:Summary} -]

:?action='''convert''': see [[Cookbook:ROEPatterns]] [- {Cookbook/ROEPatterns$:Summary} -]

:?action='''converttable''': [[Cookbook:ConvertTable]] [- {Cookbook/ConvertTable$:Summary} -]

:?action='''downloaddeleted''':
:?action='''delattach''':
:?action='''undelattach''': [[Cookbook:Attachtable]] [- {Cookbook/Attachtable$:Summary} -]

:?action='''delete''': see [[Cookbook:DeleteAction]] [- {Cookbook/DeleteAction$:Summary} -]

:?action='''discuss''': see [[Cookbook:DiscussionTab]] [- {Cookbook/DiscussionTab$:Summary} -]

:?action='''downloadman''': see [[Cookbook:DownloadManager]] [- {Cookbook/DownloadManager$:Summary} -]

:?action='''expirediff''': see [[Cookbook:ExpireDiff]] [- {Cookbook/ExpireDiff$:Summary} -]

:?action='''import''': see [[Cookbook:ImportText]] [- {Cookbook/ImportText$:Summary} -]

:?action='''PageUrl''': see [[Cookbook:CommentBoxPlus]] [- {Cookbook/CommentBoxPlus$:Summary} -]

:?action='''pageindex''': see [[Cookbook:ListCategories]] [- {Cookbook/ListCategories$:Summary} -]

:?action='''pdf''': see [[Cookbook:GeneratePDF]] [- {Cookbook/GeneratePDF$:Summary} -] or [[Cookbook:PmWiki2PDF]] [- {Cookbook/PmWiki2PDF$:Summary} -]

:?action='''publish''': see [[Cookbook:PublishPDF]] [- {Cookbook/PublishPDF$:Summary} -]

:?action='''purgeqns''': see [[Cookbook:ASCIIMath]] [- {Cookbook/ASCIIMath$:Summary} -]

:?action='''pwchange''': see [[Cookbook:UserAuth2]] [- {Cookbook/UserAuth2$:Summary} -]

:?action='''imgtpl''': (the  ''imgtpl'' action is called automatically and should not be called by a link in a wiki page)
:?action='''createthumb''': (the ''createthumb'' action is called automatically and should not be called by a link in a wiki page)
:?action='''mini''': (this action is called automatically and should not be called by a link in a wiki page)
:?action='''purgethumbs''': see [[Cookbook:ThumbList]] [- {Cookbook/ThumbList$:Summary} -] \\
 see [[Cookbook:Mini]] [- {Cookbook/Mini$:Summary} -]

:?action='''recipecheck''': see [[Cookbook:RecipeCheck]] [- {Cookbook/RecipeCheck$:Summary} -]

:?action='''regen''': see [[Cookbook:PageRegenerate]] [- {Cookbook/PageRegenerate$:Summary} -]

:?action='''rename''':
:?action='''links''': see [[Cookbook:RenamePage]] [- {Cookbook/RenamePage$:Summary} -]

:?action='''share''':
:?action='''unshare''': see [[Cookbook:SharedPages]] [- {Cookbook/SharedPages$:Summary} -]

:?action='''sitemapaddgroups''':
:?action='''sitemapupdate''': see [[Cookbook:Sitemapper]] [- {Cookbook/Sitemapper$:Summary} -]

:?action='''totalcounter''': see [[Cookbook:TotalCounter]] [- {Cookbook/TotalCounter$:Summary} -]

:?action='''trash''':
:?action='''untrash''': see [[Cookbook:Trash]] [- {Cookbook/Trash$:Summary} -]

:?action='''webadmin''': see [[Cookbook:WebAdmin]] [- {Cookbook/WebAdmin$:Summary} -]

:?action='''zap''': see [[Cookbook:ZAP]] [- {Cookbook/ZAP$:Summary} -]
[[#cookbookend]]

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.BackupAndRestore</pagename>
<data><![CDATA[(:title Backup and Restore:)
(:Summary:background information and some basic backup and restore procedures:)

This page has some background information on making backups and explains some basic *nix backup and restore procedures.

!! Introduction

Your wiki installation contains some unique data in the following directories:

    local/         Local configuration scripts
    cookbook/      Recipes obtained from the [[(Cookbook:)Cookbook]]
    pub/           Publicly accessible files
    wiki.d/        Wiki pages
    uploads/       [[Uploads|Uploaded files]] (attachments)

A good backup plan will include periodically archiving these directories &mdash; or at bare minimum [@local/@] and [@wiki.d/@].  Good practice dictates keeping your backup archives on a separate machine.

!! Simple Backup and Restore (*nix)

When it comes to backup, simpler is better.  
Since the pmwiki distribution is very small (about 1/4 megabyte), it's simplest to just archive the distribution files along with the data.

!!! Making a Backup Archive

The following *nix command, executed from the parent directory of your wiki's directory, will put a complete backup archive of your site in your home directory.

-> [@
tar -zcvf  ~/wiki-backup-`date +%Y%m`.tar.gz  wiki/
@]

[[#restore]]
!!! Restoring the Backup Archive

!!!! Simple Method

Your site can be restored and running in under 30 seconds with

-> [@
tar -zxvf ~/wiki-backup-200512.tar.gz
find wiki/uploads/ -type d |xargs chmod 777
find wiki/wiki.d/ -type d |xargs chmod 777
@]

!!!! A Slightly-More-Secure Method

The simple restore commands above will give you world-writable files and directories.  You can avoid world-writable permissions by letting PmWiki create directories with the proper attributes (ownership and permissions) for you.

Start with

-> [@
tar -zxvf ~/wiki-backup-200512.tar.gz
rm -rf wiki/wiki.d
rm -rf uploads
chmod 2777 wiki/
@]

Now upload a file in each group that had uploads.  If your site doesn't have uploads, just visit your site once so the wiki.d/ directory will be created.

Finish your installation with

-> [@
chmod 755 wiki/
tar -zxvf ~/wiki-backup-200512.tar.gz
@]

!!! Details

The commands on this page assume your site is in a directory called "wiki/".  The test backup was made in December, 2005 so it's named accordingly.

Your site will only have an uploads/ directory if uploads are enabled.

The backup command uses a date stamp (YYYYMM) in the filename.  If you automate the command via cron you'll wind up with monthly snapshots of your site.  You can get a daily snapshot by appending %d to the date command ([@`date +%Y%m%d`@] will get you YYYYMMDD).  Be wary of space limitations if you have a large uploads/ directory.

!! See Also

* A [[http://thread.gmane.org/gmane.comp.web.wiki.pmwiki.user/20317| thread]] [gmane.org] on the pmwiki-users mailing list.
* A [[(Cookbook:)Backup Pages]] recipe in the cookbook.

!! Miscellaneous

!! Backup via FTP
Download and install a ftp client like [[http://filezilla-project.org/download.php?type=client|Filezilla]]

# Using the ftp client connect to the server where you host pmWiki using
## the IP address (ex: 123.234.56.67) or the ftp name (ex: ftp.myhost.com)
## supply your account name (ex: mylogin) and password (ex: myp4ssw0rd)
# Move to your pmWiki directory (ex: @@/usr/mylogin/web/wiki/@@ or @@/tahi/public_html/pmwiki@@ )
# Select the folder you want to backup as explained before (probably either only the data or the whole wiki directory)
** for data you will want to backup both the directories
*** @@wiki.d@@ for user page data
*** @@pmwikiuploads@@ (or @@uploads@@) for your attachments (uploads)
** for system you will want, at a minimum, to backup both the directories
*** @@local@@ for configuration data 
*** @@pub@@ for local CSS and skins customisations
# Download them to a local folder
# Use [[http://www.7-zip.org/ | 7zip]] or a similar software to build an archive of this backup

You can also very easily sync your FTP directories with your hard disc via this command line:
->  [@ wget -nv -np -m ftp://user:password@ftp.yourhost.net/ @]
'-Download [[http://gnuwin32.sourceforge.net/packages/wget.htm | Wget for Windows]] (other systems normally have it installed).-'
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.BasicEditing</pagename>
<data><![CDATA[(:Summary: PmWiki's basic edit syntax:)
(:Audience: authors (basic) :)

The pages on this site are [[Wiki Wiki Web]] pages, which means that pages can be created and edited by multiple authors. To edit a page, click the '''Edit''' link that exists '''somewhere''' on the page, usually in the header or footer. Some pages may be [[password(s)]]-protected, depending on the system's security policies, but many systems allow open editing of pages.

PmWiki is not [[(Wikipedia:)WYSIWYG]] - When editing a page, you see the ''markup text'' that describes the content of the page.  The basic rules for page markup are simple:
# Use a blank line to start a new paragraph [-[[#Paragraphs|more]]-].
# To make a list, start each line with # for numbered (ordered) lists or * for bulleted (unordered) lists [-[[#lists|more]]-].
# To make a heading, start a line with two or more ! marks; !! is a subheading, and !!! is a sub-subheading [-[[#headings|more]]-].
# To emphasize text, enclose it in 2 or 3 ''single quotes''; [@''text''@] for italics or [@'''text'''@] for bold [-[[#emphasis|more]]-].
# To make a link to another page, enclose the page's name in double brackets; for example [@[[basic editing]]@] links to this page [-[[#links|more]]-].
# To make a link to another site, type its address, such as http://example.com/ [- [[#links|more]]-].

'''If you want to experiment with editing a page, try it on the [[Main/Wiki Sandbox]].''' You can [[Main/WikiSandbox?action=edit | edit the Wiki Sandbox]] without affecting anything important on this site. If you do edit other pages, it's courteous to '''sign''' your contribution; using [=~~=]~ effectively 'signs' the name that you provide in the Author field on the Page Edit form.

!! Examples of common markups

The table below demonstrates many of the common markups used to format pages.  The right column shows the effect of the markup, the left column shows what to write to achieve the effect.  More details are available from the [[text formatting rules]] and other documentation pages. An exhaustive list of default markup is available as the [[markup master index]].

!!! [[#Paragraphs]]Paragraphs and line breaks

(:table class='markup horiz' align='center':)
(:cellnr  class='markup1':)
[-'''What to type'''-]
(:cell  class='markup2':)
[-'''What it looks like'''-]
(:tableend:)

(:markup class=horiz:)
Consecutive lines
will be merged together
as part of the same paragraph.

One or more empty lines will start a new paragraph.
(:markupend:)

(:markup class=horiz:)
Two backslashes at the end of a line \\
force a line break.

Or use this markup: [[<<]] to force a break.
(:markupend:)
Further reading:
* [[text formatting rules]] for more information on linebreaks, indented or hanging paragraphs.
* [[wiki styles]] for centered or right justified paragraphs and "floating" text (boxes), borders and much more.

!!![[#lists]]Lists
Start each line with # for numbered (ordered) lists or * for bulleted (unordered) lists:
(:markup class=horiz:)
* Bullet list
* Another item
** More asterisks produce sub-items
** etc.
(:markupend:)

(:markup class=horiz:)
# Numbered lists
# Another item
## more hashes produce sub-items
(:markupend:)

(:markup class=horiz:)
# List types
# can be mixed
** numbered list with unordered sub-list
(:markupend:)

(:if false:)
if someone thinks definition lists are "basic":
(:markup class=horiz:)
: Definition list : list of definitions
: item : the item's definition
: another item : that item's definition
:: indentation : more leading colons produce deeper lists
(:markupend:)
(:ifend:)

Learn more about [[Text Formatting Rules#BulletedLists|lists]] (including [[Text Formatting Rules#DefinitionLists|definition lists]]) and [[(PmWiki:)list styles]].

!!![[#headings]] Headings
Headings are useful for creating a "well-structured" page. They're not just for making big text.

(:table class='markup horiz'  align='center':)
(:cellnr  class='markup1':)
[-'''What to type'''-]
(:cell  class='markup2':)
[-'''What it looks like'''-]
(:tableend:)

(:markup class=horiz:)
!! Major Subheading
!!! Minor Subheading
!!!! And More
!!!!! Subheadings
(:markupend:)

!!![[#emphasis]] Text Emphasis
To emphasize, enclose text in apostrophes (single-quote marks), not double-quotes.

(:table class='markup horiz'  align='center':)
(:cellnr  class='markup1':)
[-'''What to type'''-]
(:cell  class='markup2':)
[-'''What it looks like'''-]
(:tableend:)

(:markup class=horiz:)
''Emphasize'' (italics),
'''strong''' (bold), 
'''''very strong''''' (bold italics).
(:markupend:)

!!![[#links]] Links
To make a link to another page, enclose the page's name in double square brackets.

(:table class='markup horiz'  align='center':)
(:cellnr  class='markup1':)
[-'''What to type'''-]
(:cell  class='markup2':)
[-'''What it looks like'''-]
(:tableend:)

(:markup class=horiz:)
Practice editing in the [[wiki sandbox]]
(:markupend:)
Note that words are automatically ''capitalized'' in page titles. The link above links to the page WikiSandbox.

Text after a pipe (|) is used as the link text:
(:markup class=horiz:)
Practice editing in the
[[WikiSandbox | practice area]].
(:markupend:)

(:comment is this still "basic" or should it be removed? :)
Endings become part of the link text, parentheses hide parts of the link name:
(:markup class=horiz:)
[[wiki sandbox]]es.

[[(wiki) sandbox]].
(:markupend:)

When linking to a page in a different [[WikiGroup]], provide the group name, followed by a separator, and then the page name:
(:markup class=horiz:)
[[Main.Wiki Sandbox]] shows group + name

[[Main/Wiki Sandbox]] shows only name
(:markupend:)

Links to external sites
(:markup class=horiz:)
bare url:  http://google.com

link text: [[http://google.com | Google]]
(:markupend:)

Colons make [[InterMap]] (also called InterWiki) links to other wikis:
(:markup class=horiz:)
What's an [[Wikipedia:aardvark]], anyway?
(:markupend:)

Links to [[nonexistent pages]] are displayed specially, to invite others to create the page.

PmWiki supports more link types and a lot of display options, see [[Links]] to learn more.

!!!Preformatted text
Preformatted text is displayed using a monospace font and not generating linebreaks except where explicitly indicated in the markup.

Note that very long lines of preformatted text can cause the whole page to be wide.

For preformatted text with markup (e.g. emphasis) being processed, start each line with a space:
(:markup class=horiz:)
 Lines that begin with a spece
 are formatted exactly as typed
 in a '''fixed-width''' font.
(:markupend:)

If you don't want Wiki markup to be processed, use [=[@ @]=]. Can also be used inline.
(:markup class=horiz:)
[@
Text escaped this way has
the HTML ''code'' style
@]
(:markupend:)

!!! Escape sequence
If you don't want Wiki markup to be processed, but lines reformatted use [@[= =]@]. Can also be used inline.
(:markup class=horiz:)
[=
markup is ''not'' processed
but lines are reformatted
=]
(:markupend:)

!!! Horizontal line
(:markup class=horiz:)
Four or more dashes at
the beginning of a line
----
produce a "horizontal rule"
(:markupend:)

!!! Tables
Simple tables use double pipe characters to separate cells:
(:markup class=horiz:)
|| border=1
||! head 1 ||! head 2 ||! head 3 ||
|| cell 1  ||  cell 2 ||  cell 3 ||
(:markupend:)
See [[Tables|simple tables]] and [[Table Directives|advanced tables]] to learn more about the rich feature set of PmWiki tables.

!!! Images
See [[Images]]

(:if false:)
IMO this is not "basic" and should be removed from this page --OliverBetz
!!!Indented and "hanging" paragraphs
(:markup class=horiz:)
-> An arrow (->) indents content.

   Line up text to continue the indent.

-->Longer arrows (-->) indent further.

-<A reverse arrow (-<) creates a hanging indent, the first line is outdented and remaining lines are indented.
(:markupend:)
(:ifend:)

!!! Character formatting

(:table class='markup horiz'  align='center':)
(:cellnr  class='markup1':)
[-'''What to type'''-]
(:cell  class='markup2':)
[-'''What it looks like'''-]
(:tableend:)

(:markup class=horiz:)
* @@Monospaced text@@
* Text with '^superscripts^'
* Text with '_subscripts_'
* deleted {-strikethrough-} text
* inserted {+underline+} text
* [+big+], [++bigger++] text
* [-small-], [--smaller--] text
(:markupend:)

Use [[WikiStyles]] to change %red% the %blue% text %green% %color=#ff7f00% color %%.

[[#pagetitles]]
!!! Page titles

* The [@(:title:)@] directive sets the page's title to something other than its page name.
(:markup class=horiz:)
(:Title Basic PmWiki editing rules:)
The title of this page is {$Title}, spaced as {$Titlespaced}.
(:markupend:)

[[#pagesummary]]
!!! Page Description

* The [@(:Description Page summary here:)@] directive sets the page description. The description is used by search engines, and can displayed in search results and in [[page lists]].
(:markup class=horiz:)
(:Description PmWiki's basic edit syntax:)
The summary description of this page is {$Description}.
(:markupend:)

>>faq<< [[#faq]]
[[#beginning]]
Q: I'm new to PmWiki, where can I find some basic help for getting started?
A: The [[Basic Editing]] page is a good start.  From there, you can just follow the navigational links at the bottom of the page (they are called [[Wiki Trails]]) to the next pages, or to the [[Documentation Index]] page, which provides an outline style index of essential documentation pages, organized from basic to advanced.

Q: How do I include special characters such as Copyright (&#169;) and Trademark (&#174; or &#8482;) on my wiki pages?
A:  See [[special characters]] on how to insert special characters that don't appear on your keyboard.

Q: Why are separate lines of text in the markup combined into a single line on output?
A: PmWiki normally treats consecutive lines of text as being a paragraph, and merges and wraps lines together on output. This is consistent with most other wiki packages. An author can use the [@(:linebreaks:)@] directive to cause separate lines of markup text to be kept as separate lines in the output. A wiki administrator can set in config.php @@$HTMLPNewline = '<br/>';@@ to force literal new lines.

Q: Can I just enter HTML directly?
A: By default (and by design), PmWiki does not support the use of HTML elements in the editable markup for wiki pages. There are a number of reasons for this described in the [[PmWiki Philosophy]] and [[PmWiki:Audiences]]. Enabling HTML markup within wiki pages in a collaborative environment may exclude some potential authors from being able to edit pages, and pose a number of display and security issues. However, a site administrator can use the [[Cookbook:Enable HTML]] recipe to enable the use of HTML markup directly in pages.

Q: Where can I find more documentation?
A: See the [[Documentation Index | documentation index]] and the [[markup master index]] pages.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Ed W</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.BasicVariables</pagename>
<data><![CDATA[(:Summary: core variables:)

:$BaseNamePatterns:Allows population of the [@{$BaseName}@] PageVariable.  The key to the hash is the pattern to be replaced and the value is the replacement string.
:      :[@
# If {$FullName} is "Group.Page-Draft" then {$BaseName} is "Group.Page"
$BaseNamePatterns['/-Draft$/'] = '';
# If {$FullName} is "Comments-Group.Page" then {$BaseName} is "Group.Page"
$BaseNamePatterns['/^Comments-/'] = '';@]

:$DefaultGroup:[[WikiGroup]] used by default (on startup) when no group is specified in the URL, as in "{$DefaultGroup}".  

:$DefaultName:Name of the default HomePage of each WikiGroup.  Used when the group doesn't have a page with the same name as the group, as in "{$DefaultName}".

:$DefaultPage:Startup page when PmWiki is called without a specified page, normally ''$DefaultGroup.$DefaultName''.

Note: for $DefaultGroup, $DefaultName and $DefaultPage variables to work, they should be defined in the beginning of (farm)config.php, before any call to the function ResolvePageName(). This means, before any script from PmWiki and before any recipe that might be using this function.

:$SiteGroup:Default group for storing configuration and utility pages such as [[Site.Search]], [[Site.EditForm]], [[Site.PageNotFound]], etc, as in "{$SiteGroup}".

:$SiteAdminGroup:Default group for locked administrative pages such as [[SiteAdmin.AuthList]], [[SiteAdmin.AuthUser]], [[SiteAdmin.ApprovedUrls]], etc, as in "SiteAdmin".

:$EnableWSPre:Enables a markup rule that causes lines with leading spaces to be treated as sections of preformatted text.  If set to a value greater than 1, indicates the minimum number of leading spaces required for this treatment.
:      :[@$EnableWSPre = 1;             # leading spaces are preformatted text@]
:      :[@$EnableWSPre = 0;             # leading spaces are normal lines of text@]
:      :[@$EnableWSPre = 4;             # 4+ spaces are preformatted text@]

:$EnableWikiWords:Enable [[WikiWord]] processing.

:$LinkWikiWords:If set, then bare WikiWords in a page are automatically linked to pages of the same name.  Note that this value can also be affected by the [@(:linkwikiwords:)@] and [@(:nolinkwikiwords:)@] directives.
:      :[@$LinkWikiWords = 1;           # turn on WikiWord links@]
:      :[@$LinkWikiWords = 0;           # disable WikiWord links@]

:$SpaceWikiWords:If set, then WikiWords in pages are automatically spaced according to $AsSpacedFunction.  Note that this value can also be affected by the [@(:spacewikiwords:)@] and [@(:nospacewikiwords:)@] directives.
:      :[@$SpaceWikiWords = 1;          # turn on WikiWord spacing@]
:      :[@$SpaceWikiWords = 0;          # turn off WikiWord spacing@]

:$AsSpacedFunction:The name of the function used to convert WikiWords into normal, spaced strings.  Defaults to '`AsSpaced'.
:      :[@$AsSpacedFunction = '`MyAsSpaced';@]

:$EnablePGCust:Allows/disables per-page and [[PerGroupCustomizations | per-group customizations]].  Can be set to zero in any [[local customization(s)]] file to prevent remaining page/group customizations from being loaded.
:      :[@$EnablePGCust=0;              # turn off per-page/group configs@]

:$EnableLocalConfig:Allows/disables local/config.php customizations (usually for a farm's wikis).  Can be set to zero in local/farmconfig.php to prevent the farm's wikis' local/config.php from being loaded.
:      :[@$EnableLocalConfig = 0;    # disable PmWiki's local/config@]

:$GroupPattern: The regular expression pattern used for valid [[WikiGroup]] name specifications.  Defaults to allowing any group name beginning with an uppercase letter, but can be set to limit the valid group names (see Cookbook:LimitWikiGroups).
:      :[@# limit groups to Site, SiteAdmin, PmWiki, and `MyGroup@]
:      :[@$GroupPattern = '(?:Site|SiteAdmin|PmWiki|`MyGroup)';@]

:$NamePattern: The regular expression pattern used for valid page names.  Defaults to allowing pages beginning with an uppercase letter or digit, followed by sequences of alphanumeric characters, hyphens, and underscores.  

:$WikiWordPattern: The pattern that describes a WikiWord.

:$Author: Set to the current reader, who is potentially an author ([[PmWiki:AuthoringPhilosophy|see discussion]]), as in "{$Author}". See also $EnablePostAuthorRequired.

:$AuthorGroup: The WikiGroup for user profiles. Defaults to 'Profiles'.
:      :[@$AuthorGroup = 'Users';@]

:$AuthId: For sites using [[AuthUser | user-based authorization]], tracks the "reader" or login name.
:      :[@SessionAuth($pagename);@]
:      :[@if( isset($AuthId) ) { // this person has been authenticated@]

:$AuthPw: Request for documentation, meanwhile see [[http://permalink.gmane.org/gmane.comp.web.wiki.pmwiki.user/30037|here]].
:      :[@SessionAuth($pagename);@]
:      :[@if( isset($AuthPw) ) { // this person has entered a password@] 

:$TimeFmt: The format to use for dates and times, in [[http://php.net/strftime | strftime()]] format.  The default value is [@'%B %d, %Y at %I:%M %p'@], which gives dates of the form "September 8, 2005 at 10:57 PM".
:      :[@$TimeFmt = '%B %d, %Y';        # dates as "September 8, 2005"@]
:      :[@$TimeFmt = '%Y-%m-%d';         # dates as "2005-09-08"@]

:$FTimeFmt:Can be used to override the default date format used by the "ftime" function.  The default $FTimeFmt is $TimeFmt.  (See [[Markup Expressions]])

:$LogoutRedirectFmt: Identifies the page to which the visitor should be sent after an [@?action=logout@].  Defaults to the current page.
:      :[@$LogoutRedirectFmt = 'Site.Logout';    # ?action=logout target@]

:$LogoutCookies: An array of cookie names to be removed when [@?action=logout@] is invoked.

:$CookiePrefix: A string prefix to be prepended to cookies set from PmWiki scripts.  It defaults to '', but can be set to a different value to avoid conflicts with similar-named cookies from other applications, or to allow multiple wikis from the same domain to store separate cookies.
:      :[@$CookiePrefix = 'pmwiki_';@]     # set cookie prefix to 'pmwiki_'
::If you have a [[WikiFarm(s)]], use the following in each field's ''config.php'' to get a unique prefix for each field in the farm, thus isolating each field's cookies.:
:      :[@$CookiePrefix = substr($tmp = md5(__FILE__), 0, 5).'_';@]

:$Version: A string representing the release version of PmWiki, as in "{$Version}".

:$VersionNum: A number representing the release version of PmWiki,
 with the major and minor release components padded with zeroes to
 produce three digits.  Thus, release "pmwiki-2.1.40" will have
 $VersionNum set to 2001040, as in "{$VersionNum}".

 The first digit is a 2, the next three digits are the major
 release number, and the last three digits are the minor release
 number. Beta releases use 900-999 for the minor release number.
 Thus:
--> [@
2.1.0          2001000
2.1.1          2001001
...
2.1.27         2001027
2.2.0-beta1    2001901
2.2.0-beta2    2001902
...
2.2.0-beta18   2001918
...
2.2.0          2002000
@]

:$EnableRedirect:When enabled (default), causes page redirects to automatically be performed by the browser.  Setting $EnableRedirect to zero causes PmWiki to pause and issue a "Redirect to ''link''" message instead.  This is sometimes useful when debugging recipes to be able to see the results of actions before page redirections occur.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Blocklist</pagename>
<data><![CDATA[(:Summary:Blocking IP addresses, phrases, and expressions to counteract spam and vandalism.:)
(:Audience: administrators (basic) :)

The block list is one of a number of [[security]] measures that can be taken to protect your wiki from unwelcome postings.

Unfortunately, the open-editability of many wiki systems often makes them attractive targets for "link spam" or "wikispam", in which links are added to pages in an effort to increase search engine rankings or drive traffic to other sites.  Also, many link spammers have developed automated systems to locate sites that accept visitor input and attempt to flood the site with unwanted links.
Also, and harder to deal with, is just plain [[PmWiki/Security#wikivandalism|wiki vandalism]] where nonsense changes are made, often replacing entire pages.

By far the best countermeasure against wikispam is to restrict editing through the use of passwords (see [[Passwords]] and [[Passwords Admin]]).  Experience has shown that passwords can be effective even if the password is widely known, and even if the password is publicly available on the site itself.  However, there are many cases where passwording may be an impediment, so these will generally want to use some form of blocklist.

!! Blocklist basics

A ''blocklist'' is a list of IP addresses, phrases, and expressions which are prevented from being added into pages on the website.  PmWiki is distributed with a built-in blocklisting capability; blocklists can be enabled by adding the following line to ''local/config.php'':

-> $EnableBlocklist = 1;

This tells PmWiki to scan the [[SiteAdmin.Blocklist]] page and the "SiteAdmin.Blocklist-Farm" page (and possibly other pages -- see below) looking for phrases and IP addresses to be excluded from posting to the site.

!!! Blocking by word or phrase
The simplest form of block is simply a line containing "[@block:@]" followed by a word or phrase to be excluded from postings.  For example, a line like 

-> [@block:spam.com @]

in SiteAdmin.Blocklist will block any posts containing the string "spam.com" (case-insensitive) anywhere in the post.

[[#blockbyipaddress]]
!!! Blocking by IP address
Sometimes we wish to restrict posts coming from particular addresses or address ranges that are known as sources of wikispam.  If a blocklist page contains IP addresses of the form "a.b.c.d" or "a.b.c.*", then any posts coming from that address or range will be blocked. 

-> %note% To find an author's IP address, try hovering the mouse over the author name in the [[page history]] for a page.

!!! Blocking by regular expression or pattern
Blocking on simple words can sometimes pose difficulties; for example, a simple "[@block:cial@]" entry will also block the word "specialist".  For these cases it's often helpful to use a regular expression, as in:

->[@block:/\bcial\b/@]

This says to block "cial" only if it doesn't occur in the middle of a larger word.  The leading slash (/) after "block:" tells PmWiki to use a regular expression match instead of a simple string match.  (Blocklist uses PCRE or "Perl Compatible Regular Expressions"; see http://php.net/manual/en/ref.pcre.php for more information.)

!!!! Regular expression to block 'href'

If you want to block '@@href@@', you can use the following markup:
-> [@block:/[^\w\\]href\b/@]
which blocks '@@href@@', but neither '@@\href@@' nor '@@toughref@@'.

The regular expression can be interpreted as follows: Match any character that is '''neither''' a word character
'''nor''' a '\', followed by @@href@@ which ends in a word boundary.

!! Letting authors know why they've been blocked

By default, blocklist only tells an author that a particular edit has been blocked, but doesn't give a specific reason for the blocking (e.g., the offending phrase).  Setting the following in a local customization file will also provide the reasons for the block:

-> $EnableWhyBlocked = 1;

!! Managing multiple blocklists

PmWiki allows blocklist entries to come from multiple pages by setting the $BlocklistPages variable.  By default $BlocklistPages is set to "SiteAdmin.Blocklist", as well as any automatically downloaded blocklists as described below.  PmWiki will use all entries in all the blocklists for filtering wikispam. Setting a value of $BlocklistPages changes the default:

-> $BlocklistPages = array('Main.Blocklist', '{$Group}.Blocklist');

The order of blocklists really doesn't matter -- all of the blocklist
pages ultimately get used, and the [@unblock:@] entries are processed 
after all of the blocklist pages have been loaded.

[[#automaticblocklists]]
!! Automatically downloaded blocklists

Maintaining blocklists is relatively easy to do, but can become tedious over time.  Several groups have formed and maintain "shared blocklists", where a common blocklist is made available to all.  PmWiki's blocklist capability has built-in features for automatically downloading and updating such shared blocklists.

If you're just in a hurry to make use of some standard blocklists, make the following setting in ''local/config.php'':

-> $EnableBlocklist = 10;

This tells PmWiki to not only enable blocklists on the site, but to also configure itself to automatically retrieve and maintain local copies of well-known blocklists such as [[(http://)chongqed.org]] and [[http://moinmaster.wikiwikiweb.de/|MoinMaster]].  These local copies will be saved in SiteAdmin.Blocklist-Chongqed and SiteAdmin.Blocklist-MoinMaster and refreshed once per day (as determined by the value of $BlocklistDownloadRefresh).

To automatically retrieve the [[SiteAdmin.Blocklist]] page used at pmwiki.org, add the following setting in ''local/config.php'':

-> [@ $BlocklistDownload["$SiteAdminGroup.Blocklist-PmWiki"] = array('format' => 'pmwiki'); @]

!! Ignoring specific entries in a blocklist (unblock)

When using a large master blocklist or blocklists automatically refreshed from external sites, it may be that some entries in the blocklists are inappropriate or overeager and block legitimate content.  In this case a wikiadministrator can use "unblock" in a blocklist page to ignore an entry from the blocklist.  For example, to allow "spam.com" even if another blocklist has a block entry for it:

-> unblock:spam.com

In order for unblocking to work the phrase or pattern following "unblock:" must be ''exactly'' the same as the original.

!! Permissions on blocklist pages

In general, an [[(wiki )administrator]] will want to edit-protect the SiteAdmin.Blocklist and any other blocklist pages to prevent arbitrary changes to the blocklist (see [[Passwords]]).  Since most pages in the SiteAdmin.* group are edit-protected by default anyway, this usually isn't a problem.

Administrators may also wish to read-protect the various blocklist pages so that others do not know the exact phrases and/or IP addresses that are being blocked.  (By their nature blocklists tend to contain phrases or terms that may be offensive or inappropriate to some.)

Any pages created via automatic download (see above) are automatically locked against viewing except by administrators.  

%audience% administrators (intermediate)
!! Detailed configuration of automatically downloaded blocklists

Automatic downloading of blocklist information is controlled by the $BlocklistDownload array.  An entry for MoinMaster might look like:

-> $BlocklistDownload["$SiteAdminGroup.Blocklist-MoinMaster"] = array(
--> 'url' => 'http://moinmaster.wikiwikiweb.de/BadContent?action=raw',
--> 'format' => 'regex',
--> 'refresh' => 86400);

This says to download the blocklist data from the given url into the SiteAdmin.Blocklist-MoinMaster page, that the entries in the blocklist are regular expressions, and to refresh the information every 86,400 seconds (one day).

If 'refresh' is omitted, then the page will be refreshed at the time interval given by $BlocklistDownloadRefresh (default one day).  If 'format' is omitted, the page is assumed to have PmWiki-formatted entries as described above.  If 'url' is omitted, then the blocklist information is downloaded from a standard location on the pmwiki.org site.

To force a refresh of an automatically downloaded blocklist, simply delete the existing page -- a new version will be installed upon the next blocklist scan.  Blocklist pages are checked for download in response to any ?action=edit request.

If you are specifying your Blocklist-Pages in the config.php you have to specify the automatically updated pages too, else they won't be updated or created even if you use $EnableBlocklist = 10; .

!! Farm-wide blocklist

A blocklist can be applied farm-wide  (see [[(Cookbook:)SharedPages]]).  
After these pages are created they can be moved into the farm ''shared.d/'' directory:

!! [[#variables]] Blocklist Variables

The following variables help control the configuration and operation of blocklists:

:$EnableBlocklist:If set to a non-zero value, then blocklists are enabled on the site.  If set to a value of ten or higher, then add entries for automatic downloads of standard blocklists.
: : $EnableBlocklist = 1;              # enable blocklists
: : $EnableBlocklist = 10;             # auto-configure standard blocklists

:$EnableWhyBlocked:By default, authors are not told which particular phrases or IP addresses are causing a particular post to be blocked; setting $EnableWhyBlocked to 1 provides this information.
: : $EnableWhyBlocked = 1;             # give reasons for blocking

:$BlocklistPages:An array of pages to be checked for blocklist entries.  The elements of the array may contain [[page variables]].  Defaults to "Site.Blocklist", plus any other automatically downloaded blocklist pages.

:$BlocklistMessageFmt:The message to provide the author whenever a post has been blocked.

:$BlockedMessagesFmt:If $EnableWhyBlocked is set, defines the text to use for each type of block being performed.  Currently only 'ip' and 'text' are recognized.
: : BlockedMessagesFmt['ip'] = "$[IP address blocked from posting]: ";
: : $BlockedMessagesFmt['text'] = "$[Text blocked from posting]: ";

:$BlocklistDownload:An array of automatically-downloaded blocklists.  The keys of the array are the pages in which the blocklists should be stored, the values contain the url, format, and refresh interval for the downloaded blocklist.
->[@  # Download the MoinMaster blocklist every twelve hours
  $BlocklistDownload["$SiteAdminGroup.Blocklist-MoinMaster"] = array(
    'url' => 'http://moinmaster.wikiwikiweb.de/BadContent?action=raw',
    'format' => 'regex',
    'refresh' => 43200);
  # Download a shared blocklist from pmwiki.org every day
  $BlocklistDownload["$SiteAdminGroup.Blocklist-Shared"] = array(
    'format' => 'pmwiki');
@]

:$BlocklistDownloadRefresh:The default refresh interval for any $BlocklistDownload entries that don't explicitly specify a 'refresh' value.
: : # perform automatic downloads once per week by default
: : $BlocklistDownloadRefresh = 86400 * 7;

:$BlocklistDownloadFmt:The format to use when saving automatically downloaded blocklists.

:$EnableBlocklistImmediate:Some cookbook recipes update pages with author input but don't use the built-in data posting routines.  If $EnableBlocklistImmediate is set (default) and the current action is listed in $BlocklistActions (below), then an immediate blocklist scan is performed on the incoming text.

:$BlocklistActions:A list of actions for which immediate blocklist checks should be performed (see $EnableBlocklistImmediate above).
: : # perform immediate checks for ?action=comment
: : $BlocklistActions['comment'] = 1;
: : # perform immediate checks for ?action=postdata
: : $BlocklistActions['postdata'] = 1;
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Categories</pagename>
<data><![CDATA[(:Summary:Categories are a way to organize and find related pages:)
(:keywords categories, tags:)
(:Audience: authors (intermediate) :)

!!Purpose of categories
Categories (also known as "tags") are a way to organize and find related pages.  Categories are implemented by default in PmWiki 2, and in most wikis they don't require any special code or markup, they're just a useful convention.  The idea is that every page that falls into a particular subject area should have a link to a shared page containing links to other pages on that subject.  These pages are created in the ''Category'' group, and thus these subject areas are called "categories".

!!Using categories
Getting categories to work requires two steps, the first of which is adding links to each category.  A category named Subject is created by adding a link to [=Category.Subject=] on any page.  When you add the link to a page, the page can be described as being ''in'' the category "Subject".  

There is a special markup for creating these links which makes categories work more smoothly: [=[[!Subject]]=] will create a link to Category.Subject. So [=[[!Subject]]=] is a kind of shortcut to the page Subject in the category group.

If you click on the category links on a page, initially you'll just be taken to an empty page named ''Category.Subject''.  The second step in setting up categories is to modify the behavior of pages in the category group so that they will display a list of all pages containing links to ''Category.Subject''.  This is relatively simple to do:

# Open the page [[Category.GroupFooter]] for editing. (Be careful : the group "Category" may be called otherwise in international wikis.)
# Add the line [@(:pagelist link={*$FullName} list=normal:)@]
# Save the edits.

This will cause the footer on every page in the ''Category'' group to display a list of links to pages that reference that page in the category group.

It is worth noting that rather than adding this to Category.GroupFooter, the pagelist directive can be added to Category.GroupHeader to similar effect; it just depends on whether you'd prefer to have the list of pages appear before or after any text that you add to the individual category pages (which can be edited just like normal pages).

Because we use the normal [[Cookbook:PagelistExplained|PageList]] @@link=@@ markup, you can use it not only in the category group. If you want to show all pages belonging to the category Subject you can use on any wiki page [@(:pagelist link=Category.Subject list=normal:)@].

Similarly, there's no requirement that a "category page" has to be in the ''Category'' group -- any page can define a "category" of pages that link to it.

An administrator can override the default category group name of "Category" by setting the $CategoryGroup variable in ''config.php'' to another group name.

A page author can also link to a category list without adding the linking page to the category by using [=[[ {Category.Subject$PageUrl} | Subject ]]=].  This will create a link that looks like [=[[!Subject]]=] without adding the linking page to the category listing.

!!!Recap
So, by adding the link [=[[!Subject]]=] to a page, a link to that page will automatically appear on the page ''Category.Subject'', as long as  ''Category.GroupFooter'' has been tweaked appropriately.  Thus, you can create a page that automatically creates an alphabetized list of all movies discussed on your wiki by creating links to [=[[!Movies]]=] on each film's page; the resulting automatic list would be on the page ''Category.Movies'' .  

%audience% authors (advanced)
[[#CategoryNesting]]
!!Category nesting
Categories have the potential for even greater usefulness because [@Category.*@] pages can themselves be placed into categories!  To follow an excellent example from John Rankin, let's suppose we have the following film pages in the categories listed to the right:

-> [@
Film.ShaunOfTheDead   [[!Horror]] [[!Comedy]] [[!2003]]
Film.InMyFathersDen   [[!Drama]] [[!2004]]
Film.TheCorporation   [[!Documentary]] [[!2003]]
@]

Now then, we can create [@Category.Horror@], [@Category.Comedy@], [@Category.Drama@], and [@Category.Documentary@], and in each one of those pages we put [@[[!Genre]]@].  In [@Category.2003@] and [@Category.2004@], we put [@[[!Year]]@].

So, what happens when we display [@Category.Genre@] ?  We see links to "Comedy", "Drama", "Documentary", and "Horror", because they're in the Genre category.  When we click on one of those links, we see all of the films listed in one of those categories.  Similarly, if we click on [@Category.Year@], we see links to "2003" and "2004", each of which in turn displays the list of films for that year.

Finally, in [@Category.Genre@] and [@Category.Year@] we can put [@[[!Category]]@], which makes them "top-level" categories reachable from the [@Category.Category@] page.  Voila, we now have an instant "hierarchy":

-> [@
Category.Category
    Category.Genre
        Category.Comedy
            Film.ShaunOfTheDead
        Category.Drama
            Film.InMyFathersDen
        Category.Documentary
            Film.TheCorporation
        Category.Horror
            Film.ShaunOfTheDead
    Category.Year
        Category.2003
            Film.ShaunOfTheDead
            Film.TheCorporation
        Category.2004
            Film.InMyFathersDen
@]

Note however that this isn't a "strict" hierarchy--i.e., any page or category can appear simultaneously in multiple categories.  For example, [@Category.Documentary@] could be a member of both the Genre and top-level category listings.

Each category page can have content text before the generated list, e.g., to give a generic description of things in the category. (Or it can be empty, which works fine.) It can also contain associations to related categories ("see also" references). For example, in a tourism wiki, the ''bed and breakfast" category might contain a see-also reference to the "self-catering" category.

%audience% administrators (intermediate)
!!The guts of the category markup
As mentioned, all of the necessary markup features for Categories are enabled by default in current releases of PmWiki 2.0, but here's how they work for those who are interested.  The use of the Category group as the repository for all categories is determined by setting the $CategoryGroup variable, and the special [=[[!Subject]]=] markup is activated by a call to the Markup() function:
 
-> [@SDV($CategoryGroup,'Category');
Markup('[[!','<links','/\[\[!([^\|\]] ?)\]\]/',
  "<span class='category'>[[$CategoryGroup/$1]]</span>");
@]

!!Coming up with good category schemes
The hard part about using categories is choosing a good vocabulary. Site content managers may wish to follow the Guidelines for the establishment and development of monolingual thesauri (ISO 2788-1986) and the Guidelines for the establishment and development of multilingual thesauri (ISO 5964-1985). Questions to think about include:
* whether a scheme already exists and can be reused
* number of levels in a multilevel scheme (not too shallow, not too deep -- e.g. 3)
* number of categories per page (not too many, not too few -- e.g. 3)
* consistent use of singular ([@[[Mercury]] is a [[!planet]]@]) or plural ([@[[Mercury]] is in the [[!planets]] category@])
* disambiguation and use of phrases ([@[[!musical instruments]]@] and [@[[!medical instruments]]@])  or [[Cookbook:Subpage Markup]] ([@[[!Instruments*Musical]]@] and [@[[!Instruments*Medical]]@])

Or you can just let people use whatever category terms they find meaningful. A vocabulary (or "folksonomy") will emerge over time.

!!Showing a list of categories

To show a list of categories we can use a pagelist for the pages in the category group. 
For instance the following will list pages in the Category group, put it on page [[Category.Category]] for convenience, or on any other page:

->[@(:pagelist group=Category list=normal fmt=#title:)@]

But there is a problem: Just adding a category markup to a page will not create a corresponding category page, even though following the link will show the page with a list of pages linking to it!\\
To have category pages automatically created in group 'Category'  add the following to config.php:

->[@$AutoCreate['/^Category\./'] = array('ctime' => $Now, 'text' => $page['text']);@]

Change 'Category' to the name of your category group. You can also add more definitions for more category groups, useful if you use a recipe like Cookbook:Tagger which allows multiple category groups.

See also [[PmWiki/EditVariables#AutoCreate]]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>dw</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.ChangeLog</pagename>
<data><![CDATA[(:Summary: Log of changes made to PmWiki by [[Release(Notes)]]:)
See [[Cookbook:RecentChanges | the cookbook recent changes page]] for additional updates and activity by other developers, or join the [[PmWiki/MailingLists | pmwiki mailing lists]] to discuss feature development with us.

(:comment Changes made to the [[PmWiki:Subversion | subversion pre-release ]] of PmWiki.:)
!!! Version 2.2.4 (2009-07-16)
* Fix bug with page attributes, which somehow didn't make it in the 2.2.3 release.
* Fix bug with HTML entities in XLPages introduced earlier today in 2.2.3 (reverted, PITS:01111).

!!! Version 2.2.3 (2009-07-16)
* Fix action=logout could incorrectly set a session cookie (PITS:01062).
* Fix page history trim in vardoc.php (PITS:01103).
* Add $EnableUploadGroupAuth, use group password for downloads (PITS:01104).
* Fix recursive PTV loops, added $MaxPageTextVars (PITS:00915, PITS:01099).
* Fix mkdirp() messages for absolute paths (PITS:00396).
* Fix sample-config.php order for urlapprove.php (PITS:01037).
* Fix broken signature links on preview.
* Fix crypt.php (action=crypt) could malfunction for passwords with quotes or apostrophes.
* Fix @@ @_site_*@@ passwords to work in GroupAttributes (PITS:00836, PITS:00998).
* Fix possible XSS vulnerabilities, reported by Michael Engelke.
* Update documentation.

!!! Version 2.2.2 (2009-06-21)
* Fix class in pages not on the breadcrumbs trail, reported by Ed W.
* Fix @@tabindex@@ and @@onclick@@ to guiedit buttons.
* Fix $GroupPrintHeaderFmt in print.php (PITS:01073).
* Fix global vars in xlpage-utf-8.php (PITS:00980).
* Fix $txt in LinkPage (reported by Eemeli Aro).
* Add $EnableNotifySubjectEncode for international wikis (Cookbook:UTF-8).
* Fix international message in Abort().
* Fix security bug with AuthUser, reported by Eemeli Aro. See [[Release notes]].
* Fix $ActionTitleFmt for login and upload, reported by Eemeli Aro.

!!! Version 2.2.1 (2009-03-28)
* Fix $FPLTemplateMarkupFunction which somehow didn't get in the 2.2.0 archive.
* Fix wikitrails to work cross-group (PITS:00407).
* Add $EnableRedirectQuiet variable (PITS:00919).
* Fix [={$Title}=] could display global variables (reported by HansB).
* Fix reloaded form submissions could lose values (reported by DaveG).
* Fix preview while restoring a version from history (PITS:01081).
* Fix relative links with international characters (reported by G. Hermanowicz).
* Add in sample-config.php example call to xlpage-utf-8.php (PITS:01066).
* Update documentation.
* Fix guiedit.php to produce valid HTML.

!! Version 2.2.0 (2009-01-18)
* Convert beta series to official release series.
* Add $FPLTemplateMarkupFunction (PITS:00984, requested by John Rankin).

!!! [[#beta68]] Version 2.2.0-beta68 (2008-08-14)
* Fix E_NOTICE errors reported by Dominique Faure.
* Enable [@(:redirect:)@] directives in pagelists.

!!! [[#beta67]] Version 2.2.0-beta67 (2008-07-13)
* Add [={$LastModifiedTime}=] page variable.
* Add $EnableSessionPasswords variable to control session password usage.
* Add $SessionEncode and $SessionDecode variables to specify functions for encoding/decoding sensitive session data.
* Updated httpauth.php to use SessionAuth instead of poking in session guts directly.

!!! [[#beta66]] Version 2.2.0-beta66 (2008-07-04)
* Add content-type/charset to Abort() output (suggested by Petko).
* Close minor XSS vulnerability (PITS:01030).
* Add "nested if" capability.
* Fix bug in $Transition handling that would enable all transitions if any were set (reported by John Rankin).
  

!!! [[#beta65]] Version 2.2.0-beta65 (2007-11-17)
* Fix SiteAdmin.AuthList so that it defaults to list=all (reported by Roman).
* Fix pmwiki skin to include xmlns= attribute in <html> tag (PITS:00989, reported by Mateusz Czaplinski and Petko Yotov).

!!! [[#beta64]] Version 2.2.0-beta64 (2007-11-13)
* Add times to PmWiki date parsing (e.g., 2007-08-09T12:22:04).
* Suppress warning from ini_set in diag.php (suggested by Petko).
* Fix handling of -> links in trails (reported by Eemeli Aro).
* Add .kml and .kmz as valid attachment types. 
* Fix handling of [=&amp;=] in markup (PITS:00988, reported by Stirling Westrup).
* Fix duplication of language markers in $XLLangs (PITS:00987, reported by Stirling Westrup).
* Correct typo in DRange() call in stdmarkup.php (reported by Stirling Westrup).
* Turn on error displays when diagnostics are enabled.
* Default PHP's pcre.backtrack_limit to at least 1000000.

!!! [[#beta63]] Version 2.2.0-beta63 (2007-07-31)
* Added $SkinDirectivesPattern to allow adjustments to available skin directives (requested by Petko).
* Fix default permissions on Site.AuthUser and Site.AuthList (reported by Scott Connard).
* Add "monospace" to pmwiki.css default (reported by Joshua Timberman, with assistance from H. Fox)
* Fix problem with slashes in wildcards to name= and group= parameters (reported by Ian MacGregor).

!!! Version 2.2.0-beta62 (2007-07-21)
* Fix bug in trails introduced by beta61 (reported by charlequin).

!!! Version 2.2.0-beta61 (2007-07-19)
* Add ability to grab trails by section.
* Add an "ontrail" condition (from suggestions by charlequin).

!!!Version 2.2.0-beta59, 2.2.0-beta60 (2007-07-18)
* Fix problem with upgrade.php on [[wiki farms]] (reported by Scott Connard).
* Fix problem with distributed version of Site.AuthUser (reported by Jon Haupt).

!!!Version 2.2.0-beta58 (2007-07-17)
* Significant change: Site.AuthUser, Site.Blocklist, Site.ApprovedUrls, and Site.NotifyList now appear in the [[SiteAdmin]] group by default.
** Note: if you limit groups by setting $GroupPattern, you now need to include SiteAdmin (see [[Cookbook:LimitWikiGroups]])
* Abort if ldap: authentication requested and libraries aren't present.
* Added "upgrades.php" script to handle various migration issues.
* Current PmWiki [[version]] is now held in [[SiteAdmin.Status]] .
* Fix ?action=postupload to follow ?action=upload settings.
* Improvements to [[SiteAdmin.AuthList]] page (suggestions and fixes from Ian MacGregor).
* Allow leading underscores in attachment names (requested by Christophe David).

!!!Version 2.2.0-beta57 (2007-06-15)
* Fix AsSpacedUTF8() to work like AsSpaced() (reported by Petko).
* Qualify page links that contain parentheses (reported by Petko).
* Fix bug in [@(:input default $:var ... :)@] (reported by Crisses).

!!!Version 2.2.0-beta56 (2007-06-13)
* Fix AsSpaced() to not add spaces before leading digit, and treat hyphenated digits as complete numbers.
* Fix infinite recursion in self-referencing [[page text variables]] (PITS:00915).
* Fix bug introduced in beta55 not handling end [[links|anchors]] correctly (reported by Roman).

!!!Version 2.2.0-beta55 (2007-06-11)
* Fix attributes to [@(:input e_form:)@] (PITS:00387, re-reported by Crisses).
* UpdatePage() now calls StopWatch() to record posting.
* Display stopwatch output as part of redirect.
* Fix [[wiki styles]] bug when $EnableLinkPageRelative is set (reported by Petko).
* Revise TextSection() code to hopefully avoid %newwin%[[http://pcre.org/|pcre]] limits (reported by Kathryn Andersen, Knut Alboldt).
* Add wrap=inline and wrap=none options to [[page list(s#pagelistwrap)]].

!!!Version 2.2.0-beta53, 2.2.0-beta54 (2007-06-02)
* Improve error message reporting for markup rules (suggestion by Knut Alboldt).
* Clean up more E_NOTICE warnings (reported by Ian MacGregor).
* Add focus= option to [=(:=][[forms|input]]:) controls.
* Added CSS [@.faqtoc@] class, to be able to display only the questions coming from the #includefaq [[page list template(s)]].
* Changed [[PmWiki.FAQ]] to use .faqtoc class.
* Fix bug in TextSection (PITS:00935, reported by Jean-Fabrice).
* Fix bug in [[page list(s#pagelisttrail)]] caching of trails.

!!!Version 2.2.0-beta52 (2007-05-26)
* Add per-PageStore attributes (from a suggestion by Tobias Thelen).
* Add [@{$PasswdRead}@], [@{$PasswdEdit}@], etc. to display page password settings.
* Add Site.AuthList to display all password permissions on a site.
* Reorder $PageListFilters slightly.
* Add "passwd=" option to [[page list(s#pagelistpasswd)]], to return only those pages that have some sort of [[password(s)]] attribute on them.
* Add line numbers to StopWatchHTML output.
* Clean up handling of $AuthCascade.

!!!Version 2.2.0-beta51 (2007-05-23)
* Add fmt=count to [[page list(s#pagelistcount)]] (reminder from Hans).
* Ignore hidden files in [[skin(s)]] directories when searching for .tmpl (suggestion by Stephan Becker).
* Clean up queuing of pages to be updated in .pageindex .
* Reset $LinkTargets() at beginning of each UpdatePage() sequence.

!!!Version 2.2.0-beta50 (2007-05-22)
* Fix HTML cache when drafts are enabled, or other recipes using CondAuth().
* Prevent [[page lists]] with protected pages from HTML cache.

!!!Version 2.2.0-beta48, 2.2.0-beta49 (2007-05-21)
* Fix spurious value= attribute in <textarea> tag generated by [@(:input textarea ... :)@].
* Allow either [@(:input default ...:)@] or [@(:input defaults ...:)@].
* Fix problem with page text variable handling in [@(:input defaults:)@].
* Allow either [@(:template default:)@] or [@(:template defaults:)@] in [[page list templates]].
* Fix a bug handling dates with suffixes (reported by Crisses).

!!!Version 2.2.0-beta47 (2007-05-20)
* Fix bug with quote handling in [@(:include:)@] options (reported by Hans).

!!!Version 2.2.0-beta46 (2007-05-19)
* Moved $PageTextVarPatterns definition from scripts/stdmarkup.php to pmwiki.php.
* Ignore Markup() rules that have unresolved $when parameters.
* Fix issue in authuser.php when $auth array isn't set (contributed by Ben Stallings).
* The [@(:include:)@] directive now performs template argument processing on the included text.
* Optimized [@(:pagelist:)@] slightly when sorting on [[page variables]].
* Refactored [@(:input ... :)@] markups.
* Added HandleDispatch(), which allows action handlers to easily redispatch to other actions (and add messages).
* Added FmtTemplateVars(), to perform various template-substitutions.

!!!Version 2.2.0-beta45 (2007-05-02)
* Update pmwiki's date parsing to use a common routine, recognizing dates within strings and restricting range to 1900-2039.
* Add additional parameter to "date" conditional.
* Add if= option to [[page list(s#pagelistif)]] (suggested by Crisses).
* Refactor code to use TextSection() and RetrieveAuthSection() functions.
* The value= parameter to [@(:input textarea:)@] now works properly (including values loaded from $InputValues).
* The [@(:input default:)@] directive now allows loading input control defaults from another page via the [@source=@] parameter.
* Remove automatic call to FmtPageName() in $ROSPatterns.  Add $ROEPatterns (from suggestions by JB and others).
* Fix minor variable bugs in scripts/crypt.php.
* Remove E_NOTICE errors (reported by Hans).
* Fix handling of page variables when pagename is empty or not provided.
* Add $EnableLinkPageRelative configuration option.
* Clean up handling of arguments to [@{(ftime ...)}@].
* Remove mailposts.php call in stdconfig.php (reported by Christophe David).

!!!Version 2.2.0-beta44 (2007-04-16)
* Fix case conversion of U+027D and U+026B (reported by Petko).
* Add $FTimeFmt to set default formatting for [@{(ftime)}@].
* Add %s conversion to [@{(ftime)}@] for systems that don't have it by default.
* Report an error if edit [[form(s)]] cannot be read (suggested by Hans).
* Don't report ?cannot acquire lockfile when simply browsing pages.
* Add $EnableReadOnly flag to signal when PmWiki is to be run in read-only mode.

!!!Version 2.2.0-beta43 (2007-04-15)
* Update drafts code to add $EnablePublishAttr and change button labels when drafts are enabled (PITS:00755).
* Removed no-longer-needed 'compat1x.php' and 'mailposts.php' from distribution.
* Added $DraftRecentChangesFmt.
* Added "[[markup expressions]]" [@{(...)}@] into the core.
* Added charset= attribute to saved pages.
* Update pagelist.php and xlpage-utf-8.php to handle case-insensitive searches.
* Added some optimizations to phpdiff.php script to produce more useful history information.

!!!Version 2.2.0-beta42 (2007-03-27)
* Fix a bug with order=title in pagelists (reported by Anno).

!!!Version 2.2.0-beta41 (2007-03-26)
* Added $EnableWSPre option, which allows easy adjustment of the "leading space -> preformatted text" (or "whitespace") rule.
* Added a new "pre" wikistyle, to designate blocks that are to be treated as preformatted text.

!!!Version 2.2.0-beta40 (2007-03-24)
* Fix bug with order=title in pagelists when using $Titlespaced (PITS:00906, reported by Feral).
* Report state of allow_url_fopen when downloads fail in blocklist.php.

!!!Version 2.2.0-beta39 (2007-03-23)
* Allow page variable filters to appear as options in [@(:template defaults:)@] (reported by SteP).
* Updated [[Site.PageListTemplates]] to use [@(:template:)@] directives.
* Remove '#wikileft h1' and '#wikileft h5' from pmwiki default stylesheet.

!!!Version 2.2.0-beta38 (2007-03-22)
* Strip control characters from $ChangeSummary.
* Fix problem with count=m..n where m..n is outside the range of available pages (reported by SteP).
* Allow [@(:template default ...:)@] to specify a class= option.
* [[PmWiki/PageDirectives#redirect|Redirect]] pagename can now include an anchor (PITS:00558)

!!!Version 2.2.0-beta37 (2007-03-16)
* Allow an optional space after comma separators in wildcard patterns (reported by Han Baas).

!!!Version 2.2.0-beta36 (2007-03-16)
* Allow nested [[page text variables]] to work, remove extraneous ENT_NOQUOTES parameter.
* Add new [@(:template ...:)@] directives for pagelist templates.
* Modify count= option to pagelists to allow for alternate ranges.

!!!Version 2.2.0-beta35 (2007-03-05)
* Fix bug in [[conditional markup]] parsing (reported by Christophe David).

!!!Version 2.2.0-beta33, 2.2.0-beta34 (2007-03-01)
* Refactor wildcard handling into its own GlobToPCRE function.
* Allow negated wildcards for page variable filters in pagelists (PITS:00878, reported by Jiri)
* Fix wildcards so that spaces no longer separate patterns (use commas).
* Fix handling of '&amp;' prior to [@(:input:)@] and other directives (reported by Luigi).
* Adjust position of [@%define=...%@] [[wiki styles]] to occur after ampersands.
* Adjust copyright dates on many files.
* Allow spaces around text variable names in [[page text variable(s)]] markups.

!!! [[#beta32]] Version 2.2.0-beta32 (2007-02-28)
* Fix erroneous $EnableCreole item in docs/sample-config.php (reported by Sigurd).
* Added [@(:elseif:)@] and [@(:else:)@] markups (PITS:00787).
* Fix global $Skin variable handling when using SetSkin from within markup.
* Make sure directives aren't treated like [[page text variables]] (reported by Petko).
* Remove call to ResolvePageName() from authuser.php .
* Simplify [[PmWiki/AuthUser#LDAP|LDAP]] authentication for Active Directory sites.
* Cache lowercase/uppercase patterns in AsSpacedUTF8().

!!!Version 2.2.0-beta31 (2007-02-11)
* Fix bug with sorting on [[pagelist variables]] (reported by Kathryn Andersen).

!!!Version 2.2.0-beta29, 2.2.0-beta30 (2007-02-09)
* MakePageName now uses the first matching entry of $PagePathFmt as the home page of groups without a home page.
* Add AsSpacedUTF8() to handle title spacing in utf-8 (PITS:00875, contributed by Petko, Celok)
* Fix $RequestedPage when running with utf-8.
* Add <meta> content-type tag for utf-8.
* Add an experimental caching system for pagelists.
* Fix $SuffixPattern and link suffixes for utf-8 (PITS:00881, reported by ppip).

!!!Version 2.2.0-beta28 (2007-02-03)
* Update blocklist.php so that all posted fields are checked for block values (PITS:00850).

!!!Version 2.2.0-beta27 (2007-01-25)
* Fix markup processing sequence for [@(:input default:), (:input select:)@], etc. (problem noted by Marc).
* Fix default value of [@order=@] parameter to MakePageList().

!!!Version 2.2.0-beta26 (2007-01-23)
* Fix a bug where pagelist list= option had no effect when reading from trails (from an rss problem noted by Russ Fink).

!!!Version 2.2.0-beta24, 2.2.0-beta25 (2007-01-22)
* Add a scripts/creole.php module for Creole markup (http://www.wikicreole.org/).
* Move WikiWords out of the core defaults -- can be enabled via $EnableWikiWords.
* Fix handling of WikiWords following & or #, as in [=&AElig; and #FFFF00=] (reported by Moni Kellermann).
* Adjust FormatTableRow() to support Creole-style tables (using single |'s).
* Update docs/sample-config.php with new configurations and options.
* Added code to allow Abort() to refer to additional information on pmwiki.org.
* Added $EnableSkinDiag, which checks templates for required <!--HTMLHeader--> and <!--HTMLFooter--> directives.
* Removed deprecated $BasicLayoutVars support from skins.php.

!!!Version 2.2.0-beta22, 2.2.0-beta23 (2007-01-17)
* Added $EnableActions, to allow pmwiki.php to be included without generating output (from a suggestion by Wouter Groeneveld).
* Fix bug in "order=" option to [@(:pagelist:)@] (reported by Mike Bishop).
* Change DisplayStopWatch() function to StopWatchHTML().
* Allow multiple lines for markup:, wiki:, and page: template directives (reported by Marc)

!!!Version 2.2.0-beta21 (2007-01-12)
* Fix <vspace> bug in searchresults output (PITS:00846, reported by M. Czaplinski, marc, and others).
* Fix numerous E_NOTICE warnings and incorrect constants (PITS:00853, contributed by AndrewFyfe).

!!!Version 2.2.0-beta20 (2007-01-11)
* $FeedPageListOpt needs to be declared global in feeds.php.
* Add "404 Not Found" status code to ?invalid page name aborts (PITS:00854, suggested by Athan).
* Remove stale entries from $PageExistsCache when a new PageStore is added (reported by Hans).

!!!Version 2.2.0-beta19 (2006-12-29)
* Have blocklist check $_POST['text'] only when it is set (from a report by Simon).

!!!Version 2.2.0-beta18 (2006-12-28)
* Change $pagename parameter in UpdatePage() to be passed by reference (suggestion by J. Meijer).
* Fix $EnableRobotsCloakActions so that it works again with page variables.
* Add "XML Sitemaps" to $RobotPattern.
* Change $MetaRobots to return "nofollow,noindex" for non-existent pages.
* Prefer "404 Not Found" to "403 Forbidden" for [[(PmWiki:)robots]] attempting to do invalid actions on non-existent pages.
* Add rel='nofollow' to "create attachment" links.
* Added class='inputbox' to select boxes (suggested by Hans).
* Added .odt, .ods, and .odp file extensions to allowed [[uploads]] (suggested by Algis Kabaila, Robin Sheat, and others).
* Clean up some error warnings (PITS:00801, contributed by psvo).
* Set $ScriptUrl to 'https:' when accessed via SSL link (suggestions from C. Ridderstr&ouml;m, H. Fox, PITS:00410, PITS:00527, PITS:00595).
* Fix bug in link= and trail= options to [@(:pagelist:)@] (reported by C. Ridderstr&ouml;m).

!!!Version 2.2.0-beta17 (2006-12-13)
* Fix spurious hidden field in [@(:searchbox:)@] output (reported by Hans).
* Fix $CaseConversions array for \xc4\xb1 and \xc5\xbf (reported by Petko Yotov).
* Refactor [@(:input:)@] markup handling.
* Add [@(:input select ...:)@] markup (PITS:00567).
* Add [@(:input default ...:)@] markup -- may change before 2.2.0 release.
* Add ability to set defaults for radio/checkbox/select controls.

!!!Version 2.2.0-beta16 (2006-11-10)
* Fix problem with [@(:e_preview:)@] directive when viewing an edit form (reported by Dominique Faure).
* Fix out-of-memory problem in scripts/compat1x.php when dealing with large pages to be converted (contributed by Donald Gordon).
* Fix problem of Variable: lines immediately followed by newline (reported by Hans).
* Fix uninitialized variable errors in FormatTableRow() (reported by Bob Sanders).
* Fix second argument of MakeBaseName() (provided by Stirling Westrup).

!!!Version 2.2.0-beta15 (2006-10-16)
* Fix bug with displaying multi-line [@(:var:value:)@] [[page text variables]] (reported by Pico).
* Improve PageStore ls() method slightly, to restrict pagename searches to directories of a given depth (based on an issue reported by Chris Cox).
* Added $IsBlocked status variable to scripts/blocklist.php.
* Added $UnapprovedLink array to report unapproved links.
* Added $TimeISOFmt, $TimeISOZFmt, and $CurrentTimeISO variables.
* Switched scripts/feeds.php to use $TimeISOZFmt instead of $ISOTimeFmt.
* Added [@request=@] option to [@(:pagelist:)@], switched pagelist to default to not use url/form parameters.
* Fixed bug with array [@{$$options}@] in pagelist.

!!!Version 2.2.0-beta14 (2006-10-06)
* Fix problem with extra parameter to mail when $NotifyParameters is empty (reported by Tom Lederer).
* Improve configurability of $SearchPatterns (from suggestions by Stirling Westrup).
* Add ability for $WikiWordCount to disable wikiword spacing (PITS:00327).

!!!Version 2.2.0-beta13 (2006-10-04)
* Fix handling of angle brackets (and potential XSS) in pagelists combined with page text variables (noted by Pico).

!!!Version 2.2.0-beta12 (2006-10-03)
* Added the UpdatePage() function into the core.  

!!!Version 2.2.0-beta11 (2006-10-03)
* Added ability to automatically create targets.
* Added sample code to docs/sample-config.php for automatic generation of Category.* pages.
* Fixed character escapes in pagelist [@{$$option}@] variables.

!!!Version 2.2.0-beta10 (2006-10-02)
* Added [@{$$option}@] variables to get option values from [@(:pagelist:)@] (based on a recipe from Martin Fick).
* Changed [@{$PageCount}, {$GroupPageCount}, and {$GroupCount}@] to be [@{$$PageCount}, {$$GroupPageCount}, and {$$GroupCount}@].
* Added [@{$BaseName}@] page variable and $BaseNamePatterns.

!!!Version 2.2.0-beta9 (2006-10-01)
* Fix bug with $EnablePageListProtect (reported by Brent Zupp).
* Added ability to select based on page variables in [@(:pagelist:)@].

!!!Version 2.2.0-beta8 (2006-09-30)
* Update scripts/blocklist.php to check only $_POST['text'] instead of entire markup text.
* Fix bug in pagelist.php that wouldn't return correctly formatted array in certain circumstances (noted by Florian Fischer and JDem).

!!!Version 2.2.0-beta7 (2006-09-30)
* Added scripts/blocklist.php to core.
* Updated handling of $PageTextVarPatterns.
* Eliminated need for extra flush() steps in notify.php, pagelist.php.

!!!Version 2.2.0-beta6 (2006-09-27)
* Fix bug with initialization of $FeedPageListOpt in scripts/feeds.php (reported by Roman).
* Fix bug with over-eager [@(:textvar:value:)@] markup (from a bug reported by Chris Cox).

!!!Version 2.2.0-beta4, 2.2.0-beta5 (2006-09-27)
* Fix bug with name= option in pagelist (reported by Ben Wilson).
* Fix bug with array_merge under PHP 5 (reported by Kathryn Andersen).

!!!Version 2.2.0-beta3 (2006-09-26)
* Remove extra <!----> comment at end of table directives (noted by Ben Stallings).
* Fix directive form of page text variables (reported by Kathryn Andersen).
* Add first version of new modular pagelist code.

!!!Version 2.2.0-beta2 (2006-09-25)
* Add support for [@{$:var}@] page text variables, and [@(:var:...:)@] markup.
* Fix default setting of $EnableRelativePageVars in docs/sample-config.php .

!!!Version 2.2.0-beta1 (2006-09-25)
* Added [@{*$var}@] page variables (always the currently browsed page).
* Convert link and page variable handling in [=(:include:)=] to be relative to the included page.
* Added $EnableRelativePageVars and $EnableRelativePageLinks variables, as well as transition options.
* Added basepage= option to [=(:include:)=].
* Updated $GroupHeaderFmt and $GroupFooterFmt to use basepage= option.
* Adjusted $MakePageNamePatterns to automatically strip any #... or ?... from the end of a pagename input string (solution to a problem reported by J. Meijer).

!!!Version 2.1.27 (2006-12-11)
* Backport in bug fix for TableRowFormat (from 2.2.0-beta16).
* Add support for [@{*$Variable}@] syntax (from 2.2.0 page variables).

!!!Version 2.1.26 (2006-09-11)
* Fix a bug with variable referencing that caused feeds.php to get a confused PCache (reported by Helge Larsen).

!!!Version 2.1.25 (2006-09-08)
* Fixed a bug in authuser.php that would fail if $AuthUser isn't defined (reported by Hans Huijgen).
* Added <!--XMLHeader--> and <!--XMLFooter--> aliases to <!--HTMLHeader--> and <!--HTMLFooter--> directives in skin templates (suggested by John Rankin).
* Added $PageExistsCache (suggested by John Rankin).

!!!Version 2.1.24 (2006-09-06)
* Fixed a bug in authuser.php that had trouble dealing with non-array entries in $AuthUser (reported by Udo).
* Can now specify authorization groups using $AuthUser['@group'] entries.
* Can now specify an Apache .htgroup-formatted file for authorization groups via $AuthUser['htgroup'].

!!!Versions 2.1.21, 2.1.22, 2.1.23 (2006-09-05, 2006-09-06)
* Close a potential security hole with $FarmD when register_globals is set "On".
* Correct a syntax error in feeds.php (noted by Ben Wilson).
* Fix a bug that prevented PmWiki from reading page files generated by versions prior to 0.5.6 (discovered by Milan Avramovic).

!!!Version 2.1.20 (2006-09-04)
* Fixed a bug in [[PageDirectives#attachlist| [@(:attachlist:)@] ]] when passed a wikiword argument (reported by Kathryn Andersen).
* Changed $HTMLStylesFmt['markup'] to honor config.php setting (reported by Hans).

!!!Version 2.1.19 (2006-08-30)
* Corrected a bug in the pageindex code that was causing the .pageindex to not update as quickly as it should.
* Slightly changed the handling of 'width' and 'height' in wikistyles.php, so that they can be be applied as attributes to <object> and <embed> tags.
* Updated the Keep() function to recognize closing block tags as being in the 'B' block pool.
* Fixed a bug with wikistyles and form tags.

!!!Version 2.1.18 (2006-08-28)
* Closed a potential cross-site scripting vulnerability in table markups (reported by JB).
* Added [@(:input image:)@] markup (requested by JB).
* Fixed problem with ?action=print failing to set [@{$Action}@] (reported by Bart).

!!!Version 2.1.17 (2006-08-26)
* Added some improvements to IMS caching to better handle logout and authorization actions (PITS:00573, reported by floozy and Henrik Bechmann).

!!!Version 2.1.16 (2006-08-26)
* Added $SkinLibDirs variable, to select filesystem and url locations where skins may be found (resolves PITS:00708, as reported by Hagan Fox, with additional suggestions from Ben Wilson).
* Changed [@<!--HeaderText-->@] to [@<!--HTMLHeader-->@] in skin templates, and added an optional [@<!--HTMLFooter-->@] directive (PITS:00767).
* Adjusted the pmwiki and print skins to use the new directives.

!!!Version 2.1.15 (2006-08-25)
* Fixed issue dealing with order of [@@_site_*@] passwords (reported by Jean-Fabrice and others).
* Added $LocalDir variable (requested by John Rankin).
* Removed an unnecessary setting of $DefaultPage in ''scripts/pgcust.php'' (it's now handled by ResolvePageName() ).
* Added some variables and changes in wikistyles.php to better support wikipublisher (contributed by John Rankin).
* RetrieveAuthPage (PmWikiAuth) now recognizes a $level of 'ALWAYS' as indicating that access should always be allowed, regardless of current passwords or identities.
* Added filter specifier for AuthUser LDAP authentication (contributed by Balu).

!!!Version 2.1.13, 2.1.14 (2006-08-15, 2006-08-16)
* Updated scripts/authuser.php to allow ldaps://... authentications (contributed by Michael Brenner).
* Fixed problem with numeric passwords introduced in 2.1.beta20 (reported by Christophe David and Dirk Blaas).

!!!Version 2.1.12 (2006-08-07)
* Corrected typo in Site.SideBar file (reported by Judith Zacharie).
* Suppressed warning message for search on sites without a wikilib.d/ directory.
* Added capability for nested divs.
* Use $Transition['nodivnest'] to restore previous non-nesting div/table behavior.
* Including authuser.php now automatically resolves pagename.
* Added [@(:noaction:)@] directive to turn off actions.
* Fixed bug in wikistyles prior to image blocks.
* Added white-space as allowed wikistyle (suggested by C. Ridderstr&#246;m).
* Allow colons, hyphens, and dots in id= tags.

!!!Version 2.1.11 (2006-06-09)
* Fixed generation of empty paragraphs around [@%define=...%@] wikistyles (PITS:00753).

!!!Version 2.1.10 (2006-06-04)
* Added a <span> around the RecentChanges link in the pmwiki skin (PITS:00750, suggested by Hagan Fox).
* Changed the $Action variable to $ActionTitle (PITS:00749, reported by Hagan Fox).
* Changed $FPLTemplatePageFmt to be an array of pages to be searched for page templates, enabled searching of current page and Site.LocalTemplates page.
* Updated .vspace margin in sidebar for pmwiki skin (PITS:00751, by Hagan Fox).

!!!Version 2.1.9 (2006-06-02)
* Fixed a bug with [@[[~Author]]@] links (PITS:00530 reported by Klonk, PITS:00611 reported by weijang, PITS:00671 reported by Stirling Westrup, and helpful clues provided by Clayton Curtis).

!!!Version 2.1.8 (2006-06-01)
* Added ability to specify notification entries from ''local/config.php'' as well as Site.Notify (suggested by Christophe David).
* Fixed $Transition['vspace'] from 2.1.7.

!!!Version 2.1.7 (2006-05-31)
* Adjusted width of edit form for IE browsers (contributed by Roman and H. Fox).
* Suppress authentication failure error from LDAP (PITS:00739).
* Fixed problem with invalid page names resulting in redirect loop (PITS:00723, reported by jojoo).
* Added "Group." and "Group/" page name syntax, resolving PITS:00736 (from a suggestion by Pico).
* Changed handling of "vspace" paragraphs.
* Fixed some XSS vulnerabilities in uploads.php and url links (reported by Moritz Naumann, http://moritz-naumann.com).
* Added notify.php script, allowing finer control of email notifications.

!!!Version 2.1.6 (2006-05-22)
* Optimized performance of urlapprove.php.
* Added [@(:if auth xyz PageName:)@] syntax.
* Corrected XSS bug in trails.php.
* Slightly improved performance of free links.
* Restore ability to use hyphens in InterMap links (reported by Henrik Bechmann).

!!!Version 2.1.4, 2.1.5 (2006-03-29)
* Fixed problem with pagelist-based feeds (PITS:00709, reported by Jon Haupt).
* Added [@{$Action}@] page variable. (PITS:00696, reported by Sebastian Pipping).
* Added stripmagic() around variables submitted to authuser.php.
* Fixed problem with multi-term searches containing special characters (PITS:00713, reported by Leo).
* Switched [[PageDirectives#attachlist| [@(:attachlist:)@] ]] to use a natural case sort (suggested by H. Fox).

!!!Version 2.1.3 (2006-03-17)
* Re-fixed problem with PHP 5.1.1 and lines= option to [@(:include:)@] (PITS:00620).
* Fixed empty LDAP password issue (reported by Thomas Lederer).

!!!Version 2.1.2 (2006-03-16)
* Fixed <h1>/<h2> tag mismatches (PITS:00702, reported by Martin Hason).
* Fixed bug with $AllowPassword and "nopass" (reported by M. Weiner and bram brambring).
* Improved the speed of RSS and other web feeds when $EnablePageListProtect is not set.

!!!Version 2.1.1 (2006-03-13)
* Fixed a bug with multiple authorization groups as a password (PITS:00699, reported by Ari Epstein).
* Updated the authorization code to be a bit more liberal with password/group settings.
* Updated PmWiki.FAQ page to be able to grab FAQ items from other pages in the documentation.

!!Version 2.1.0 (2006-03-12)
* Many many documentation updates (special thanks to many authors).
* Allow trailing underscores in upload names (requested by Hans).
* Fixed 'ak_print' problem causing accesskey='a' for print (noted by Pico).
* Added code to make sure each anchor is generated only once per page (for XHTML validity).
* Added a $BlockPattern variable to recognize block HTML tags.
* Made an adjustment to Keep() so that it places strings with block HTML into the 'B' pool.
* Adjusted stdmarkup.php to not produce paragraphs for keep blocks in the 'B' pool.
* Corrected a variety of i18n phrases.
* Added class='escaped' to distinguish [=@@...@@=] from [=[@...@]=] (from a comment by Hans).
* Slightly changed styling of .faq divs.
* Made the edit textarea a couple of rows smaller to better fit on smaller displays (suggested by H. Fox).
----
[[(PmWiki:)ChangeLog Archive]] - changes prior to version 2.1.0.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.ConditionalMarkup</pagename>
<data><![CDATA[(:Summary:The if directive allows portions of a page to be included or excluded from rendering:)
%define=indent block margin-left=2em%
(:Audience: authors, admins (advanced) :)
!! Using the [=(:if:)=] Directive
The [@(:if:)@] directive allows portions of a page to be included or 
excluded from rendering.  The generic forms of the [@(:if:)@] directive are

-> [@(:if cond param:) body (:ifend:)@]
-> [@(:if cond param:) body (:else:) body (:ifend:)@]
-> [@(:if cond param:) body (:elseif cond param:) body (:ifend:)@] '^see [[PmWiki/ReleaseNotes#elseifelse|#]] [[PmWiki/ChangeLog#beta32|#]]^'

where "cond" names a [[#built-in-conditions | condition to be tested]], and "param" is a parameter or other argument to the condition.

!! Markup Shortcut
You can also use an abbreviated form of [@(:ifend:)@], [@(:if:)@] for brevity:
-> [@(:if cond1:) cond1 is true (:if:)@]
-> [@(:if cond1:) cond1 is true (:if cond2:) cond2 is true (:if:)@]
The latter is identical to :
-> [@(:if cond1:) cond1 is true (:ifend:)(:if cond2:) cond2 is true (:ifend:)@]

!! Built-in Conditions [[#built-in-conditions]]
The built-in conditions include:

(:table class='indent' border=0 cellpadding=0 cellspacing=0 valign=top:)
(:cellnr:)[@(:if name PAGENAME:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)current page is named "[@PAGENAME@]"
(:cellnr:)[@(:if group GROUPNAME:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)current group is named "[@GROUPNAME@]"
(:cellnr:)[@(:if auth LEVEL PAGENAME:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)viewer is authorized - meaning "what they are allowed to do" - matches a "[@LEVEL@]" where [@LEVEL@] can be: [@read@], [@edit@], [@upload@], [@attr@] or [@admin@]; [@PAGENAME@] is optional.
(:cellnr:)[@(:if authid:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)current viewer is authenticated - meaning they have proven who they are via login - to use this the wiki must include recipe [[PmWiki/AuthUser|AuthUser]] or others which set the [@$AuthId@] variable.
(:cellnr:)[@(:if enabled InvalidLogin:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)username and password not authenticated
(:cellnr:)[@(:if true:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)always include text
(:cellnr:)[@(:if false:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)always exclude text (same as a comment)
(:cellnr:)[@(:if attachments:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)current page has one or more attachments
(:cellnr:)[@(:if date DATE VALUE:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)[@DATE@] may be year-month.  year-month-day is optional.  
Evaluates to true if [@VALUE@] is within [@DATE@] ("now" or "today" is assumed for VALUE. VALUE may be omitted, as in the following examples.)  (Note that [@VALUE@] can be a recognizable date via strtotime() whereas DATE [or DATE1 and DATE2 below] have a more fixed format which explicitly must exclude spaces.  Any spaces in DATE1 or DATE2 cause unpredictable results.)
(:cellnr:)[@(:if date DATE..:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if current date is [@DATE@] or later (unlimited)
(:cellnr:)[@(:if date DATE1..DATE2:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if current date is in range [@DATE1@] to [@DATE2@] (inclusive) 
%green newwin%[-''dates are in [[http://w3.org/QA/Tips/iso-date|standard]] format yyyy-mm-dd or yyyymmdd or yyyymmddhhmm (but see comment above on format of VALUE)''-]
[[<<]][-Note the ".." cannot have leading or trailing spaces.-]
(:cellnr:)[@(:if enabled VAR:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if PHP VAR is true
(:cellnr:)[@(:if enabled AuthPw:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if user has entered any password during the current browser session.
- This does not mean the user has entered the correct password, just that they entered one.
(:cellnr:)[@(:if equal STRING1 STRING2:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if [@STRING1@] equals [@STRING2@], use quotes if the string or string variable contains spaces, eg [@"MY STRING"@]
(:cellnr:)[@(:if match REG_EXPRESSION:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if current page name matches the regular expression
(:cellnr:)[@(:if exists PAGENAME:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if the page ''pagename'' exists
(:cellnr:)[@(:if action ACTION:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if the action ?action=ACTION (edit, print, ...) is currently permitted. To test what the current action being requested is, use [@(:if equal {$Action} ACTION:)@].
(:cellnr:)[@(:if ontrail WikiTrailPage ThisPage:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)true if ThisPage is in a list used as a [[wiki trails | trail]] on WikiTrailPage
(:tableend:)

The name and group conditionals will work even for an included page, as the "name" and "group" conditionals always check the currently displayed page, as opposed to the page that the markup appears in.

!! Negated Conditions
Negated forms of conditions also work:

(:table class='indent' border=0 cellpadding=0 cellspacing=0 valign=top:)
(:cellnr:)[@(:if !attachments:)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)this page has no attachments
(:cellnr colspan=3:)&nbsp;
(:cellnr:)[@(:if ! name PAGENAME:)@]
(:cell rowspan=3:)
(:cell rowspan=3 valign=middle:)current page is NOT named "[@PAGENAME@]"
(:cellnr:)[@(:if name -PAGENAME :)@]
(:cell:)
(:cellnr:)[@(:if name !PAGENAME :)@]
(:tableend:)

!! Nesting Conditions [[#nested-conditions]]
Conditions may be nested (from 2.2.beta 66).

Nested [@(:if:)@] works the same way as nested [@(:div:)@]. To have nested conditionals you need to number the if, and the matching else/ifend:
->[@
(:if cond1:)
  cond1 is true
  (:if2 cond2:)
     cond1 and cond2 are true
  (:else2:)
     cond1 is true, cond2 is not
  (:if2end:)
(:else:)
  cond1 is false, cond2 testing was skipped
(:ifend:)
@]
[-''Spaces were added for better readability.''-]

!! Using wildcard placeholders(:if false:)%green%[-(new for pmwiki 2.1.beta21)-]:(:ifend:)
The character [@*@] can be used as a wildcard to represent any character, zero, one, or multiple times.\\
The character [@?@] can be used as a wildcard to represent any character exactly once.\\
Wildcard characters ([@*@] and [@?@]) can be used with the ''name'' and ''group'' conditional markups, thus:

(:table class='indent' border=0 cellpadding=0 cellspacing=0 valign=top:)
(:cellnr:)[@(:if name PmCal.2005* :)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)current page is in group PmCal and begins with 2005
(:cellnr:)[@(:if group PmWiki* :)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)current page is in group PmWiki or a group beginning with PmWiki
(:cellnr:)[@(:if name Profiles.*,-Profiles.Profiles :)@]
(:cell:)&nbsp;-&nbsp;
(:cell:)current page is in group [@Profiles@] but not [@Profiles.Profiles@]
(:tableend:)

!!Using [[PmWiki/page text variables]], [[PmWiki/page variables]] and [[PmWiki/markup expressions]]
Page text variables (PTVs), page variables (PVs) and markup expressions can be used in conditional markup. They will be assigned/evaluated before the condition(s). 

!! Use with [[PmWiki/page list templates]]
Conditional markup is used extensively with [[Site/page list templates]].

Use with page variables:
-> =   current item
-> <   previous item
-> >   next item

Conditionals used to structure pagelist output:
  [@(:if equal {<$Group}:)@] deprecated in favour of [@(:template first:)@] At beginning of list
  [@(:if equal {>$Group}:)@] deprecated in favour of [@(:template last:)@] At end of list
  [@(:if ! equal {=$Group} {<$Group}:)@] deprecated in favour of [@(:template first {=$Group}:)@] First item in group
  [@(:if ! equal {=$Group} {>$Group}:)@] deprecated in favour of  [@(:template last {=$Group}:)@] Last item in group

!! Combining conditions
Conditions (as previously defined) may be combined into more complex conditional expressions using one of these three equivalent forms:

->[@
(:if expr EXPRESSION :)
(:if [ EXPRESSION ] :)
(:if ( EXPRESSION ) :)@]

Conditions are combined into expressions with boolean operators and brackets. In the next table, A and B are either regular conditions or (round-)bracketed sub-expressions of regular conditions:

>>indent<<
|| border=1 cellpadding=2 cellspacing=0
||! Expression ||! Operator ||! Result ||
|| [@A and B@] || And ||TRUE if both A and B are TRUE.||
|| [@A or B@] || Or ||TRUE if either A or B is TRUE.||
|| [@A xor B@] || Xor ||TRUE if either A or B is TRUE, but not both.||
|| [@! A@] || Not ||TRUE if A is not TRUE.||
|| [@A && B@] || And ||TRUE if both A and B are TRUE.||
|| [@A || B@] || Or ||TRUE if either A or B is TRUE.||
>><<

Example
->[@
(:if [ name SomePage and group SomeGroup ]:)    equivalent to (:if name SomeGroup.SomePage:)@]

Note:
* Spaces around operators and brackets are required.
* No specific feedback is given for syntax errors or unbalanced brackets.
* Use round brackets (not square) for nested expressions.

Thus, the following is a valid way of building an expression that shows the following contents only when the user is either the administrator, or is logged in and the time is later than the given date:

->[@(:if [ auth admin || ( authid && date 2006-06-01 ) ] :)@]

Nesting with square brackets will silently fail to work as expected:

->[@(:if [ auth admin || [ authid && date 2006-06-01 ] ] :) @]&nbsp;&nbsp;&nbsp;%red%NOTE: Doesn't Work!

A common use of these complex tests are for expressions like:

->[@(:if expr auth admin || auth attr || auth edit :)@]
->[@[[Logout -> {$Name}?action=logout]]@]
->[@(:ifend:)@]

which provides a ''logout'' link only when the browser has admin, attr, or edit permissions.

%audience% admins (advanced)
!! Creating new conditions
See [[Cookbook:ConditionalMarkupSamples]].

See also [[PmWiki/PageVariables#specialreferences|special references]] for the use of [={*$Variables}=].

>>faq<< [[#faq]]]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>HansB</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Contributors</pagename>
<data><![CDATA[(:Summary:A list of contributors to PmWiki development and improvement:)
Here's a list of contributors to [[PmWiki]] development and improvement.  My apologies if I've forgotten anyone -- feel free to add your name if you've been left out, feel free to remove your name if you don't want to be associated with these people.  :-)

* GNUZoo - Several recipes, some security and bug fixes
* Scott Duff - pmwe, simple-journal.php, all-around Pm sanity checker 
* Ross Kowalski - [[uploads]] and printable page research
* John Rankin - WikiTrails, [[Links]], `EditQuickReference, notify.php, documentation, debugging
* Joachim Durchholz - hacking documentation, general pest
* Jessica Tishmack - uploads, testing
* Jean-Claude Gorichon - voting
* Janice Heinold - early PmWiki testing and suggestions, documentation
* James Davis - WikiStyles markup, testing
* Isabelle Michaud - floating images markup, [[Wiki Group]]s, [[uploads]]/attachments
* Glenn Blalock - WikiStyles suggestions, testing, documentation
* Dawn Green - WikiStyles suggestions, [[uploads]], documentation
* Christian Ridderström - [[Cookbook:EmacsPmWikiMode |pmwiki-mode for Emacs]] and some other hacks/modifications.
* Carlo Strozzi - Internationalization, PmWiki on Boa, HTML redirection
* Michael Weiner - Modifications to the ToDo, RssFeedDisplay, MyPmWiki, and CommentBox recipes
* Criss Ittermann (aka Crisses/XES) - ye old best seller Blocklist2 that topped the charts for a while and many other recipes
* Rev. Dr. Ian MacGregor - I've contributed with monetary donations, skins, bug reports and continued testing. [[http://ardchoille.nfshost.com/ | My home page]] is powered by PmWiki.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.CreatingNewPages</pagename>
<data><![CDATA[(:Summary:How to create a new page:)
(:title Creating New Pages:)
(:Audience: authors (basic) :)
To create a new page, you need to edit an existing page, and on it add a link to the page you want to create.  

To link to your new page, you must choose a name for it.  The best names describe the page's contents well, so that everyone can remember and type the name easily.

To create a link, surround the page name with '''double brackets'''. Typing [@[[my new page]]@] will create a link to [[my new page]].  There's [[a lot you can do -> Links]] with double bracket links.

You can see that the links to [[my new page]] all have question marks after them.  That's because [[my new page]] hasn't been written yet.  Clicking the link will take you to an edit form where you could write and save the new page. 

----
Another way to create a page:  in your browser's address bar (where the page URL is), replace the name of the current page with the name of the page you wish to create, and hit Enter or do whatever you would normally do to go to a new location.  PmWiki will then dutifully tell you that the page you entered doesn't exist, but you can click on the "Edit" link in order to create, edit, and save the new page.

The bad thing about this method is that there are no links to your new page, so you're the only person who knows it is there.  It will be an orphan, unread, unlinked, unloved.  That's why adding a link to an existing page or to the [[Site/SideBar]] is a better way to create a page.
----

You can also organize related pages into [[wiki group | groups]], and link between pages in different groups.  [[wiki group | Learn more]].

>>faq<< [[#faq]]
[[#beginning]]
Q: How do I create a new page?
A: Typing [=[[my new page]]=] will create a link to the new page. There's [[PmWiki.Links | a lot you can do]] with double bracket links.

Q: Why do some new pages have a title with spaces like "Creating New Pages" and others end up with a WikiWord-like title like "CreatingNewPages"?
A: The default page title is simply the name of page, which is normally stored as "CreatingNewPages."  However, you can override a page's title by using the [@(:title Creating New Pages:)@] markup.  This is especially useful when there are special characters or capitalization that you want in the title that cannot be used in the page name.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.CustomInterMap</pagename>
<data><![CDATA[(:Summary:PmWiki's default [[PmWiki/InterMap]] links, and how to can create additional InterMap links:)
(:title Custom InterMap:)
(:Audience: administrator (intermediate) :)

This page describes PmWiki's default [[InterMap]] links, and how a [[wiki administrator]] can create additional InterMap links.

An intermap entry takes the following format:

-> [@
MapPrefix:      http://example.com/partial/url/
@]

The InterMap entry can be for any of the [[(PmWiki:)link schemes]] supported by PmWiki.
[[<<]]
You can create your own InterMap links by doing one or more of the following:

* Modify the page called ''[[{$SiteGroup}.InterMap]]'' and place entries like the ones above in it.
* Create a file called ''local/localmap.txt'' and place entries like the
  ones above in it.
* In a [[WikiFarm(s)]] installation you can create a file called
  ''local/farmmap.txt'' and there place entries like the ones above in it.
  These prefixes will be common to all the wikis in the farm.
* Ensure that there is a space after the colon

Do not edit the file ''scripts/intermap.txt'' directly!  If you do, you'll
lose your changes when you [[PmWiki/upgrade(s)]] PmWiki.

!! Variables and InterMap links

It's possible to use variables within your InterMap entries.  The following
entries create [@ThisWiki:@] and [@ThisPage:@] shortcuts:

-> [@
ThisWiki:        $ScriptUrl
ThisPage:        {$PageUrl}
@]

You can also define InterMap entries where the text of the entry is
substituted into the middle of the URL.  Just include '$1' in the URL where
you want the substitution to take place.  For example:

->[@Jargon:          http://catb.org/~esr/jargon/html/$1.html@]

would cause [@Jargon:F/feature-creep@] to be converted to [@http://catb.org/~esr/jargon/html/F/feature-creep.html@].

!! Tips and tricks

It is possible to document your intermap prefixes directly in the page
[[Site.InterMap]]. The extra text will not cause a performance penalty, nor
will it break the definition of prefixes. However, be aware that anything
matching a line starting with a word and a colon (''':''') will be
considered to define a prefix.

The order in which various sources are checked for definitions of prefixes
is controlled by the variable $InterMapFiles. Currently the precedence
(highest to lowest is as follows):
* ''local/localmap.txt''
* ''$SiteGroup.InterMap''
* ''$FarmD/local/farmmap.txt''
* ''$FarmD/scripts/intermap.txt''

!! PmWiki InterMaps
(:include PmWiki/InterMap#custominclude#customincludeend:)

>>faq<< [[#faq]]

Q: Are InterMap names case sensitive?
A: Yes, thus [@eAdmin:@] is a different InterMap link than [@EAdmin:@].

Q: How can I achieve a ''localmap.txt'' mapping with the effect of [@Pics: Path:/somepathto/pics/@]?
A: Use the following:
->[@Pics:     /somepathto/pics/@]

Q: How can I define an InterMap in PHP?
A: Use the following:
->[@
      $LinkFunctions['PmWikiHome:'] = 'LinkIMap';
      $IMap['PmWikiHome:'] = 'http://pmwiki.org/wiki/$1';
@]

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.CustomMarkup</pagename>
<data><![CDATA[(:Summary: Using the Markup() function for custom wiki syntax:)
(:Audience: administrators (intermediate) :)
!! Introduction

PmWiki's markup translation engine is handled by a set of rules; each rule searches for a specific pattern in the markup text and replaces it with some replacement text.  Internally, this is accomplished by using PHP's "[[(http://www.php.net/)preg_replace]]" function.

Rules are added to the translation engine via PmWiki's Markup() function, which looks like

->[@Markup($name, $when, $pattern, $replace);@]

where [@$name@] is a unique name (a string) given to the rule, [@$when@] says when the rule should be applied relative to other rules, [@$pattern@] is the pattern to be searched for in the markup text, and [@$replace@] is what the pattern should be replaced with.

For example, here's the code that creates the rule for [@''emphasized text''@] (in ''scripts/stdmarkup.php''):

->[@Markup("em", "inline", "/''(.*?)''/", "<em>$1</em>");@]

Basically this statement says to create a rule called "em" to be performed with the other "inline" markups, and the rule replaces any text inside two pairs of single quotes with the same text ($1) surrounded by [@<em>@] and [@</em>@].

The first two parameters to Markup() are used to specify the sequence in which rules should be applied.  The first parameter provides a name for a rule -- "[@em@]" in the example above.  We could've chosen other names such as "[@''@]", or even "[@twosinglequotes@]".  In general PmWiki uses the markup itself to name the rule (i.e., PmWiki uses "[@''@]" instead of "[@em@]"), but to keep this example easier to read later on we'll use a mnemonic name for now.

The second parameter says that this rule is to be done along with the other "inline" markups.  PmWiki divides the translation process into a number of phases:

[@
_begin      start of translation
fulltext    translations to be performed on the full text            
split       conversion of the full markup text into lines to be processed
directives  directive processing
inline      inline markups
links       conversion of [[links]], url-links, and WikiWords     
block       block markups
style       style handling       
_end        end of translation
@]

This argument is normally specified as a left-angle bracket ("before") or a right-angle bracket ("after") followed by the name of another rule. 

Thus, specifying "inline" for the second parameter says that this rule should be applied when the other "inline" rules are being performed.  If we want a rule to be performed with the directives -- i.e., before inline rules are processed, we would specify "directives" or "<inline" for the second parameter.

->'-  A significant rule in terms of ordering is "{$var}" which substitutes variables -- if you say "<{$var}" then your markup will be processed before variables are substituted whereas if you say ">{$var}" then your markup will be processed after variables are substituted. -'

The third parameter is a Perl-compatible regular expression. Basically, it is a slash, a [[regular expression -> http://www.php.net/manual/en/reference.pcre.pattern.syntax.php]], another slash, and a set of optional [[modifiers -> http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php]].

The example uses the pattern string [@"/''(.*?)''/"@], which uses [@''(.*?)''@] as the regular expression and no options. (The regular expression says "find two single quotes in succession, then as few arbitrary characters as are needed to make the match find something, then two additional single quotes in succession"; the parentheses "capture" a part of the wikitext for later use.)

The fourth parameter is the replacement text that should be inserted instead of the marked-up wikitext. You can use [@$1@], [@$2@], etc. to insert the text from the first, second etc. parenthesised part of the regular expression.

In the example, we have [@"<em>$1</em>"@], which is an [@<em>@], the text matched by the first parentheses (i.e. by the [@.*?@] section of the pattern), and [@</em>@].

Here's a rule for [@@@monospaced@@@] text:

->[@Markup("@@", "inline", "/@@(.*?)@@/", "<code>$1</code>");@]

and for a [@[:comment ...:]@] directive that is simply removed from the output:

->[@Markup("comment", "directives", "/\\[:comment .*?:\\]/", '');@]

Okay, now how about the rule for [@'''strong emphasis'''@]?  We have to be a bit careful here, because although this translation should be performed along with other inline markup, we also have to make sure that the rule for [@'''@] is handled ''before'' the rule for [@''@], because [@'''@] also contains [@''@]. The second parameter to Markup() can be used to specify the new rule's relationship to any other rule:

->[@Markup("strong", "<em", "/'''(.*?)'''/", "<strong>$1</strong>");@]

This creates a rule called "strong", and the second parameter "<em" says to be sure that this rule is processed before the "em" rule we defined above.  If we wanted to do something after the "em" rule, we would use ">em" instead.  Thus, it's possible to add rules at any point in PmWiki's markup translation process in an extensible manner.  (In fact, the "inline", "block", "directives", etc., phases above are just placeholder rules used to provide an overall sequence for other rules.  Thus one can use "<inline" to specify rules that should be handled before any other inline rules.)             

If you want to disable available markup just call e.g.:

->[@DisableMarkup("strong")@]

PmWiki's default markup rules are defined in the ''scripts/stdmarkup.php'' file.  To see the entire translation table as the program is running, the scripts/diag.php module adds "[@?action=ruleset@]", which displays the set of defined markup rules in the sequence in which they will be processed.  You can see it at [[CustomMarkup?action=ruleset | CustomMarkup?action=ruleset]]. You must first enable the action by setting $EnableDiag = 1 in your configuration file.

!! Other common examples

!!! Define a custom markup to produce a specific HTML or Javascript sequence

Suppose an admin wants to have a simple "[@(:example:)@]" markup that will always produce a fixed HTML string in the output, such as for a webring, Google AdSense display, or Javascript.  The Markup() call to do this would be:

->[@
Markup('example', 'directives',
  '/\\(:example:\\)/',
  Keep("<div class='example'><p>Here is a 
    <a target='_blank' href='http://www.example.com'>link</a> to
    <em>example.com</em></p></div>") );
@]

* The first argument is a unique name for the markup ("example").
* The second argument says to perform this markup along with other directives.
* The third argument is the pattern to look for "(:example:)".
* The fourth argument is the HTML that "(:example:)" is to be replaced with.  We use the Keep() function here to prevent the output from being further processed by PmWiki's markup rule -- in the above example, we don't want the http://www.example.com url to be again converted to a link.

[[#random]]
!!! Define a markup to call a custom function that returns content

An 'e' option on the [@$pattern@] parameter will cause the [@$replace@] parameter to be treated as a PHP expression to be evaluated instead of replacement text.  Thus, a markup to produce a random number between 1 and 100 might look like:

->[@
Markup('random', 'directives',
  '/\\(:random:\\)/e',
  "rand(1, 100)");
@]

This calls the PHP built-in rand() function and substitutes the directive with the result.  Any function can be called, including functions defined in a [[local customization(s)]] file.

Arguments can also be passed by using regular expression capturing parentheses, thus

->[@
Markup('randomargs', 'directives',
  '/\\(:random (\\d+) (\\d+):\\)/e',
  "rand('$1', '$2')");
@]

will cause the markup [@(:random 50 100:)@] to generate a random number between 50 and 100.

->%note% Note:  Be very careful with the /e modifier in regular expressions; malicious authors may be able to pass strings that cause arbitrary and undesirable PHP functions to be executed.

For a PmWiki function to help with parsing arbitrary sequences of arguments and key=value pairs, see Cookbook:ParseArgs.

>>faq<< [[#faq]]
Q: How can I embed JavaScript into a page's output?
A: There are several ways to do this.  The [[Cookbook:JavaScript]] recipe describes a simple means for embedding static JavaScript into web pages using [[custom markup]].  For editing JavaScript directly in wiki pages (which can pose various security risks), see the [[(Cookbook:)JavaScript-Editable]] recipe.  For JavaScript that is to appear in headers or footers of pages, the [[skin(s)]] template can be modified directly, or <script> statements can be inserted using the $HTMLHeaderFmt array.

Q: How would I create a markup (''[=(:nodiscussion:)=]'') that will set a page variable (''[={$HideDiscussion}=]'') which can be used by ''[=(:if enabled HideDiscussion:)=]'' in [=.PageActions=]?
A: Add the following section of code to your config.php
-> [@
SDV($HideDiscussion, 0); 	#define var name
Markup('hideDiscussion', '<{$var}',
 '/\\(:nodiscussion:\\)/e', 'setHideDiscussion(true)'); 
function setHideDiscussion($val) { 
  global $HideDiscussion; 
  $HideDiscussion = $val;
} 
@]

This will enable the @@[=(:if enabled HideDiscussion:)=]@@ markup to be used.  If you want to print the current value of [={$HideDiscussion}=] (for testing purposes) on the page, you'll also need to add the line:  \\
@@[=$FmtPV['$HideDiscussion'] = '$GLOBALS["HideDiscussion"]';=]@@

Q: PmWiki only supports tool tips for external links, can I use custom markup to add tool tips to internal links?
A: Yes, add the following custom markup to your config.php: \\
[= Markup('%title%', 'inline', '/%title%(.*?)"(.*?)"(.*?)%%/', '<span title="$2">$1$3</span>');    # Add tool tips to internal links, Example: %title%[[link"tool tip"]]%% =]

Use the markup with internal links such as: \\
[= %title%[[CookBook "cool" | Example]]%% =]

A: See also [[Cookbook:LinkTitles]].

Q: It appears that (.*?) does not match newlines in these functions, making the above example inoperable if the text to be wrappen in <em> contains new lines.
A: If you include the "s" modifier on the regular expression then the dot (.) will match newlines.  Thus your regular expression will be "/STUFF(.*?)/s".  That s at the very end is what you are looking for.  If you start getting into multi-line regexes you may be forced to look at the m option as well - let's anchors (^ and $) match not begin/end of strings but also begin/end of lines (i.e., right before/after a newline).

Q: How do I get started writing recipes and creating my own custom markup?
A: [[PmWiki:CustomMarkupAlt|(alternate) Introduction to custom markup for Beginners]]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.CustomWikiStyles</pagename>
<data><![CDATA[(:Summary: Predefined PmWiki styles & adding custom wiki styles:)
(:Audience: administrators (intermediate) :)
This page describes the predefined [[Wiki Styles]] and how a [[Wiki Administrator]] can define additional [[Wiki Styles]] as a local customization for all pages (in local/config.php) or specific groups (in local/$Group.php).

All predefined [[Wiki Styles]] are setup in the global array $WikiStyle.
To define your own [[Wiki Styles]], add the setting of the correspondent `WikiStyle within the array.

[[#predef]]
!! Predefined Wiki Styles

The following array-values are set by [@scripts/wikistyles.php@] using the [[Cookbook:Functions#SDV |SDV()-function]] (so you can overwrite them by setting them prior in config.php or farmconfig.php):

||width=70% border=1 cellpadding=3 cellspacing=0
||'''markup:''' ||'''definition:''' ||
||[[<<]]'''text colors:''' [[<<]] (equiv. to [@%define=xxxx color=xxxx%@] ||||
|| [@%black%@]  ||[@$WikiStyle['black']['color'] = 'black';@] ||
|| [@%white%@]  ||[@$WikiStyle['white']['color'] = 'white';@] ||
|| [@%red%@]    ||[@$WikiStyle['red']['color'] = 'red';@] ||
|| [@%yellow%@] ||[@$WikiStyle['yellow']['color'] = 'yellow';@] ||
|| [@%blue%@]   ||[@$WikiStyle['blue']['color'] = 'blue';@] ||
|| [@%gray%@]   ||[@$WikiStyle['gray']['color'] = 'gray';@] ||
|| [@%silver%@] ||[@$WikiStyle['silver']['color'] = 'silver';@] ||
|| [@%maroon%@] ||[@$WikiStyle['maroon']['color'] = 'maroon';@] ||
|| [@%green%@]  ||[@$WikiStyle['green']['color'] = 'green';@] ||
|| [@%navy%@]   ||[@$WikiStyle['navy']['color'] = 'navy';@] ||
|| [@%purple%@] ||[@$WikiStyle['purple']['color'] = 'purple';@] ||
||[[<<]]'''list-styles:''' ||||
|| [@%decimal%@] ||[@$WikiStyle['decimal']['apply'] = 'list';@][[<<]][@$WikiStyle['decimal']['list-style'] = 'decimal';@] ||
|| [@%roman%@] ||[@$WikiStyle['roman']['apply'] = 'list';@][[<<]][@$WikiStyle['roman']['list-style'] = 'lower-roman';@] ||
|| [@%ROMAN%@] ||[@$WikiStyle['ROMAN']['apply'] = 'list';@][[<<]][@$WikiStyle['ROMAN']['list-style'] = 'upper-roman';@] ||
|| [@%alpha%@] ||[@$WikiStyle['alpha']['apply'] = 'list';@][[<<]][@$WikiStyle['alpha']['list-style'] = 'lower-alpha';@] ||
|| [@%ALPHA%@] ||[@$WikiStyle['ALPHA']['apply'] = 'list';@][[<<]][@$WikiStyle['ALPHA']['list-style'] = 'upper-alpha';@] ||
||[[<<]]'''special:''' ||||
||open links in a new browser-window: ||||
|| [@%newwin%@] ||[@$WikiStyle['newwin']['target'] = '_blank';@] ||
||Turns markup into a comment via display:none CSS ||||
|| [@%comment%@] ||[@$WikiStyle['comment']['display'] = 'none';@] ||

!!Author-Defined Wiki Styles

# The first index of the array defines the style name (e.g. mynewstyle, projectentry etc)
# the second index defines the attribute name (e.g. color, background-color, etc.)
# the value set defines the attribute value (e.g. red, bold, #00ffcc, etc.)

'''Sample:''' If you want to define a (site-wide) style the same as the page style
->[@%define=projectentry color:red%@]
use
->[@$WikiStyle['projectentry']['color'] = 'red';@]

The [@$WikiStyle['projectentry']['apply']@] variable may be defined if the wikistyle concerns a particular tag. It may be @@'item' (for li|dt), 'list' (for ul|ol|dl), 'div', 'pre', 'img', 'p'@@ or the combining @@'block' (for p|div|ul|ol|dl|li|dt|pre|h[1-6])@@. Example:

 [@$WikiStyle['top']['apply'] = 'item';@]
 [@$WikiStyle['top']['class'] = 'top';@]

then a markup
 [@* %top% An important list-item@]
will output
 [@<li class="top">An important list-item</li>@]

!! Printer-Friendly Styles

If your custom-styles (in local/config.php) are getting very colorful it might be useful to disable them in print-view. This can be done easily by putting them into a condition.

[@if($action!="print") {
  // your custom-styles
}@]

!!Notes

!!!To be done:

!!Questions:
'''I tried this but background didn't work, thou border and float worked?''' /Vincent 2008-04-08
[@
$WikiStyle['vMenu']['background']='#ffffcc' ;
$WikiStyle['vMenu']['float']='left' ;
$WikiStyle['vMenu']['border']='1px dotted red' ;
@]
->Try using [@$WikiStyle['vMenu']['background-color']='#ffffcc';@] -- unlike @@background@@, @@background-color@@ is defined in the $WikiStyleCSS array, which is checked for valid properties.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.DebugVariables</pagename>
<data><![CDATA[(:Summary:variables useful for debugging:)

:$EnableDiag:
>>indent<<
(:include AvailableActions#BEGENABLEDIAG#ENDENABLEDIAG:)
>><<
:$EnableIMSCaching:A variable which, when set equal to 1, recognizes the "If-Modified-Since" header coming from browsers and allows browsers to use locally cached pages.  Disabled by default to help the administrator customize its page without needing permanent reloading.

:$EnableStopWatch:This activates an internal stopwatch that shows how long it takes to render a page. (If you have a wiki that composes a HTML page from multiple pages, such as a normal layout with a sidebar, you'll get separate timings for each subpage and for the total page.)

: :The timings can be displayed by adding [@<!--function:StopWatchHTML 1-->@] in the wiki template.

: :Valid values are:
        $EnableStopWatch = 0; # No timings (the default). No HTML will be generated.
        $EnableStopWatch = 1; # Wall-clock timings only.
        $EnableStopWatch = 2; # Wall-clock and CPU usage timings. Won't work on Windows.

: :See [[(Cookbook:)Stopwatch]] for more details.

See also:
* scripts/refcount.php is useful for debugging

----
>>faq<<[[#faq]]
Q:Is it possible for someone with admin priviledges to always have access to debugging tools, without letting everyone else access them?
A:You can easily & automatically allow debugging for anyone with admin priviledges (meanwhile leaving it off for everyone else) by including this line in config.php - ''just be sure that 1) $EnableDiag is either null or set to 0, and 2) to include it near the end of config.php, AFTER declaring your passwords, and after any AuthUser or other priviledge settings'':

-->@@if (CondAuth($pagename, 'admin')) $EnableDiag = 1;  # allows admin to always call phpinfo, etc@@

>><<
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.DeletingPages</pagename>
<data><![CDATA[(:Summary: Page maintenance:)
To delete a page, edit the page, select (highlight) all text in the edit textarea and replace it with the single word

->[@delete@]

Note that it may be a good idea to add a comment to the field @@summary@@
explaining why you deleted the page. (The field @@summary@@ is usually found
just below the edit textarea).

After saving the changes the page is deleted.  As an added safety feature, the deleted page still exists on the server (with a timestamp) and can be restored to the former page by the [[wiki administrator]].

If you suspect that a page has been deleted but aren't sure, have a look at the wikigroup's [=RecentChanges=]. Erasing a page counts as editing the page, and the activity is recorded there and on [[{$SiteGroup}.AllRecentChanges]].

The default word used for page deletion ("delete") can be changed in config.php by setting the variable $DeleteKeyPattern (see [[Edit Variables]]). If there is a danger of malicious page deletion it may be a good idea to change the delete word to something more obscure. There is also a recipe for creating a separate delete action at Cookbook:DeleteAction.

>>faq<< [[#faq]]

Q: Deleting [[Wiki Group]]s & [[Categories]]: Once I create a Group or Category, how can I get rid of that group or category?
A: An admin can just remove the unwanted pages from wiki.d/ .  Normally, doing it via the wiki
doesn't resolve the problem, since it counts as an "update" which causes the [[Recent Changes]] page to be re-created, but it is possible to modify the site's configuration to allow deletion of the group's RecentChanges page -- see Cookbook:RecentChangesDeletion.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.DesignNotes</pagename>
<data><![CDATA[(:Summary:Some of the features and notes about PmWiki's design decisions:)
Here are some of the features and notes about PmWiki's design decisions.  
Many of these derive directly from the [[PmWiki Philosophy]] and lots of discussion on the [[mailing lists]].

* [[PmWiki:Flat File Advantages]] - why PmWiki uses flat files to store pages instead of an SQL database
* [[PmWiki:Hierarchical Groups]] - why PmWiki doesn't support nested groups
* [[PmWiki:Page Locking]] - how PmWiki works without locking pages (see also [[simultaneous edits]])
* [[PmWiki:Page File Format]] - the format of PmWiki's page files
* [[PmWiki:Search Improvements]] - why PmWiki has a native search engine
* [[PmWiki:File Permissions]] - some information about PmWiki's file permission settings
* [[PmWiki:Wiki Group Motivation]] - why WikiGroups
* [[PmWiki:WYSIWYG]] - why not WYSIWYG.

>>faq<< [[#faq]]

Q: Why doesn't PmWiki  use hierarchical / nested groups?
A: It essentially comes down to figuring out how to handle 
page links between nested groups; if someone can figure out 
an obvious, intuitive way for authors to
do that, then nested groups become plausible.  See [[Design Notes]]
and [[PmWiki:Hierarchical Groups]].

Q: Why don't PmWiki's scripts have a closing ?> tag?
A: All of PmWiki's scripts now omit the closing ?> tag.  The tag is not
required, and it avoids problems with unnoticed spaces or blank
lines at the end of the file.  Also, some file transfer protocols
may change the newline character(s) in the file, which can also
cause problems.  See also the [[http://php.net/manual/en/language.basic-syntax.instruction-separation.php | Instruction separation ]] page in the [[http://php.net/manual/en/index.php | PHP manual ]].

Q: Does PmWiki support WYSIWYG editing (or something like the FCKEditor)?
A: Short answer:  PmWiki provides GUI buttons in a toolbar for common markups, but otherwise does not have WYSIWYG editing.  For the reasons why, see PmWiki:WYSIWYG.

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>yo</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.DocumentationIndex</pagename>
<data><![CDATA[(:Title: Documentation Index:)(:Summary: PmWiki documentation index:)

>>rframe font-size:smaller<<
!! [[#contents]] Table of Contents
* [[#using | Beginner Topics for Creating/Editing Pages]]
* [[#intermed |Intermediate Editing Topics]]
* [[#struct | Wiki Structures: Organizing and Protecting Pages]]
* [[#admin | PmWiki Site Administration]]
** [[#install|Install]]
** [[#customise|Customise]]
** [[#troubleshoot|Troubleshoot]]
** [[#security|Security]]
* [[#development|Development]]
* [[#misc |About PmWiki]]
>><<

The pages below describe various aspects of [[#using|using]], [[#admin|administering]] and [[#trouble|troubleshooting]] a PmWiki installation, as well as aspects of the [[#misc|PmWiki community]].

As you know, documentation is ''always'' incomplete. 
Feel free to help yourself and others by contributing to it.  
Just edit the pages on %newwin%[[PmWiki:DocumentationIndex|pmwiki.org]].  
You might want to follow or contribute to the [[PmWiki:DocumentationGuidelines | documentation guidelines]].
----
[[#trailstart]]
* [[Introduction]]   %item comment%

!! [[#using]] Beginner Topics for Creating and Editing Pages

* [[Basic editing]]       - {BasicEditing$:Summary}
* [[Creating new pages]]  - {CreatingNewPages$:Summary}
* [[Links]]               - {Links$:Summary}
* [[Images]]              - {Images$:Summary}
* [[Text formatting rules]] - {TextFormattingRules$:Summary}

!! [[#intermed]] Intermediate Editing Topics
* [[Markup master index]] - {MarkupMasterIndex$:Summary}

* [[Uploads]]            - {Uploads$:Summary}
* [[Tables]]             - {Tables$:Summary}
* [[Table directives]]   - {TableDirectives$:Summary}
* [[Wiki styles]]        - {WikiStyles$:Summary}
** [[Wiki style examples]] - {WikiStyleExamples$:Summary}

* [[Access keys]]         - {AccessKeys$:Summary}
* [[Page directives]]     - {PageDirectives$:Summary}
* [[Include other pages]] - {IncludeOtherPages$:Summary}
* [[InterMap]] links      - {InterMap$:Summary}
* [[Conditional markup]]  - {ConditionalMarkup$:Summary}
* [[Page variables]]      - {PageVariables$:Summary}
* [[Page text variables]] - {PageTextVariables$:Summary}
* [[Markup expressions]]  - {MarkupExpressions$:Summary}
* [[Forms]]               - {Forms$:Summary}

* [[Simultaneous edits]] - {SimultaneousEdits$:Summary}

!! [[#struct]] Organizing and Protecting Pages
* [[Wiki structure]] - {WikiStructure$:Summary}
* [[Wiki group]]s    - {WikiGroup$:Summary}
* [[Group headers]]  - {GroupHeaders$:Summary}
* [[Wiki trails]]    - {WikiTrails$:Summary}
* [[Page history]]   - {PageHistory$:Summary}

* [[Passwords]]      - {Passwords$:Summary}
* [[Categories]]     - {Categories$:Summary}
* [[Page lists]]     - {PageLists$:Summary}
* %% [[PageDirectives#attachlist|Attach lists]] - Get a list of files uploaded and attached to a group using [=(:attachlist:)=] [-({PageDirectives$:Summary})-]
* [[Deleting pages]] - {DeletingPages$:Summary}

!! [[#admin]] PmWiki Site Administration
!!! [[#install]]Installation and maintenance
* [[Installation]]          - {Installation$:Summary}
* [[Initial setup tasks]]   - {InitialSetupTasks$:Summary}
* [[Upgrades]]              - {Upgrades$:Summary}
* [[Backup and Restore]] - {BackupAndRestore$:Summary}
* [[Uploads admin]]istration - {UploadsAdmin$:Summary}
* [[Security]]              - {PmWiki/Security$:Summary}

!!! [[#customise]] Customisation
* [[Custom inter map]]    - {CustomInterMap$:Summary}
* [[Custom markup]]       - {CustomMarkup$:Summary}
* [[Custom wiki styles]]  - {CustomWikiStyles$:Summary}
* [[Internationalizations]] - {Internationalizations$:Summary}
* [[Local customizations]]  - {LocalCustomizations$:Summary}
* [[PerGroup customizations | Per-group customizations]] - {PerGroupCustomizations$:Summary}
* [[Skins]]              - {Skins$:Summary}
* [[Skin templates]]     - {SkinTemplates$:Summary}
* [[Site Preferences]]   - {SitePreferences$:Summary}
* [[Web feeds]]          - {WebFeeds$:Summary}
* [[Wiki Farms]]         - {WikiFarms$:Summary}

!!! [[#troubleshoot]] Troubleshooting
* [[FAQ | Frequently answered questions]]
* [[(PmWiki:)AQ | Answers to some other questions]]
* [[(PmWiki:)FAQ Candidate]] - more answered questions
* [[(PmWiki:)Questions]]
* [[(PmWiki:)How to get assistance]]
* [[Troubleshooting]] - {Troubleshooting$:Summary}
* [[(PmWiki:)Available actions]] - documentation for developers

!!! [[#security]] Security
* [[AuthUser]]      - {AuthUser$:Summary}
* [[Blocklist]]     - {Blocklist$:Summary} 
* [[Notify]]        - {Notify$:Summary}
* [[Passwords admin]]istration - {PasswordsAdmin$:Summary}
* [[Ref count]]     - {RefCount$:Summary}
* [[Url approvals]] - {UrlApprovals$:Summary}

!! [[#development]] Development
* [[Variables]]        - {Variables$:Summary}
* [[Functions]]        - {Functions$:Summary}
* [[Page file format]] - {PageFileFormat$:Summary}

!! [[#misc]] About PmWiki
* [[Audiences]]      - {Audiences$:Summary}
* [[Contributors]]   - {Contributors$:Summary}
* [[Mailing lists]]  - {MailingLists$:Summary}
* [[PmWiki philosophy]] - {PmWikiPhilosophy$:Summary}
* [[Design notes]]   - {DesignNotes$:Summary}
* [[Release notes]]  - {PmWiki/ReleaseNotes$:Summary}
* [[Change log]]     - {PmWiki/ChangeLog$:Summary}

* [[(PmWiki:)References]] - References to PmWiki media coverage
* [[Glossary]]            - {PmWiki/Glossary$:Summary}

* [[Introduction]]   %item comment% loop trail
[[#trailend]]

>>comment<<
Note: The following pages are listed here so that they can include a #faq section and have the questions appear on the FAQ page. 

The problem is that these pages become part of the trail 

* [[Access Keys]]
* [[Basic Variables]]
* [[Edit Variables]]
* [[File Permissions]]
* [[Fmt Page Name]]
* [[I18n Variables]]
* [[Layout Variables]]
* [[Link Variables]]
* [[Other Variables]]
* [[Pagelist Variables]]
* [[PageList Templates]]
* [[Path Variables]]
* [[Requirements]]
* [[Skin Templates]]
* [[Special Characters]]
* [[Upload Variables]]
* [[Wiki Administrator]]
* [[Wiki Page]]
* [[Wiki Wiki Web]]
* [[Wiki Word]]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Drafts</pagename>
<data><![CDATA[PmWiki has the capability to stage ''draft'' versions of a page prior to them becoming "official".  Multiple interim edits to a page can be temporarily saved in a "-Draft" copy of a page until the draft is ready to be published to the original.

When the site administrator sets $EnableDrafts in a local customization file, the "Save" button on the edit page is split into separate "Publish" and "Save draft" buttons.  

The "Save draft" button causes any edits to be saved to a "-Draft" copy of the original page, leaving the original page intact.  Subsequent requests to edit the page (either the original or -Draft) bring up the draft copy for further editing.

The "Publish" button saves back to the original non-Draft copy of the page, removing any -Draft page that may have been created.

By default, saving drafts and publishing are available to anyone with 'edit' permissions (see [[Passwords]]).  However, the site administrator can also set the $EnablePublishAttr configuration variable, which provides a separate 'publish' permission that is required to publish to the original page.

>>faq<< [[#faq]]

Q:  How do I moderate all postings?

A:  Start by [[Drafts | enabling drafts]] to change the "Save" button into separate "Publish" and "Save draft" buttons.  Then set $EnablePublishAttr.  This adds a "publish" authorization level to distinguish editing of page drafts from publishing.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Pm</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.EditVariables</pagename>
<data><![CDATA[(:Summary:variables used when editing pages:)
To set many of the variables below specify them in @@config.php@@.

:$EnableGUIButtons:When set to '1', turns on the graphical buttons in the "Edit Page" form.
->        # turn on graphical edit buttons
->        $EnableGUIButtons = 1;

:$EnablePostAuthorRequired:When set to '1', posting of pages requires the author to provide an author name.  Otherwise, authors can post without a name.
->        # require authors to provide a name
->        $EnablePostAuthorRequired = 1; 

:$EnableDrafts:When set to '1', enables the "Save draft" button and built-in handling of "draft" versions of pages, where: 
## initial "Save draft" of an existing page ("PageName") saves changes to a new name ("PageName-Draft")
## subsequent attempts to edit PageName causes PageName-Draft to be edited
## subsequent selections of "Save draft" cause PageName-Draft to be saved
## pressing "Publish" causes PageName-Draft to be posted to PageName, and deleted.
->        # turn on draft edits
->        $EnableDrafts = 1;

->A related variable, $EnablePublishAttr, adds a new "publish" authorization level to distinguish editing of drafts from publishing them.

:$DraftSuffix:The suffix to use for draft versions of pages (default "-Draft").

:$DiffKeepDays:The $DiffKeepDays variable sets the minimum length of time that a page's revision history is kept. By default it is set to 3650 days, or a little less than ten years. You can change this value in a customization file to be something smaller, e.g.:
->        $DiffKeepDays = 30; # keep revisions at least 30 days
: :Note that a specific page revision isn't removed from the page until the first edit after the time specified by $DiffKeepDays has elapsed. Thus, it's still possible for some pages to have revisions older than $DiffKeepDays -- such revisions will be removed the next time those pages are edited.

:$DeleteKeyPattern:The pattern used to determine if a page should be deleted.  The default is to remove pages that contain only the single word "delete" (and optional spaces).
->        # change delete word to "remove"
->        $DeleteKeyPattern = "^\\s*remove\\s*$";
->        # delete any page with no visible text, i.e., empty
->        $DeleteKeyPattern = "^\\s*$";

:$EditTemplatesFmt:Name of the page (or an array of names) to be used as the default text for any newly created pages.
->     [@# Use 'Main.NewPageTemplate' as default text of all new pages
$EditTemplatesFmt = 'Main.NewPageTemplate';
# Use 'Template' in the current group for new pages
$EditTemplatesFmt = '$Group.Template';
# Use 'Template' in the current group if it exists, otherwise
# use 'Main.NewPageTemplate'
$EditTemplatesFmt = array('$Group.Template', 'Main.NewPageTemplate');@]
-> See [[Cookbook:EditTemplates]] for more information.

:$AutoCreate:Used in conjunction with the AutoCreateTargets edit function, this array records any sets of pages which should be created automatically if they don't exist.  The syntax is 
->        [@$AutoCreate[REGEXP] = PAGE_PARAMETERS;@]
->        where @@REGEXP@@ is a regular expression which will identify the pages to be autocreated, and @@PAGE_PARAMETERS@@ is an array of attributes for the page to be created.  For example, 
->        [@$AutoCreate['/^Category\\./'] = array('ctime' => $Now);@]
->        will create a blank page with a current creation time for any missing Category page.

:$DefaultPageTextFmt:The text that should be displayed when browsing non-existent pages. As default PmWiki uses the contents of Site.PageNotFound 
->        [@$DefaultPageTextFmt = '(:include $[{$SiteGroup}.PageNotFound]:)';@] 

:$EditFunctions: This array contains the sequence of functions that are called when a page is edited.  It can be customized to provide additional functions to be called as part of the editing process.  The standard setting is:
->        [@$EditFunctions = array('EditTemplate', 'RestorePage', 'ReplaceOnSave',
  'SaveAttributes', 'PostPage', 'PostRecentChanges', 'AutoCreateTargets', 'PreviewPage'); @]

:$ROEPatterns: With this array you can add a pattern as ''key'' and set a text ''value'' which replace it on every edit request, using preg_replace function. Specifically it is replaced when the page is loaded into the editform, whenever a preview is done, and when the page is saved (from PmWiki 2.2.0beta45). See Cookbook:ROEPatterns for examples.

:$ROSPatterns: With this array you can add patterns as ''key'' and set a text ''value'' which will replace it when the edited page is posted (as signaled by $EnablePost).  It is not replaced when the page is loaded into the editform nor when a preview is done, but it is replaced only when the page is saved.  See Cookbook:ROSPatterns for examples.

:$IsPagePosted: Set to a true value if the page is actually saved (e.g., this is used to tell the RecentChanges handlers if they need to update).
       
:$PageEditFmt: By default, this is the HTML to be displayed for an edit form.

:$PageEditForm: Specifies the edit form for ?action=edit.  Defaults to '$SiteGroup.EditForm'.

:$HandleEditFmt: Like $HandleBrowseFmt, this specifies the entire output format for ?action=edit for a page.

:$EditRedirectFmt: The page to which an author is sent after pressing "Save" or "Cancel" from an edit form.  Defaults to "$FullName", which sends the author to the page just edited, but can be changed to specify another page.
->      [@# redirect to Main.HomePage
$EditRedirectFmt = 'Main.HomePage';  
# redirect to HomePage of current group
$EditRedirectFmt = '{$Group}.HomePage';
@]]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.FAQ</pagename>
<data><![CDATA[(:Summary:List of frequently asked questions:)

This page will attempt to summarize some of the more commonly asked questions. The answers are on the corresponding pages (see link). If you have a question which isn't answered here, you can leave your question on the [[(PmWiki:)Questions]] page or search for documentation using the [[Site.Search | search]] facility. More documentation can be found on the [[PmWiki.DocumentationIndex | documentation index]] page.

(:comment The questions and answers are held on their respective page(s), then collated below according to the pagelist. Please make changes to those page(s) rather than making the changes here .:)

(:pagelist trail=PmWiki.DocumentationIndex "[[#faq]]" fmt=#includefaq class=faqtoc :)

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Pm</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.FilePermissions</pagename>
<data><![CDATA[(:Summary: PmWiki's settings for file and directory permissions in a typical Unix environment:)

This page briefly describes PmWiki's settings for file and directory permissions in a typical Unix environment.

!! Simple installation (out of the box)

First, let's look at PmWiki without any cookbook scripts loaded.  PmWiki needs to be able to write into the
* ''wiki.d/'' directory to be able to save pages
* ''uploads/'' directory to save uploads.  
Those are the *only* directories that need to be writable by the webserver.  
It doesn't matter to PmWiki who owns or creates those directories, as long as it has write permission to them.

Everything else should be owned by the account holder, and readable by the webserver account (but normally not writable by the webserver account).

That's it -- everything else depends on the specific PHP configuration and running environment, which is detailed below (and which is why there isn't a definitive answer that applies to every situation).  But the above two rules are absolute and answer 95% of the questions about directory permissions.      

On a Unix host the webserver typically runs with a userid and groupid that is different from the account holder.  Usually the webserver account is something like "nobody", "apache", "www", or "httpd".  Thus, in a standard installation, the account holder manually creates the wiki.d/ and uploads/ directories, and sets the permissions on the directories to be world-writable in order for PmWiki (running as the webserver account) to be able to create files there.

-> [@
$ pwd
/home/pmichaud/public_html/pmwiki
$ mkdir uploads
$ mkdir wiki.d
$ chmod 777 uploads wiki.d        
$ ls -ld . uploads wiki.d
drwxr-xr-x   12 pmichaud pmichaud     1024 Feb 10 11:51 .         
drwxrwxrwx    8 pmichaud pmichaud     1024 Jan 23 11:58 uploads             
drwxrwxrwx    2 pmichaud pmichaud    54272 Feb 10 15:29 wiki.d      
@]

!! Avoiding world-write directories

However, lots of people don't like having those world-writable (rwx) permissions on the directories.  The only practical way to eliminate the world write permissions is if we can get the webserver and account holder to be the owner and group of the directories and the files within them.  Since Unix typically doesn't allow non-superusers to change ownerships of files or directories that already exist, we have to make sure they are created with the correct ownerships in the first place.

To get the directories to be owned by the webserver account, we let PmWiki take care of creating them.  This means we temporarily grant write permission to the parent, and then execute PmWiki to allow it to create the directories.  However, we also want the newly created directories to have the same group as the account holder, so the account holder can remove or manipulate files in the directories.  Therefore, we use Unix's ''setgid'' capability (2777 or 'rws' permissions) to cause all newly created files to inherit the same group as the parent.

To avoid world-write directories, use the following instructions '''instead of''' the instructions above.  If you already have created the ''wiki.d/'' and ''uploads/'' directories, use chown and chmod to match the following results.

-> [@
$ pwd
/home/pmichaud/public_html/pmwiki
$ chmod 2777 .  
$ ls -ld .
drwxrwsrwx  10 pmichaud pmichaud 4096 May 28 09:55 .
# <-- execute pmwiki.php script from web browser -->
$ ls -ld . uploads wiki.d
drwxrwsrwx  10 pmichaud pmichaud 4096 May 28 09:55 .
drwxrwsr-x   2 nobody   pmichaud 4096 May 28 09:55 uploads
drwxrwsr-x   2 nobody   pmichaud 4096 May 28 09:55 wiki.d
$ chmod 755 .
drwxr-xr-x  10 pmichaud pmichaud 4096 May 28 09:55 .
drwxrwsr-x   2 nobody   pmichaud 4096 May 28 09:55 uploads
drwxrwsr-x   2 nobody   pmichaud 4096 May 28 09:55 wiki.d
@]

Now the two directories are owned by 'nobody', which means the webserver can write to them.  We don't have world-writable permissions on the directories, and the account holder (pmichaud) still has write permissions to the files and directories by virtue of the group ownership and permissions.  The setgid bit also ensures that any files or subdirectories created within ''uploads/'' or ''wiki.d/'' will belong to the same (pmichaud) group.

!! Safe mode
HOWEVER, if a site is running in PHP's "%newwin%[[http://php.net/features.safe-mode|safe_mode]]", then the "let PmWiki create the directories" solution doesn't work, as PHP will only create files in directories that are owned by the same user that owns the pmwiki.php script itself.  Thus, PmWiki (apache) ''cannot'' create the directories in this case, or safe_mode will complain when PmWiki attempts to write a file into those directories. The *only* way for things to work in safe_mode is to manually create the needed directories and set their permissions to 777, as outlined at the beginning of this section.

!! PHP running as script owner

There are some webservers and PHP installations that are configured to run a PHP script with the same identity as the owner of the script.  This is often called "suexec PHP" or even just "suPHP".  In this case, since the PmWiki script ends up running with the same identity as the account holder, then everything "just works" out of the box without doing anything manually.  PmWiki creates any directories and files as needed, each owned by the account holder, and permissions aren't generally an issue at all.

!! Cookbook scripts
Okay, now let's look at cookbook scripts.  
If a cookbook script has files that it wants to make available to browsers, such files should generally be placed somewhere within the 'pub/' hierarchy and referenced via '$PubDirUrl'.         

If a cookbook recipe needs to *write* files to disk, then the same rules apply to that directory as for the wiki.d/ and uploads/ directories above, with the exact ownerships and permissions depending on the webserver and PHP configuration.  In general the cookbook recipe should do the same as PmWiki, and just call PmWiki's mkdirp($dir) function.  PmWiki will then take care of creating the directory (if it can) or prompting for its creation as appropriate.

For example, if cookbook recipe 'frobot' wants to distribute a .css file, then that file should go somewhere like pub/css/frobot.css or pub/frobot/frobot.css.  The directories and files in this case should be created and owned by the account owner, since the cookbook recipe doesn't need to create or modify any of the files when it runs.           

As an alternate example, the Cookbook:MimeTeX recipe wants to be able to create cached images for the math markup, and those images need to be available to the browser.  Thus, `MimeTeX uses a pub/cache/ directory, which should be created in whatever manner was used to create the wiki.d/ and uploads/ directories (i.e., according to the webserver and PHP configuration).  Again, Cookbook:MimeTeX just solves this by calling mkdirp("pub/cache"), and letting that function create the directory or prompt the administrator for the appropriate action based upon the server settings encountered.

!! See also
* [[Cookbook:Directory and file permissions]] [- {Cookbook/DirectoryAndFilePermissions$:Summary} -]

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.FmtPageName</pagename>
<data><![CDATA[(:Summary: Documentation for the PmWiki internal function [@FmtPageName()@] :)
(:Audience: admins (advanced) :)
This page describes an internal function in PmWiki's engine called [=FmtPageName()=]. 
The contents are not intended for those with a weak heart
;-)

Also see: [[PmWiki.Functions]]

!! [[#FmtPageName]] [@FmtPageName@]($fmt, $pagename)

[[#FmtPageName-desc]]Returns [@$fmt@], with $variable and $[internationalisation] substitutions performed, under the assumption that the current page is [@pagename@]. As a rule is used to pre-process all variables which by convention have a "Fmt" suffix (like $GroupFooterFmt), but also other strings that require %newwin%[[Wikipedia:Variable#Variable_interpolation | interpolation]], notably the page template (.tmpl) file. See [[PmWiki.Variables]] for an (incomplete) list of available variables, [[PmWiki.Internationalizations]] for internationalisation.

The function [@FmtPageName()@] applies internationalization-substitutions
and $Variable-substitions to the string $fmt under the assumption that the
current page is $pagename.

The substitutions go as follows:

# Replace any sequences of the form [@$XyzFmt@] with value of any \
  corresponding global variable.
# Process the string for any [@$[...]@] phrases (internationalized phrase), \
  using the currently loaded translation tables.
# Replace any instances of [@{$ScriptUrl}@] with [@$ScriptUrl@] \
  (to defer processing to the URI processing phase)
# Replace any instances of standard [[PmWiki/PageVariables|Page Variables]] \
  (beginning with an upper case letter, followed by at least one word character) \
  with their values. \
  If there are no more $-sequences, then return the formatted string and exit the function
# Perform any pattern replacements from the array $FmtP. Typically \
  this is used to handle things like $Name and $Group etc that are \
  specific to the name of the current page. %green%''?? Appears to be used in robots.php to hide actions from robots.''
# Replace any remaining instances of Page Variables with their values.
# If $EnablePathInfo isn't set, convert [@URIs@] to use the syntax \
  $ScriptUrl?n=<Group>.<Name> instead of $ScriptUrl/<Group>/<Name>. \
  In any case, replace $ScriptUrl with its value. \
  If there are no more $-sequences, then return the formatted string and exit the function
# Replace any $-sequences with global variables (caching as needed) \
  of the same name (in reverse alphabetical order, and filtering out any unsafe globals) *
# Replace any $-sequences with values out of the array $FmtV.

Note that [@FmtPageName@]() is automatically aware of any global
variables. However, since modifying global variables may be expensive, the
array $FmtV exists as a way to avoid rebuilding the variable cache for
values that change frequently.

!! Security

According to PM, as a general rule it's unwise to be calling FmtPageName() on strings that are coming from page markup, as this exposes the ability for people to view the values of variables that perhaps they shouldn't see.  This is also why page variables (which come from markup) use PageVar() and PageTextVar() and don't go through FmtPageName().

!! Availability of Variables in FmtPageName

To be very specific, here's what Pm wrote regarding different ways of
defining a variable that can be used by FmtPageName (when it is formatting a
string):

* Set a global variable.  FmtPageName() automatically performs \
  substitution on all global variables that aren't arrays. \
  If the variable is going to change value over repeated calls \
  to FmtPageName, it's probably better to use $FmtV as in the next item.

* Set a value in the $FmtV array.  $FmtV['$MyVariable']='something'  \
  means to replace instances of '$MyVariable' with 'something'. \
  Use this for variables that change value frequently over \
  multiple calls to FmtPageName.  

* Set a pattern/replacement in the $FmtP array.  This is normally \
  done for substitutions that have to be dynamic somehow based on \
  the pagename being referenced, such as '$Title', '$Group', '$Name', \
  '$PageUrl', etc.

Also see: [[Cookbook:Functions#FmtPageName]]

Finally, here's something else Pm wrote that is related and explains
why we have this function:

-> In order to produce its output, PmWiki has to do a variety of string \
   substitutions:

## Generating the full name, group, title, or url of a page \
    (other than the currently displayed page)
## Substituting the values of global variables
## Performing internationalization substitutions
## Converting $ScriptUrl/$Group/$Name to $ScriptUrl?n=$Group.$Name \
   for sites that cannot handle PATH_INFO urls
## Other substitutions needed by specific functions
   
-> PmWiki centralizes all of that substitute-a-dynamic-value-in-a-string \
   into the FmtPageName() subroutine.  Because some things are extremely \
   dynamic, such as the url or group for an arbitrary page that is not the \
   current one, those things cannot be simple global PHP variables.  Or, if \
   they do become global variables, they're variables that cannot be \
   trusted to hold a value for very long because some other routine (that \
   may happen to be formatting a string for a different page) will come \
   along and change that global variable for whatever it happens to be doing.

->  A limited set of $-substitutions -- basically anything that \
    corresponds to a page attribute -- are not PHP variables and \
    are only available through the FmtPageName() subroutine.  \
    The complete set of these special substitutions is $Group, \
    $Name, $FullName, $PageUrl, $Title, $Titlespaced, $Namespaced, \
    $Groupspaced, $LastModifiedBy, $LastModifiedHost, and $LastModified.  \
    These items cannot just be standard PHP variables because often\
    PmWiki needs to obtain the url, name, group, title, etc. of a page \
    other than the one currently being viewed by a browser.

->  At the moment, $Title, $LastModified, $LastModifiedBy, and \
    $LastModifiedHost can only work if the page's attributes have been \
    loaded and cached using the `PCache function.   So, to get\
    at these values one must typically do:

-> [@
$page = ReadPage($pagename);
PCache($pagename, $page);
$ptitle = FmtPageName('$Title', $pagename);
$pauthor = FmtPageName('$LastModifiedBy', $pagename);
@]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Forms</pagename>
<data><![CDATA[(:Summary:How you can embed input forms into wiki pages:)
This page explains how you can embed input forms into wiki pages.

Input forms don't actually handle processing of the form data -- the feature simply allows creation of forms inside wiki pages. Forms processing can be found in the Cookbook (see below).

!! Markup
Two directives are used to begin and end forms:

    [=(:input=] form "''url''" ''method'':)
    ...
    [=(:input end:)=]

The [@(:input form:)@] directive starts a form that will post to ''url'' using the supplied ''method''.  The ''url'' must be in quotes.  If the url is omitted, then the current page is assumed.  If ''method'' is omitted then "POST" is assumed.  The [@(:input end:)@] directive ends the current form.

Note that this feature doesn't ensure that the form output is correct HTML -- it assumes the author knows a little bit of what he or she is doing. Notably, [=(:input form:) and (:input end:)=] shouldn't appear inside tables, and all form fields and controls should be inside an [=(:input form:)...(:input end:)=] block.

[[#standardinputcontrols]]
!!!Standard input controls
The standard input controls are:

    [=(:input=] text ''name'' ''value'' size=''n'':)
    [=(:input=] hidden ''name'' ''value'':)
    [=(:input=] password ''name'' ''value'':)
    [=(:input=] radio ''name'' ''value'':)
    [=(:input=] checkbox ''name'' ''value'':)
    [=(:input=] [[#select|select]] ''name'' ''value'' ''label'':)
    [=(:input=] [[Cookbook:InputDefault|default]] ''default-name'' ''default-value'':) 
    [=(:input=] submit ''name'' ''value'':)
    [=(:input=] textarea ''name'' ''value'' rows=''n'' cols=''n'':)
    [=(:input=] reset ''name'' ''label'':)
    [=(:input=] file ''name'' ''label'':)
    [=(:input=] image ''name'' ''"src"'' ''alt'':)

Where ''name'' and ''value'' are in the HTML syntax: name="addr" value="808 W Franklin".

For most controls the markup has the form:

    [=(:input=] ''type'' ''name'' ''value'' ''parameter=value'':)

where ''type'' is the type of input element (described below), ''name'' is the name of the control, ''value'' is its initial value, and parameters are used to specify additional attributes to the control.  For example, the following creates a text input control with a size of 30 characters:

(:markup:)
(:input text authorid "Jane Doe" size=30:)
(:markupend:)

For convenience, an author can also specify name and value arguments directly using [@name=@] and [@value=@] attributes (same as HTML):

(:markup:) 
(:input text name=authorid value="Jane Doe" size=30:)
(:markupend:)

For the @@textarea@@ control a value can be set from PmWiki 2.2.0beta45 onwards. 

The [@submit@] control will more often be written as:

    [=(:input=] submit value=''label'':)

Here's a more complete example, e.g., for a login prompt:

(:markup:) [=
(:input form "http://www.example.com":)
(:input hidden action login:)
||     Name:||(:input text username:)    ||
|| Password:||(:input password password:)||
|| ||(:input submit value="Log In":) ||
(:input end:)
=]

[[#select]]
!![@(:input select ... :)@]

The basic form of a select box is a sequence of options:

(:markup:) [=
(:input form:)
(:input select name=abc value=1 label=alpha :)
(:input select name=abc value=2 label=beta  :)
(:input select name=abc value=3 label=gamma :)
(:input submit:)
(:input end:)
=]

The values can be specified positionally:
 [=(:input select abc 1 alpha :)=]

We can specify the size of the selection box:
 [=(:input select abc 1 alpha size=3 :)=]

You can specify a multiple select box:
 [=(:input select abc 1 alpha size=3 multiple:)=]

To have an element selected, use @@selected=selected@@:
 [=(:input select abc 2 beta selected=selected:)=]

Note that to have two select boxes inline, not only should you give them different @@name=@@ parameters, but also place a separator, like a character, [@&nbsp;@] or even the null sequence [@[==]@] between them:
(:markup:)
(:input form:)
(:input select name=FIRST value=1:)(:input select name=FIRST value=2:)[==]
(:input select name=SECOND value=3:)(:input select name=SECOND value=4:)
(:input end:)
(:markupend:)

!! See Also
*[[Cookbook:Input Default]] {Cookbook.InputDefault$:Summary}
*[[Cookbook:Form Validation]] {Cookbook.FormValidation$:Summary}
*[[Cookbook:Form Extensions]] {Cookbook.FormExtensions$:Summary}
*[[Cookbook:Input Forms and JavaScript]] {Cookbook.InputFormsAndJavaScript$:Summary}

Compatible recipes:
* [[Cookbook:PmForm]] {Cookbook/PmForm$:Summary}
* [[Cookbook:Fox]] {Cookbook.Fox$:Summary}
* [[Cookbook:Wiki Forms]] {Cookbook/WikiForms$:Summary}
* [[Cookbook:ProcessForm]] {Cookbook/ProcessForm$:Summary}

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Functions</pagename>
<data><![CDATA[(:Summary: How some of the functions in pmwiki.php work:)
(:Audience: admins (advanced) :)

This page describes some of the internal workings of PmWiki by explaining how some of the functions in pmwiki.php work. For a more brief list/overview on functions useful to for instance cookbook writers, see Cookbook:Functions. 

To use this functions you have to make sure that all relevant internal variables have been initialized correctly. See [[Custom Markup]] and [[(PmWiki:)Custom Actions]] for more information on how these functions are typically called via [@Markup()@] or [@$HandleActions[]@].

!![[#PSS]] [@PSS($string)@]

The PSS() function removes the backslashes that are
automatically inserted in front of quotation marks by
the /e option of PHP's preg_replace function.  PSS() is
most commonly used in replacement arguments to Markup(),
when the pattern specifies /e and one or more of the 
parenthesized subpatterns could contain a quote or backslash.  
("PSS" stands for "PmWiki Strip Slashes".)
-->From PM: PmWiki expects PSS() to always occur inside of double-quoted strings and to contain single quoted strings internally.  The reason for this is that we don't want the $1 or $2 to accidentally contain characters that would then be interpreted inside of the double-quoted string when the PSS is evaluated.
--->@@Markup('foo', 'inline', '/(something)/e', 'Foo(PSS("$1"))');  # wrong@@
--->@@Markup('foo', 'inline', '/(something)/e', "Foo(PSS('$1'))");  # right@@

!!! Example
This is a fictitious example where PSS() should be used.
Let us assume that you wish to define a directive [@(:example:)@]
such that [@(:example "A horse":)@] results in the HTML
-> [@<div>"A horse"</div>@].
Here is how the markup rule can be created:
-> [@
Markup('example', 'directives',
       '/\\(:example\\s(.*?):\\)/e',
       "Keep('<div>'.PSS('$1').'</div>')");
@]
We need to use PSS() around the '$1' because the matched text
could contain quotation marks, and the /e will add backslashes
in front of them.

!![[#stripmagic]] [@stripmagic($string)@]

This function should be used when processing the contents of [@$_POST@] or [@_GET@] variables when they could contain quotes or backslashes. It verifies [@get_magic_quotes()@], if true,
strips the automatically inserted escapes from the string.

!![[#FmtPageName]] [@FmtPageName@]($fmt, $pagename)

[[#FmtPageName-desc]]Returns [@$fmt@], with $variable and [=$[internationalisation]=] substitutions performed, under the assumption that the current page is [@pagename@]. See [[PmWiki.Variables]] for an (incomplete) list of available variables, [[PmWiki.Internationalizations]] for internationalisation.  Security: not to be run on user-supplied data.

This is one of the major functions in PmWiki, see [[PmWiki.FmtPageName]] for
lots of details.

!![[#Markup]] [@Markup@]($name, $when, $pattern, $replace)

[[#Markup-desc]]Adds a new markup to the conversion table.  Described in greater detail at PmWiki.CustomMarkup.

This function is used to insert translation rules into the PmWiki's
translation engine. The arguments to [@Markup()@] are all strings, where:

:[@$name@]: The string names the rule that is inserted.  If a rule of the same name already exists, then this rule is ignored.
:[@$when@]: This string is used to control ''when'' a rule is to be applied relative to other rules.  A specification of "[@<xyz@]" says to apply this rule prior to the rule named "xyz", while "[@>xyz@]" says to apply this rule after the rule "xyz".  See [[(PmWiki:)CustomMarkup]] for more details on the order of rules.
:[@$pattern@]: This string is a [[regular expression -> http://www.php.net/preg_replace]] that is used by the translation engine to look for occurences of this rule in the markup source.
:[@$replace@]: This string will replace the matched text when a match occurs.

Also see: [[PmWiki.CustomMarkup]] and [[Cookbook:Functions#Markup]]

!![[#MarkupToHTML]] [@MarkupToHTML@]($pagename, $str)

[[#MarkupToHTML-desc]] Converts the string [@$str@] containing PmWiki markup into the corresponding HTML code, assuming the current page is [@$pagename@].

Also see: [[Cookbook:Functions#MarkupToHTML]]

!![[#mkdirp]] [@mkdirp@]($dir)

The function [@mkdirp@]($dir) creates a directory, [@$dir@], if it doesn't
already exist, including any parent directories that might be needed.  For
each directory created, it checks that the permissions on the directory are
sufficient to allow PmWiki scripts to read and write files in that
directory.  This includes checking for restrictions imposed by PHP's
safe_mode setting.  If [@mkdirp@]() is unable to successfully create a
read/write directory, [@mkdirp@]() aborts with an error message telling the
administrator the steps to take to either create $dir manually or give
PmWiki sufficient permissions to be able to do it.

!![[#MakeLink]] [@MakeLink@]($pagename, $target, $txt, $suffix, $fmt)

The function [@MakeLink@]($pagename, $target, $txt, $suffix, $fmt) returns a ???. Its arguments are as follows:
 $pagename is the source page
 $target is where the link should go
 $txt is the value to use for '$LinkText' in the output 
 $suffix is any suffix string to be added to $txt
 $fmt is a format string to use

If $txt is NULL or not specified, then it is automatically computed from $target.

If $fmt is NULL or not specified, then MakeLink uses the default
format as specified by the type of link.  For page links this
means the $LinkPageExistsFmt and $LinkPageCreateFmt variables,
for intermap-style links it comes from either the $IMapLinkFmt
array or from $UrlLinkFmt.  Inside of the formatting strings,
$LinkUrl is replaced by the resolved url for the link, $LinkText
is replaced with the appropriate text, and $LinkAlt is replaced
by any "title" (alternate text) information associated with the
link.

Also see: [[PmWiki:MakeLink]] and [[Cookbook:Functions#MakeLink]]

!![[#MakeUploadName]] [@MakeUploadName@]($pagename, $x)

@@MakeUploadName()@@ simply takes a string @@$x@@ (representing an attachment's
name) and converts it to a valid name by removing any unwanted characters.
It also requires the name to begin and end with an alphanumeric character,
and as of 2.0.beta28 it forces any file extensions to lowercase.
This function is defined in @@scripts/upload.php@@ and only used when uploads
are enabled.

!![[#SessionAuth]] [@SessionAuth@]($pagename, $auth=NULL)

@@SessionAuth()@@ manages keeping authentication via cookie-sessions. Session contains
ever password or vaidated id and associated groups from previous calls.It adds
elements passed by @@$auth@@ to session. It also writes every element
saved in session to @@$AuthPw@@(passwords) and @@$AuthList@@(ids and groups).

!![[#IsAuthorized]] [@IsAuthorized@]($chal, $source, &$from)
@@IsAuthorized@@ takes a pageattributesstring (e. g. "id:user1 $1$Ff3w34HASH...") in @@$chal@@.
@@$source@@ is simply returned and used for building the authcascade (pageattributes - groupattributes - 
@@$DefaultPassword@@). @@$from@@ will be returned if @@$chal@@ is empty, because it is not checked 
before calling @@IsAuthorized()@@, this is needed for the authcascade. @@IsAuthorized()@@ returns an array
with three values: @@$auth@@ @@1@@ - authenticated, @@0@@ - not authenticated, @@-1@@ - refused; @@$passwd@@; 
@@$source@@ from the parameter list.

!![[#CondAuth]] [@CondAuth@] ($pagename, 'auth level')
[@CondAuth@] implements the [[ConditionalMarkup]] for [@(:if auth level:)@]. For instance [@ CondAuth($pagename,'edit')@] is true if authorization level is 'edit'. Use inside local configuration files to build conditionals with a check of authorization level, similar to using [@(:if auth level:)@] on a wiki page.

Note that CondAuth() should be called after all authorization levels and passwords have been defined. For example, if you use it with [[Drafts]], you should include the draft.php script before calling CondAuth():
[@
   $EnableDrafts = 1;
   $DefaultPasswords['publish'] = crypt('secret');
   include_once("$FarmD/scripts/draft.php");
   if (! CondAuth($pagename, 'edit')) { /* whatever */ }
@]
Best is to use CondAuth() near the bottom of your config.php script.

!! [[#RetrieveAuthPage]] @@RetrieveAuthPage($pagename, $level, $authprompt=true, $since=0)@@

Use e.g. [@$page = @RetrieveAuthPage('Main.MyPage', 'read')@] to obtain a page object that contains all the information of the correspondent file in separate keys, e.g. [@$page['text']@] will contain a string with the current wiki markup of Main.MyPage. Use this generally in preference to the alternative function [@ReadPage($pagename, $since=0)@] since it respects the authorisation of the user, i.e. it checks the authorisation level before loading the page, or it can be set to do so. [@ReadPage()@] reads a page regardless of permission.

!! [[#UpdatePage]] @@UpdatePage($pagename, $old (page object), $new (page object));@@
''[[PmWiki:UpdatePage|More Technical Notes]]''

[@UpdatePage()@] allows cookbook recipes to mimic the behavior of editing wiki pages via the browser. Internally, PmWiki does several house keeping tasks which are accessible via this function (preserving history/diff information, updating page revision numbers, updating RecentChanges pages, sending email notifications, etc._
* "Page object" refers to an array pulled from [@ReadPage($pagename); @] Note that $new['text'] should contain all page data for the new version of the page. 
* If a page doesn't exist, UpdatePage() will attempt to create it.
* Ignoring $old (e.g. [@UpdatePage($pagename, '', $new);@]) will erase all historical page data---a ''tabula rasa''.
@@UpdatePage()@@ cannot be called directly from config.php because there are necessary initializations which occur later in pmwiki.php.  It is not enough to just load stdconfig.php.  If you want to use @@UpdatePage()@@ you will need to do it within a custom markup, a custom markup expression, or a custom action.]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Glossary</pagename>
<data><![CDATA[(:Summary: Terms related to PmWiki:)

This page describes various terms related to PmWiki.

:Author: Any user with privileges to write to the wiki.

:Admin: The person (or people) who controls access to the wiki, configures the wiki, and generally is the person who installed the wiki.

:Configuration file: A specially-named PHP script file where local customizations can take place for a farm, a wiki, a group, or a page.

:Default configuration: The way Pm has chosen to set all settings, or an individual setting, by default.  For example, $EnablePathInfo is disabled by default.  A wiki with no ''local/config.php'' file is using the default configuration.  Likewise, a farm that only defines $FarmPubDirUrl in ''farmconfig.php'' is using the default configuration.

[[#farm]]
:Farm: A group of wikis that share code. Content and formats may or may not be shared. For more farm-related terms, including several which have been deprecated, see [[WikiFarmTerminology]]

:Farm-wide configuration file: A WikiFarm's ''local/farmconfig.php'' file, where any settings (besides $FarmPubDirUrl) customize the default configuration for all of the wikis in a farm.

:Full page name: The ''full page name'' consists of a group and a name, e.g. [@Main.WikiSandbox@]. The variable for the full page name is [@{$FullName}@], which for this page is @@{$FullName}@@. Similarly, the variable for the group is [@{$Group}@] which here is @@{$Group}@@.

:Group: A collection of associated wiki pages; by default this appears in the page name as "Group.PageName". Attributes can be set on all pages in the group simultaneously. The variable for the group is [@{$Group}@], which here is @@{$Group}@@.

:Local configuration file: A specially-named PHP script where local customizations can take place for an individual wiki.  For an entire wiki it's named ''local/config.php''.  Individual groups and pages can also have their own local configuration files.

:Local customization: Any deviation from the default configuration.  A related phrase is "farm-wide customization".

:Page file name: The ''page file name'' is the name of the file that normally stores the data of a page in the directory [@wiki.d/@]. This file name is normally built directly from the page name.

:Page link: A ''page link'' is something that is used to generate a link to a page. For example, the markup [@[[wiki sandbox]]@], [@[[(wiki) sandbox]]@], [@WikiSandbox@], [@Main/WikiSandbox@], [@[[Main/wiki sandbox]]@], [@[[Main.WikiSandbox | click here]]@], etc all specify a link to the page '[=Main.WikiSandbox=]'.  In each case PmWiki uses the context of the link to generate a page name from the page link -- normally by capitalizing each word found in the link and stripping any characters that aren't considered valid in page names.

:Page name: The ''page name'' is a string that PmWiki uses to refer to a page - i.e. it ''names the page''. This could also be considered a ''handle'' for the page. The variable for the page name is simply called [@{$Name}@], which for this page is @@{$Name}@@.
-> Note that there is no whitespace in page names, and by default PmWiki capitalizes each word in a page's name. There is however a variable [@{$Namespaced}@] where spaces have been inserted, e.g. for the page [=WikiSandbox=] this variable would be [@Wiki Sandbox@].
-> Note that PmWiki also uses the page name to locate per-group and per-page customization files in the [@local/@] subdirectory. For example, browsing [=Main.WikiSandbox=] would cause [@local/Main.WikiSandbox.php@] and [@local/Main.php@] to be loaded if these files existed.

:Page title: A ''page title'' is the title element of a page, i.e. what is usually shown above the page and in the browser window's name. This title is normally set via the directive [@(:title:)@], but if no such directive is given the title will be automatically generated from the page name. The title of a page is accessed via either the variable [@{$Title}@] or the variable  [@{$Titlespaced}@]. The latter differs in that it uses the spaced version of the name.

:Page URI: Page names are used in `URIs to tell PmWiki which page is to be loaded or acted upon. The normal form of a page URI is usually one of these two
--> [@http://www.example.com/pmwiki/pmwiki.php?n=Main.WikiSandbox@]
--> [@http://www.example.com/pmwiki/pmwiki.php/Main.WikiSandbox@]
-> Note that various aliasing and rewriting tricks can be used to modify this, but PmWiki expects to obtain a page name from the parameter 'n' or from the [@PATH_INFO@] component following the URI of the script ([@pmwiki.php@]).
-> Note that the parameter 'n' takes precedence over [@PATH_INFO@] if both are available.

:Wikifarm:Synonymous for "[[#farm | farm]]".

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.GroupFooter</pagename>
<data><![CDATA[(:Summary:Trail and talk page links:)
[[#trailstart]] (:comment included in PmWiki localisation headers and footers :)
(:if ontrail {*$Group}.DocumentationIndex#trailstart#trailend {*$Name}:) 
(:div style="clear:right; float:right; font-size:smaller; background-color:#eee;":)
<|[[{*$Group}/Documentation index(#trailstart#trailend)]]|> %%
(:divend:)
(:ifend:)
(:if ontrail {*$Group}.Variables {*$Name}:) 
(:div style="clear:right; float:right; font-size:smaller; background-color:#ddd;":)
<|[[{*$Group}/Variables]]|> %%
(:divend:)
(:ifend:)
[[#trailend]]
[[<<]]
>>bgcolor=#ffe border-top="1px solid black" font-size=.8em<<
(:if name *-Talk:)
This is a talk page for improving [[{(substr "{*$FullName}" 0 -5)}]].
(:else:)
This page may have %commentout-pmwikiorg% a more recent version on [[(http://www.)pmwiki.org]]: [[PmWiki:{*$Name}]], and %% a talk page: [[PmWiki:{*$Name}-Talk]].
(:ifend:)
>><<
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.GroupHeader</pagename>
<data><![CDATA[(:Summary: PmWiki group header. Includes styles and trail.:)
%define=note font-style=italic color=green%\
%define=important block bgcolor=#fcc border='1px solid black' padding=5px%\
%define=audience class='frame rfloat' font-size:smaller bgcolor=#ffffcc clear:right%(:comment please leave the multiple style definitions concatenated as a single line.  Linebreaks do appear in the output when the wiki is configured with linebreaks enabled -- thanks!:)
(:include PmWiki.GroupFooter#trailstart#trailend:)
(:if ! equal "{*$:Audience} "" :)(:div style="clear:right;":)%audience%{*$:Audience}%%
(:divend:)(:ifend:)]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.GroupHeaders</pagename>
<data><![CDATA[(:Summary: Group Header and Group Footer page usage:)
(:Audience: authors (intermediate) :)
Every [[WikiGroup]] can have `GroupHeader and `GroupFooter pages that contain markup that should be included at the beginning or end of each page within the group. This feature is useful for:

* adding a disclaimer or heading to all of the pages of a group
* defining custom [[WikiStyles]] that may be used for all pages in a group
* replacing the default headers and/or footers for pages in a group (e.g., using [@(:noheader:)@] and or [@(:nofooter:)@] -- see [[PageDirectives]]).

To create a group header, just create a new page called [@YourGroup.GroupHeader@]. Group headers allow authors to create groups with custom headers and footers without having to coordinate with a [[wiki administrator]].  

The default `GroupHeader or `GroupFooter can be suppressed on an individual page (such as a group's `HomePage) by using the [@(:nogroupheader:)@] and [@(:nogroupfooter:)@] markups ''on that page''.

If a generic `GroupHeader is used in one wikigroup (say, the Site wikigroup), then the code can be easily duplicated in the `GroupHeader of any other group by using 
[@(:include Site.GroupHeader:)@].  See [[IncludeOtherPages]].

If you want a header or footer to appear when you print a page (action '''print'''), simply create a page called [@YourGroup.GroupPrintHeader@] or [@YourGroup.GroupPrintFooter@] and fill it with your markup.

>>faq<< [[#faq]]

Q: How do I set one header for all pages/groups?
A: The header for each page is controlled by the $GroupHeaderFmt variable.  Thus a site-wide groupheader can be added with

->[@
$GroupHeaderFmt = '(:include {$SiteGroup}.SiteHeader
                   basepage={*$FullName}:)(:nl:)' . $GroupHeaderFmt;
@]
(:comment above line split as it breaks fixed width skins:)

Note that single quotes must be used so that [@$Group@] (which is part of the default contents of $GroupHeaderFmt) will be substituted properly by PmWiki, and that this applies to all variables ending in $[@...Fmt@].
(:comment above note edited as it was breaking fixed width skins:)
See also the Cookbook:AllGroupHeader page.

A: Any form of markup is valid in $GroupHeaderFmt, thus one can do

->[@$GroupHeaderFmt .= "Global markup text here.";@]

Q: Would this then work for site footers?
->[@
$GroupFooterFmt = '(:include {$SiteGroup}.SiteFooter
                   basepage={*$FullName}:)(:nl:)' . $GroupFooterFmt;
@]]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>mzuther</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.I18nVariables</pagename>
<data><![CDATA[(:Summary:variables used for internationalization (i18n):)

This page describes the variables used by PmWiki for [[Internationalizations]] (i18n).

:$VarPagesFmt:An array which contains the PageNames where you can find variable definitions.  To be modified when documentation is not in english.  See ''scripts/vardoc.php''.

:$XL:An array (hash) which contains pairs of language identifiers and translation hashes. Each translation hash maps a given lookup key (or phrase) into a corresponding text string for the given language. Thus, it is essentially a multi-lingual dictionary used for phrase translation.  It is also used for handling user preference mappings. Thus, the 'e_row' value that one finds on the [[Site.Preferences]] page is loaded into $XL during preference processing.

:$XLLangs:An array that contains the names of the currently active language definitions. Only dictionaries in $XL that are named in $XLLangs are used by the [=$[...]=] markup when performing a translation.

See also:
* $TimeFmt
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Images</pagename>
<data><![CDATA[(:Summary:Placing images in pages:)
To place an image into a page, enter the address (url) of the image into the markup text.  
Any ''alternate text'' (used for tooltips and for browsers that do not display images) is placed in double quotes immediately following the image url.
A caption can follow separated by a vertical bar (|), and may include simple formatting

(:markup:)
http://pmichaud.com/img/misc/pc.jpg"Paper clips" | [- %newwin% [[ (Wikipedia:Paper_clips | Paper clips ]] are ''fun'' to work with. -]
(:markupend:)

Images can also be specified as [[upload(s)]]ed files (i.e., [@Attach:image.jpeg@]) and using [[InterMap]] links.  
By default PmWiki supports the following image types:
(:include PmWiki/Uploads#imagetypes#imagetypesend:)
%note% (See also [[PmWiki/Uploads]] and [[#notes|Notes]] below for image files that lack extensions.)

To create a [[link(s)]] to an image (like [[http://pmichaud.com/img/misc/pc.jpg]] as opposed to displaying the image itself), use double brackets to mark the link, as in [@[[http://pmichaud.com/img/misc/pc.jpg]]@] or [@[[Attach:image.jpeg]]@].

To have an image link to another location, use the image as the link text as in 
(:markup:)
[[http://pmwiki.org/ | http://pmichaud.com/img/misc/pc.jpg"PmWiki"]]|Visit '''PmWiki'''
(:markupend:)
or [@[[http://example.com|Attach:Groupname/image.jpeg]]@].

[[#captions]]
!! Captions
A caption can be added to an image using a vertical brace and the caption text.

(:markup class=horiz:)
http://pmichaud.com/img/misc/pc.jpg"Paper clips" | '''Figure 1'''
(:markupend:)

A caption can be added to an image using a vertical brace and the caption text.
Normally, images are displayed "in line" with the surrounding text. Use [@%center%@] to center an image. Use [@%right%@] to right-align an image.

(:markup:)
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. %center%http://pmichaud.com/img/misc/pc.jpg"Paper clips"%%

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. %right% http://pmichaud.com/img/misc/gem.jpg%%
(:markupend:) 

[[#floating]]
!! Floating images
To left or right-align an image with text wrapping around it, use the [@%lfloat%@] or [@%rfloat%@] [[wiki styles]]. 

(:markup:)
%lfloat text-align=center margin-top=5px margin-right=25px margin-bottom=5px margin-left=25px% http://pmichaud.com/img/misc/gem.jpg | '''Rock on!'''
'''The image is left-aligned, with margins set; the caption is centered; the text wraps on the right side of the image.'''

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. 
(:markupend:)

The [@[[<<]]@] markup breaks floating text, and the text continues at the bottom of the image.

(:markup:) 
%lfloat% http://pmichaud.com/img/misc/gem.jpg
'''The image is left-aligned, and the text wraps on the right side of the image. The text after the ''[@[[<<]]@]'' markup continues below the image.'''
[[<<]]
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
(:markupend:)

Use the [@%lframe%@] or [@%rframe%@] styles to float an image and place a frame around the image and its caption.  The frame can be formatted via wikistyles:

(:markup:) 
%rframe% http://pmichaud.com/img/misc/gem.jpg | '''Rock on!'''
'''The image is right-aligned, and the text wraps on the left side of the image.'''

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

%cframe width=100px bgcolor=lightblue border='3px solid red' padding=20px% http://pmichaud.com/img/misc/gem.jpg

Example to show failure to fully apply width setting:-
%cframe width=50px bgcolor=lightblue border='3px solid red' padding=20px% http://pmichaud.com/img/misc/gem.jpg
(:markupend:)

Use [@%block rframe%@] to set off multiple images and caption text to be stacked vertically in a right-floating frame.

(:markup:) 
%block rframe width=300px%http://pmichaud.com/img/misc/gem.jpg\\
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\\
http://pmichaud.com/img/misc/bubble.jpg\\
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.%%

Text subsequent to the defined block wraps to the left of the frame. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
(:markupend:)

!!Resizing images [[#resizing]]

To resize an image via wikistyles, use [@%width=50px%@] or [@%height=50px%@] in front of an image.    The [@%thumb%@] wikistyle is a helpful shortcut for [@%width=100px%@].

(:markup:)
%width=50px% http://pmichaud.com/img/misc/bubble.jpg \
%height=50px% http://pmichaud.com/img/misc/bubble.jpg \
%thumb% http://pmichaud.com/img/misc/bubble.jpg
(:markupend:)

Note: Resizing an image via wikistyles only affects how it is displayed in a browser; it does not reduce the transfer size of the image itself - hence resizing via wikistyles is not an acceptable method of generating a page-full of images, or 'gallery'.

If you want a resized image within a link, you have to specify the size before the link as well as close it off with  a [=%%=].

(:markup:)
%width=60%[[http://pmwiki.org/ | http://pmichaud.com/img/misc/pc.jpg"PmWiki"]]%% \
%height=60%[[http://pmwiki.org/ | http://pmichaud.com/img/misc/pc.jpg"PmWiki"]]%% \
(:markupend:)

To open the link in new window, you place [=%newwin%=] before the size specification.

(:markup:)
%newwin%[[http://pmwiki.org/ | http://pmichaud.com/img/misc/pc.jpg"PmWiki"]]%%
(:markupend:)

Resized images using [@%thumb%@] can also be floated with frames, as well as made into links.

(:markup:) 
%lframe thumb% [[http://pmichaud.com/img/misc/bubble.jpg | http://pmichaud.com/img/misc/bubble.jpg"Burst the bubble"]] | [-Bubble-]
%lframe thumb% http://pmichaud.com/img/misc/pc.jpg"Clip the ticket" | [-Paper Clips-]
%lframe thumb% [[DocumentationIndex | http://pmichaud.com/img/misc/gem.jpg"Visit the Documentation Index"]] | [[DocumentationIndex | [-Rock On-]]]
(:markupend:)

[[#links]]
!!! Images as [[PmWiki/links]]
To use an image as a link specify an image instead of text in the [[PmWiki/link(s)]] markup.
(:markup:)
[[PmWiki/Links | http://pmichaud.com/img/2003/atc-1.gif"Information about wiki links"]]
(:markupend:)

[[#notes]]
!!!Notes
* '''An image file that lacks a correct extension''' can be displayed by addition of a "false" extension to the URL. For example, if the url is [@http://example.com/script/tux@], add a fake query string on the end with the desired extension (e.g., [@http://example.com/script/tux?format=.png@]). If query strings are unsuitable, a fragment identifier should work, e.g. [@http://example.com/script/tux#file.png@].

* Relative width is possible by using percentages.
(:markup:)
%width=10pct% http://pmichaud.com/img/misc/bubble.jpg \
%height=30pct% http://pmichaud.com/img/misc/bubble.jpg 
(:markupend:)

* '''Flowing text is possible, like captions, within a frame'''
(:markup:)
>>lframe width=130px<<
%thumb width=130% [[http://pmichaud.com/img/misc/bubble.jpg | http://pmichaud.com/img/misc/bubble.jpg"Burst the bubble"]] | [--Long caption for an image like [[http://pmichaud.com/img/misc/bubble.jpg | the bubble]]. This is just to show some text flowing within the frame.--]
>><<
(:markupend:)

'''Unable to upload images?''' If you get messages telling you that the upload was not able to complete for some reason, here's something to check. If your web host has your web site
-> [=http://www.website.com=]
with username
-> ''username''
the system path (not http) to your website could be at
-> /home/users/~username/public_html
If you have your wiki installed at what you think is the system's root directory
-> /pmwiki
your system's path to the wiki uploads directory might actually be
-> /home/users/~username/public_html/pmwiki/uploads
instead of the simpler
-> /pmwiki/uploads
That's how I was able to get [[mine -> mailto:ispinn aatt gmail ddoott com]] working.

!!!See also
* [[Cookbook:Images]] - adding image galleries, automatic thumbnails, background images and more. 

!!!Credits
The images on this page were obtained from http://flickr.com and are redistributed under a Creative Commons License.

(:keywords graphics, pictures, photos:)

>>faq<< [[#faq]]

Q: Is it possible to link an image on PmWiki without using a fully qualified URL?
A: Yes. For images that are attachments, the general format is [@Attach:Groupname/image.gif@].  To link to an image that is on the same server, use [@Path:/path/to/image.gif@].

Q: Can I attach a client image file on PmWiki?
A: Yes, see [[PmWiki/Uploads]] .

Q: How can I include a page from another group that contains an attached image?
A: Include the page in the normal way, ie [@(:include GroupName.Pagename:)@]. In the page to be included (that contains the image) change [@Attach:filename.ext@] to [@Attach:{$Group}./filename.ext@]. 

Q: Why, if I put an image with rframe or rfloat and immediatly after that I open a new page section with ! the section title row is below the image instead of on the left side?
A: Because the CSS for '''headings''' such as ! contains an element '''clear:both''' which forces this behaviour. Redefine the CSS locally if you want to stop this happening, but I think the bottom border (that underlines the heading) would need further re-definition. I just use bolding for the title, and 4 dashes below [=-=]--- to separate a new section, and it saves the effort of fiddling with the core definitions.

Unlike the '''lframe''' and '''rframe''' directives, '''cframe''' does not fully honour the width setting. While the frame itself resizes to match the request, the enclosed image does not, and retains its original width. Effect is the same in IE and Fx. I've added an example beneath the standard example above.

Q: Is it possible to disallow all images?  I already disabled uploads but I also want to disallow external images from being shown on my wiki pages.

A: Yes, add to config.php [@DisableMarkup('img');
$ImgExtPattern = "$^";@]

Q: How can I make it so that when I place an image in a page, the block of text it is in is a <p> (paragraph) rather than a <div> (division)?

A: If you just want it to happen for a single image (instead of all), then
try putting [@[==]@] at the beginning of the line, as in:

->[@[==] http://www.pmwiki.org/pub/pmwiki/pmwiki-32.gif@]

Having [@[==]@] at the beginning of a line forces whatever follows to
be part of a paragraph.

Q: Is there any way to use relative paths for images?
A: See Cookbook:RelativeLinks and $EnableLinkPageRelative.

Q: Is there a way to attach a BMP and have it display rather than link?
A: PmWiki supports @@.bmp@@ images out of the box. If you insist on using an uppercase extension see Cookbook:AddImageType.

Q: Is there a way to have a table to the left or right of an image?
A: Yes, see [[(http://www.pmwiki.org/wiki/Test/)TableAndImage]].
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.IncludeOtherPages</pagename>
<data><![CDATA[(:Summary: Include contents from other PmWiki pages:)
(:Audience: authors (intermediate) :)
The [@(:include:)@] directive makes it possible to insert (or [[Wikipedia:Transclusion|"transclude"]]) the contents of other pages into the current wiki page.  All of the include directives below perform a straight text inclusion.  In particular, any page [[links]] in the included text are assumed to link to pages in the current [[(wiki) group]] if not otherwise qualified.

!! Syntax
The basic syntax is
* [=(:=]include PageName:)
-> with pagename includes the full page from the same group.
* [={Group/PageName$:=][[#includeptv|PTVar]]}
-> includes a [[PageTextVariables|named variable]] from a page, [[(Wiki)Group]] and PageName are options

The full syntax is
* [=(:=]include
  [[#includefullname|FullName]]#[[#includeanchor|fromanchor]]#[[#includeanchor|toanchor]] \
  [[#includelines|lines]]=''123'' \
  [[#includeself|self]]=''0''  \
  [[#includebasepage|basepage]]=''abc'' \
  [[#includevariable|variable]]=''value'' \
  :)
-> includes a page or pages according to the parameters supplied. Parameters are optional.
[[#firstanchor]]

!! Use with [[conditional markup]]
The [@(:include ...:)@] markup is processed after conditional markup is evaluated.\\
Therefor you can include a page or page section as part of a condition, like
->[@(:if some condition:)(:include SomePage#section:)(:if:) @] 
But [@(:include SomePage#section:)@] doesn't look to see if [@[[#section]]@] is part of a conditional, like 
->[@(:if some condition:)[[#section]]...[[#sectionend]](:ifend:)@]
[@(:include SomePage#section:)@] will ignore such a condition. 

When [[Conditional Markup|testing variables]] in included pages the context of the page (source or target) can be useful.
See [[PmWiki/PageVariables|special references]] for details.

!! Parameters
Name parameters with or without anchors, and [[#includevariable| variable]] parameters, may be repeated.

[[#includefullname]]
!!! Named pages
-< [@(:include PageName:)@]
-< [@(:include Group.PageName:)@]
-< [@(:include PageName GroupName.Pagename:)@]
-> Includes the entire text of another page into the current page.  Multiple pages may be specified, but only the first available is included.

[[#includeanchor]]
!!! Anchors
|| width=*
||[@(:include PageName#from#to:)@] ||include lines from ''`PageName'' between the [@[[#from]]@] and [@[[#to]]@] [[Links#anchors|anchors]]
||[@(:include PageName#from#:)@]   ||include all lines after [@[[#from]]@] to the end of the page
||[@(:include PageName##to:)@]     ||include all lines from the start of the page to [@[[#to]]@]
||[@(:include PageName#from:)@]    ||include everything between [@[[#from]]@] and the next anchor
||[@(:include PageName#:)@]        ||include everything from the top of the page to the first anchor
||[@(:include PageName##:)@]       ||include everything from the top of the page to the bottom of the page
-> %note% Note: do not put whitespace between "#from" "#to"

-> %note% Note: text on the same line as a closing anchor but preceding the closing anchor will '''NOT''' be included in the text.  Example Below:
--> [@[[#start]]some text on the first line@]
--> [@some text on the last line [[#end]]@]
-> %note%The above, when included via [@(:include PageName#start:)@] will have the text on the first line but not the text on the last line.

-< [@(:include Page1 Page2 #from#to:)@]
-> Include from the first available of Page1, Page2 between the [@[[#from]]@] and [@[[#to]]@]  
-> %note% Note: put whitespace between "Page2" and "#from#to". The same anchors "#from#to" should be in both pages. If proper anchors are missing in the first available of Page1, Page2 the whole contents of the page is included.
-> This does not seem to work in 2.2 betas. See Cookbook:IncludeSection for a fix.

-< [@(:include Page1#from1#to1 Page2#from2#to2:)@]
-> Include the first from the first available of Page1 (between the [@[[#from1]]@] and [@[[#to1]]@]) or Page2 (between the [@[[#from2]]@] and [@[[#to2]]@] ) 

-< %green%Note%%: Previous versions of PmWiki allowed whitespace between [@#from@] and [@#to@] anchors even though it was not designed to.  Newer versions do not allow whitespace anymore.  To re-enable this "exploited misbehavior" put this into your config.php or farmconfig.php

-> [@Markup('includeanchors', '<include', '/(\\(:include.*?#\\w+)\\s+(#\\w+)/', '$1$2');@]

[[#includelines]]
!!! Lines=
-< [@(:include PageName lines=10:)@]
-< [@(:include PageName lines=5..10:)@]
-< [@(:include PageName lines=5..:)@]
-> Include the first 10 lines, lines 5-10, or lines 5 and up from ''`PageName''. A "line" in this context refers to a line of source. ''Thus a line may be a paragraph that wraps over several lines on the screen, or a completely blank line.''

-< [@(:include Page1 Page2 Page3 lines=1..5:)@]
-> Include the first five lines from the first available of Page1, Page2, or Page3.  (To include lines from a list of pages, use a separate include for each.)

[[#includeself]]
!!! Self=
-< [@(:include PageName self=0:)@]
-> The parameter @@self@@ can be @@0@@ or @@1@@. It tells the include directive if it is allowed to include the current page. This is useful if PageName is a variable like [@{$Name}@] and you want to prevent the directive from including the current page.

[[#includeptv]]
!!! [[Page text variables]]
-< [@{Group/PageName$:Var}@]
-> Includes definition list values from an (optional) page as [[page text variables]]. These are defined using a definition list ([@:item:description@]), simple colon delimiter ([@item:description@]), or special markup ([@(:item:description:)@]).

[[#includebasepage]]
!!!  Basepage=

-< [@(:include PageName basepage=BasePageName:)@]
-> Include PageName, but treat all relative links and page variables on ''PageName`'' as relative to ''BasePageName''.
If @@basepage=@@ is provided all relative links and page variables are interpreted relative 
to basepage.
So, if one creates [@TemplateName@] as
-> [@Name: {$:Name}
Address: {$:Address}@]
then the directive
-> [@(:include TemplateName basepage=PageName:)@]
will retrieve the contents of [@TemplateName@], treating any page variables and links as being relative to [@PageName@].  
In particular, the values for [@{$:Name}@] and [@{$:Address}@] will be taken from [@PageName@], but things like [@{$Title}@] and [@{$LastModifiedBy}@] would also work here.

!!!! Basepage usage
The primary purpose of basepage is to allow the include of pages in a way that mimics the 2.1.x behavior where page variables 
and links are interpreted relative to the currently displayed page.
This is done with:
-> [@(:include SomeOtherPage basepage='' :)@]
  -or-
-> [@(:include SomeOtherPage basepage={*$FullName} :)@]

It also allows [=GroupHeader and GroupFooter=] to have their page variables and links be relative to the currently displayed page 
(instead of [=GroupHeader and GroupFooter=]):
>>pre<<
  ## PmWiki default $GroupHeaderFmt setting
  $GroupHeaderFmt = 
    [='(:include {$Group}.GroupHeader self=0 basepage={*$FullName}:)(:nl:)';=]
>><<

Otherwise, using {$Name} inside of a [=GroupHeader=] would display '[=GroupHeader=]' and not the name of the currently displayed page.

As has been discovered, the basepage= parameter is general enough that it can also be used as a templating engine, so that
we can grab a template page containing variables that are then filled in with values from another page:
->[@(:include TemplatePage basepage=DataPage :)@]

And, of course, a single TemplatePage can actually contain multiple templates delimited by anchors, so that we end up with a syntax eerily similar'^[[#footnote|#]]^' to pagelist-templates:
>>pre<<
    [@(:include TemplatePage#abc basepage=DataPage :)@]
    (:include TemplatePage#def basepage=DataPage :)
    (:include TemplatePage#xyz basepage=DataPage :)
>><<

So then [=TemplatePage=] can use a syntax like:
>>pre<<
    [@
    [[#abc]]
    ...template stuff here...
    [[#abcend]]
    @]
>><<

and it's possible to display [=TemplatePage=] as a template without it being interpreted... same as we do for [[Site.PageListTemplates]].

-< [[#footnote]] [- '^[1]^'Okay, maybe it's not so eerie, given that the pagelist template code actually uses the same function as (:include:) to grab its templates.  But it's still a useful parallel. -]

[[#includevariable]]
!!! Specifying variables as parameters
You can also specify variable values inline with the include statement, and refer to the variables in the template using the [@{$$variable1}@] format:
-> [@(:include TemplatePage variable1="value" variable2="value2":)@]

This assumes that a site has $EnableRelativePageVars enabled, which is recommended in PmWiki 2.2.0 -- but disabled by default to help people upgrading from 2.1.x.

For example, on my included page ("template") I might have this:

(:markup class=horiz:)
[[#ivars]]
Hi, {$$Name}, how are you today?
[[#ivarsend]]
(:markupend:)

Then, including that section above (that section is available via the section @@[@{$FullName}#ivars)@]@@) you get this type of behavior:

(:markup class=horiz:)
(:include {$FullName}#ivars Name=Sam:)
(:markupend:)

(:markup class=horiz:)
(:include {$FullName}#ivars Name=Sally:)
(:markupend:)

!! See Also
* [[PmWiki/Page text variables]] {PmWiki/PageTextVariables$:Summary}
* [[Cookbook:IncludeUrl]] {Cookbook.IncludeUrl$:Summary}

!! Styling Note
By default, Included pages or lines cannot be distinguished from other text on the page. To provide a visual indication that this text is special, you can apply [[PmWiki/Wiki Styles]]. For example:

(:markup:)
%define=leftborder border-left="2px solid #88f" margin-left="2px" padding="1px 0 3px 10px"%
What is PmWiki?
>>leftborder<< (:include PmWiki.PmWiki lines=1..4:) 
>><<
''Have a very nice day!''
(:markupend:)

!!! Parameter References

Any parameters supplied to an include statement (whether they are keywords or not) are accessible inside the included page as a special [@{$$...}@] variable of the same name. This feature can be used to provide extra information to use when displaying the included page.

!!! Notes
* You can also say [@(:include My/Page#myanchor lines=4:)@] which starts from, and includes, the line with the anchor [@[[#myanchor]]@] for four lines.

>>faq<< [[#faq]]

Q: [[#maxincludes]] What's the maximum number of includes that can exist in a page? 
-> My site seems to stop including after 48 includes. ($MaxIncludes)

A: By default, PmWiki places a limit of 50 include directives for any given page, to prevent runaway infinite loops and other situations that might eat up server resources. (Two of these are GroupHeader and GroupFooter.) The limit can be modified by the [[wiki administrator]] via the $MaxIncludes variable.

Q: Is there any way to include from a group of pages without specifying by exact name, e.g. between Anchor X and Y from all pages named IFClass-* ?
A: This can be achieved using [[page lists]].

Q: There appears to be a viewing issue when the included page contains the [=(:title:)=] directive.
A: As of version 2.2.0, the ''last'' title in the page overrides previous ones. In future versions, this may be configurable, but for the moment, best is to place your [=(:title :)=] directive at the bottom of the page, after any includes.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>HansB</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.InitialSetupTasks</pagename>
<data><![CDATA[(:Summary:First steps following a fresh installation:)
(:Audience: administrators (basic) :)
Once you have PmWiki running on your site (see [[Installation]]), you can customize it for your particular needs.

Most PmWiki configuration is performed in files called ''local/config.php'' and ''pub/css/local.css''. 
Some configuration is done on special pages in the [[{$SiteGroup}/]] and [[SiteAdmin/]] groups, such as the [[{$SiteGroup}.SideBar]] menu.

!! The local configuration file (''local/config.php'')
When you first install PmWiki, the ''local/config.php'' file does not exist. Copy the ''sample-config.php'' file (in the ''docs/'' directory) to ''local/config.php'' and use it as a starting point.  You could create ''local/config.php'' from scratch, but ''sample-config.php'' is already populated with many of the options you might want to adjust.

Here is a simple ''config.php'' file:

-> [@
<?php if (!defined('PmWiki')) exit();
$WikiTitle = "My New Wiki";
$PageLogoUrl = "http://example.com/mylogo.gif";

$DefaultPasswords['admin'] = crypt('onesecret');

$EnableUpload = 1;
$DefaultPasswords['upload'] = crypt('secrettwo');

putenv("TZ=EST5EDT");
$TimeFmt = '%B %d, %Y, at %I:%M %p EST';
@]

Note that ''config.php'' begins with @@<?php@@ . The PHP end tag @@?>@@ is optional, and can be left off to improve compatibility with some operating systems.  Be sure there aren't any blank lines or spaces before the @@<?php@@ or after any closing @@?>@@, or else you may get strange PHP error messages at the beginning of your wiki pages.

The ''config.php'' file above sets the value of PHP variables used by PmWiki:
* The $WikiTitle variable gives the name of your site as it will appear in a user's browser title bar.
* The $PageLogoUrl variable specifies the URL of the icon image that will appear in the upper-left corner of each wiki page.
* The @@$DefaultPasswords['admin']@@ sets an administrative password.
* Setting $EnableUpload to "1" enables Uploads ("Attached files").  @@$DefaultPasswords['upload']@@ sets an upload password.
* The TZ environment variable defines a particular time zone (see [[Cookbook:ChangeTimeFormat]]).
* The $TimeFmt variable defines the appearance of time strings and (along with TZ) localizes the wiki to a specific time zone (see [[Cookbook:ChangeTimeFormat]]).

By setting these (and other) variables in ''local/config.php'', you can change the look and feel of PmWiki from its default, sometimes substantially so.  See [[PmWiki.Variables]] for a list of variables that PmWiki uses, and see PmWiki:PmWikiUsers for examples of sites that use PmWiki in customized ways.

!!! Other common setup tasks
The following [[variables]] are often requested when preparing a new wiki
* Author required when editing a page @@$EnablePostAuthorRequired = 1;@@ 
* Set the $DefaultGroup 

These common [[(Cookbook:)Cookbook]] recipes are also often installed immediately
* [[(Cookbook:)Clean Urls]] - Remove the @@?n=Group.Page@@ arguments from the end of URLs

If you prepare an international wiki, potentially with characters in different alphabets (Cyrillic, Greek, Chinese) or many diacritical symbols (Czech + French), please look at [[PmWiki.UTF-8]] and Cookbook:UTF-8.

!! Security
Review and set up any [[security]] required.

!!!Setting an administrative password

The pages in the [[{$SiteGroup}/Site]] group (except the {$SiteGroup}.SideBar) are locked by default. In order to edit pages in this group you need to create a site-wide admin password in ''local/config.php''.  To set the site-wide admin password to "@@mysecret@@", change the line to the following:

->[@$DefaultPasswords['admin'] = crypt('mysecret');@]

You must use the [@crypt()@] function, but set the password to a value with meaning for you. See [[PasswordsAdmin]] for details about making the password more secure.

!![[#dontmodify]]Don't modify or rename ''pmwiki.php''

PmWiki has been designed so that all customizations can be made without changing the distribution files -- one of its design goals is to provide seamless upgrades.   PmWiki never writes to files in the ''local/'' or ''cookbook/'' directories, so placing your customizations here makes it easier to track the changes and [[upgrades | upgrade PmWiki]] without losing the changes.

When changing the configuration of your site, always change the ''local/config.php'' file or add files to the ''cookbook/'' or ''pub'' directories.  Do not change ''pmwiki.php'' or the files in the ''scripts/'' directory because the files are supposed to be overwritten upon upgrading.

You shouldn't rename ''pmwiki.php'' either.  If you rename the file it will not be overwritten during an upgrade of the software and there will be a version mismatch.  Many administrators add an ''index.php'' "wrapper script" in the pmwiki directory that contains the following single line:

->[@<?php include('pmwiki.php');@]

Just  make an text-file. Paste <?php include('pmwiki.php'); into it.
Save the file as index.php
Send it via FTP to the same directory as pmwiki.php is located. 

!! Other organisation
!!! Upload directories
By default Pmwiki uses an upload directory for each group
(see [[Uploads admin(#uploaddirectoryconfiguration)]]istration.
Deciding on accepting the default, or choosing an alternative (eg one directory for the entire wiki, or one directory per page) is best done when setting up your wiki.

!!! Page store directories
By default Pmwiki uses a single page store directory (wiki.d).
Deciding on accepting the default (recommended), or choosing the alternative (one directory per group) is best done when setting up your wiki. '^[[Cookbook:PerGroupSubDirectories|#]]^'

!!Other customization

After setting up ''local/config.php'' file, you may wish to make other [[local customizations]]. See the [[Cookbook:CookbookBasics | PmWiki Cookbook]] for a large number of customizations that have been contributed. And don't fear Cookbook recipes - they're well prepared, so that most of them require only to download a single file, add a one-line include command to @@config.php@@, and ''voilà!'' - they're working!

If you (or others sharing your server) want to maintain more than one wiki on the same server, see [[Wiki Farms]].

!!Now what?

Don't forget to join a [[MailingLists | PmWiki mailing list]], where you can email other [[wiki administrator]]s for help on customizing PmWiki and participate in discussions about PmWiki improvements.  Once you have your site operational, be sure to add it to PmWiki:PmWikiUsers so others will know about it!
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Installation</pagename>
<data><![CDATA[(:title PmWiki Installation :)
(:Summary: Obtaining and installing PmWiki:)
(:Audience: administrators (basic) :)
This page explains how to download and install PmWiki 2.1 and 2.2.  
Here's a list of related pages:

* [[Requirements]] - {Requirements$:Summary}
* [[Upgrades]] - {Upgrades$:Summary}
* [[Wiki Farms]] - {WikiFarms$:Summary}
* [[Change Log]] -  {ChangeLog$:Summary}

'''Improvements''' to these instructions are always appreciated.  Just report any problems you  encounter to the pmwiki-users [[mailing list(s)]] or use the [[PITS:PITS |PmWiki Issue Tracking System]].

!! Installing PmWiki

!!! 1. Download
Download the latest version of PmWiki as a
* zip archive ([[(http://pmwiki.org/pub/pmwiki/)pmwiki-latest.zip]]), or a
* gzipped tarball ([[(http://pmwiki.org/pub/pmwiki/)pmwiki-latest.tgz]]) from [[http://pmwiki.org/pub/pmwiki/]], or
* download the latest beta from the [[PmWiki:Download]] page.

!!! [[#unpack]] 2. Unpack
Unpack the archive ([@tar zxvf pmwiki-latest.tgz@] or [@unzip pmwiki-latest.zip@]).  This will create a ''pmwiki-x.y.z'' directory containing the PmWiki software.  For example, the current "latest" should unpack to a directory named ''{$Version}''.  The files in this directory include:
>>pre<<
  README.txt        An introductory document
  pmwiki.php        The main PmWiki script
  local/            Configuration scripts (local configuration files)
  cookbook/         Recipes (add-ons) from the [[(Cookbook:)Cookbook]]
  docs/             Brief documentation, sample configuration scripts
  pub/              Publicly accessible files
  pub/css/          Extra CSS stylesheet files '^[[PmWiki/Skins#further|#]]^'
  pub/guiedit/
  pub/skins/        Layout templates for [[Cookbook:Skins|custom]] look and feel
  scripts/          Scripts that are part of PmWiki
  wikilib.d/        Bundled default PmWiki pages
>><<

The ''pmwiki-x.y.z'' directory needs to be placed into a location accessible by your webserver (e.g., in a ''public_html'' directory of some sort).  You can place files and directories using a number of methods -- FTP, or a Unix [@mv@] or [@cp@] command generally does the job.

->%note% Note: It is recommended to change the "''pmwiki-x.y.z''" directory name to be simply "''pmwiki''".

!!! [[#directories]] 3. Create directories
[[#dirsetup]]In most cases PmWiki will do this for you.
Open a web browser to the ''pmwiki.php'' script on the server (i.e., not the one on your local computer or accessed using a [=file://...=] URL).  PmWiki will then analyze your system configuration and provide instructions (if needed) for creating the ''wiki.d/'' directory which will be used to hold the pages created for your site. 

Otherwise, there are two ways to achieve this. (Use %newwin%[[http://filezilla-project.org/download.php|Filezilla]] or [[http://winscp.net/eng/download.php|WinSCP]] to change FTP file/folder permissions.)

->3a. You can create the ''wiki.d/'' directory manually, and then give it full write permissions (i.e., "[@chmod 777 wiki.d@]"). Use this method when "safe mode" is activated in the server's PHP installation.

->3b. On some systems you can let PmWiki create ''wiki.d/'' by temporarily changing the permissions on the directory containing the ''pmwiki.php'' file to 2777.  In Unix this is commonly done by changing to the directory containing ''pmwiki.php'' and executing the command

->@@chmod 2777 .@@

->(note the dot at the end). The [@chmod@] command also works in many FTP programs. Creating ''wiki.d/'' in this manner will (1) make the directory writable so the web server can create the data directory it needs for the wiki files, (2) preserve group ownership of the directory so the installer account can manipulate the files created in this directory, and (3) make it more difficult for other accounts on the same server to access the files in ''wiki.d/''.

After establishing directory permissions, try opening a browser to the ''pmwiki.php'' script again.  If all is well, the ''wiki.d'' directory will have been created and you'll see the default home page.

%red%'''Important:''' If you used method 3b, you should reset permissions by executing "[@chmod 755 .@]" in the directory containing pmwiki.php.%%

[[#dirsetupend]]
!!! 4. Initialize
Check out [[Initial Setup Tasks]] for other tasks you may want to perform to begin customizing your PmWiki installation.  You might also want to peruse the [[Release Notes]] for further information.

!!! 5. Set language
If you want to use PmWiki in a different language download the [[Internationalizations|international]] language pack as zip archive ([[(http://pmwiki.org/pub/pmwiki/i18n/)i18n-all.zip]]) from [[http://pmwiki.org/pub/pmwiki/i18n/]]. Then extract it and copy the files into the ''wikilib.d/'' directory as described above. Besides the ''-all'' file you can also download your country localization file only.

Languages available are:
(:pagelist fmt=#listlanguage name=PmWiki* list=normal order=$:Language $:Language=- :)
(:if false:)
[[#listlanguage]]
(:template first:)
->
(:template each:)
[[{=$Group}/{=$Name} | {=$:Language} ]]
[[#listlanguageend]]
(:ifend:)

There are two directories in the decompressed i18n archive, ''scripts'' and ''wikilib.d''. Copy the files respectively contained in these directories to the ''scripts'' and ''wikilib.d'' of your PmWiki directory. For example, for French localization,  PmWikiFr.* and PmWiki.* must be contained in the '''same''' directory.

Then, enable localization by adding an instruction to local/config.php to load the language translation page of your choice. For instance,  [@XLPage('fr','PmWikiFr.XLPage');@] loads the French language page PmWikiFr.XLPage.

Read more about this on [[Internationalizations]].

!! [[#notes]] Notes

* [[#indexphp]] The PmWiki distribution deliberately doesn't include an ''index.php'' file.  You can easily add your own "wrapper script" in the same directory as  ''pmwiki.php''.  Create a new file called ''index.php'' with the following single line of text (missing a closing "[@ ?>@]" tag deliberately):

-->[@<?php include('pmwiki.php');@]

Resist the temptation to rename ''pmwiki.php'' to ''index.php'' because if you rename the file it will not be overwritten during an upgrade.

* If using the Unix ''tar'' command to unpack the archive in step 2 above, be sure that the files are created with sufficient permissions for the webserver to be able to access them.  Usually you can ensure this by typing @@umask 002@@ on the command line before unpacking the tar file.

* When installing on Windows you should take a look at [[Cookbook:SimultaneousEdits]] to enable [[simultaneous edits]] on that platform.

* Additional tips can be found at [[Troubleshooting]].

See also:
* [[Cookbook:PHP]] {Cookbook/PHP$:Summary}
* [[Cookbook:InstallOnIIS]] {Cookbook/InstallOnIIS$:Summary}

>>faq<< [[#faq]]
Q: Should I rename pmwiki.php to index.php?
A: Renaming pmwiki.php is not recommended. Instead, create an ''index.php'' file that contains this single line

->[@<?php include_once('pmwiki.php');@]

Q: How do I make pmwiki.php the default page for a website?
A: Create an ''index.php'' file that runs PmWiki from a subdirectory (''pmwiki/'' for example) and place it in the site's web document root (the main directory for the website).

->[@<?php chdir('pmwiki'); include_once('pmwiki.php');@]

Note: You will also need to explicitly set the $PubDirUrl variable (e.g. to [@"http://example.com/pmwiki/pub"@]) in ''local/config.php'' .

Q: How do I enable "Clean URLs" that are shorter and look like paths to my wiki pages? Why does pmwiki.org appear to have a directory structure rather than "?n=pagename" in URLs?
A: See [[Cookbook:CleanUrls]].

Q: Is it possible to move wiki.d to /tmp/persistent/foo/wiki.d (a new sourceforge rule)?
A: Sourceforge suggests moving everything to ''/tmp/persistent/new-folder-of-your-choice/'' and creating a symbolic link to the new folder on /tmp . It works -- see [[Cookbook:SourceForgeServers]].

Q: How can I run PmWiki on a standalone (offline, portable) machine ?
A: See [[Cookbook:Standalone]] or [[Cookbook:WikiOnAStick]].

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.InterMap</pagename>
<data><![CDATA[(:Summary: Interwiki links definition and use:)
(:Audience: author (intermediate) :)

The InterMap (also called InterWiki in some other wikis) is a system for defining links between [[WikiWikiWeb]] sites that was first developed by UseMod:UseModWiki and Meatball:MeatballWiki.  The method is to use a word that stands for a path that is defined. InterMap links have the form [@MapPrefix:PagePath@], where the host prefix is converted to a partial URL based on entries in the site's ''intermap.txt'' and ''localmap.txt'' files.

[[#custominclude]]
The default ''intermap.txt'' distributed with PmWiki (in the ''scripts/'' directory) includes the following InterMap entries:
>>pre<<
 PmWiki:     http://pmwiki.org/wiki/PmWiki/ 
 Cookbook:   http://pmwiki.org/wiki/Cookbook/ 
 Wiki:       http://c2.com/cgi/wiki? 
 UseMod:     http://usemod.com/cgi-bin/wiki.pl? 
 Meatball:   http://usemod.com/cgi-bin/mb.pl? 
 Wikipedia:  http://wikipedia.com/wiki/ 
 PITS:       http://pmwiki.org/PITS/ 
 Path:
>><<

(:if exists {$SiteGroup}.InterMap:)
[[{$SiteGroup}.InterMap]] includes the following entries:
(:include {$SiteGroup}.InterMap#include#includeend:)
(:else:)
You can map your own prefixes in your local page [[{$SiteGroup}.InterMap]].
(:ifend:)
[[#customincludeend]]

Thus, "PmWiki:Variables" becomes "http://pmwiki.org/wiki/PmWiki/" + "Variables," a link to the [[PmWiki.Variables->http://pmwiki.org/wiki/PmWiki/Variables]] page on the official PmWiki web site, Wiki:FrontPage is a link to the front page of the first WikiWikiWeb, and Wikipedia:Stonehenge takes you to the Wikipedia article about the famous megaliths in England.  

Like other links, you can use the double-bracket syntax to get different link text:
(:markup class=horiz:)
* [[Meatball:StartingPoints | starting points]] over at Meatball
* [[starting points -> Meatball:StartingPoints]] over at Meatball
(:markupend:)

If you want to link just to what the intermap says (e.g. http://wikipedia.com/wiki/ for Wikipedia), then do [@[[Wikipedia:. | Wikipedia's main page]]@], which produces [[Wikipedia:. | Wikipedia's main page]].  Note the . (period) after the Map: reference.

[[#path]]
The special [@Path:@] InterMap entry can be used to create "[[Cookbook:RelativeUrls|relative urls]]" in [[Cookbook:RelativeLinks|links]].

The actual set of InterMap links at any site is defined by the site administrator via the [[Site.InterMap]] page and the ''local/localmap.txt'' file; for more details, see [[PmWiki.CustomInterMap]]s.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Internationalizations</pagename>
<data><![CDATA[(:Summary: Language internationalisation of web pages:)
[[#include]]
PmWiki supports internationalization (internationalisation) of web pages, allowing accented characters to appear in page names and almost complete customization of PmWiki's prompts.  
[[#includeend]]
Most customization is provided via the XLPage() function in PmWiki, which loads a set of translation variables from a wiki page (typically named XLPage, but it can be named anything you wish).

>>rframe font-size:smaller clear:right<<
(:pagelist fmt=#languagelist name=PmWiki* list=normal order=$:Language $:Language=- :)
(:if false:)
[[#languagelist]]
(:template each:)
-< [[{=$Group}/{=$Name}]] {=$:Language} ~ [-[[{=$Group}/XLPage]]-] (:if exists {=$Group}.XLPageLocal:) [-[[{=$Group}/XLPageLocal]]-] (:ifend:)
[[#languagelistend]]
(:ifend:)
>><<
!! Loading Translation Pages

Pages for many [[(PmWiki:)other languages]] have already been created and maintained at the pmichaud.com site.  You can download an archive of these translations from http://pmichaud.com/pub/pmwiki/i18n/ .  Simply download the appropriate language archive(s), and unpack the archive(s) into the directory containing your ''pmwiki.php'' installation.  Each archive contains a number of page files that are placed in your ''wikilib.d/'' directory, and some special scripts for translations that use a character set other than iso-8859-1 (PmWiki's default). You can also use [[UTF-8]] charset.

Once the translation pages are installed, you enable a language by adding a call to `XLPage() in your ''config.php'' file.  For example, to select French language prompts, one would specify

->[@XLPage('fr','PmWikiFr.XLPage');@]

which says to load the translations for French ('fr') from the page [[PmWikiFr.XLPage]].  It's perfectly okay to load multiple pages; so if you want to create your own local translations without changing the ones you got from from an i18n archive, just create another page (see below) and load it on top. Be sure that you load first the page with your local changes:

-> [@
XLPage('fr','PmWikiFr.XLPageLocal');  # my local translations
XLPage('fr','PmWikiFr.XLPage');       # from i18n.tgz
@]

If your intention is to offer multiple languages on your site, and use [[Wiki Group]]s as language selectors, you may want to place this code in local customizations files (see [[PerGroup Customizations]]). For example, if your site is published in French and English, and the French pages are in a group called Fr, you could create a file named Fr.php in the ''local/'' directory which contains:

-> [@
<?php if (!defined('PmWiki')) exit();
##change to French language
XLPage('fr','PmWikiFr.XLPage');
@]

You may wish to create a page called ''PmwikiFr.php'' with the same content to access the French documentation in the PmwikiFr group.  ''En.php'' is not necessary in this case since English is the default language.

An alternative to the above would be to add to ''config.php'' the following, which tests if there is an XLPage in a group, and if it finds one it gets loaded:

-> [@    
$xlpage = FmtPageName('$Group.XLPage', $pagename);
if (PageExists($xlpage)) XLPage($xlpage, $xlpage);
@]

With this method you would need to copy any relevant XLPage into any group which needs the different language support.

See also [[Cookbook:MultiLanguage]] {Cookbook/MultiLanguage$:Summary}

!![[#CreatingNewTranslations]]Creating New Translations

If language pages don't exist for your desired language, it's easy to create one!  An XLPage translation file simply contains lines of the form

->[@'phrase' => 'translated phrase',@]

where "phrase" is an internationalized phrase (denoted by [@$[phrase]@]) in PmWiki's $...Fmt variables, and "translated phrase" is what should be printed in your particular language.  For example, the line (in [@PmWikiFr.XLPage@])

->[@'Search' => 'Rechercher',@]

converts "[@$[Search]@]" to "Rechercher" on output.  The file PmWiki:XLPageTemplate is a good starting point for creating a new XLPage and has most of PmWiki's key phrases already listed in it.  

If you create new versions of PmWiki pages in other languages, please consider adding them to the [[PmWiki:PmWiki | main PmWiki site]] so that they can be made available to others in the i18n archives!

->%note% The term "i18n" is commonly used as an abbreviation for the English word "internationalization".  The abbreviation is derived from the fact that there are 18 letters between the "i" and the final "n" and few people want to type them all out.

!! Enabling "Special" Characters in WikiLinks

To enable "special" characters like for example German umlauts in WikiLinks, it is necessary to configure the server locale to ensure that PmWiki uses the proper character set definition.

If this is not possible due to limited access to the server configuration, PmWiki can be configured to use a specific locale by using the XLPage options (see [[(PmWiki:)XLPageTemplate]]).

For German umlauts, you'd need for example:

*[='Locale' => 'deu',=] <- for Windows servers, see [[http://msdn.microsoft.com/en-us/library/39cwe7zf.aspx|MSDN List of locale identifiers]]
*[='Locale' => 'de_DE',=] <- for Linux servers

Note that the locale identifier depends on the operation system and perhaps on the specific installation.

[[#notes]]
!! Notes

>>faq<< [[#faq]]

Q: If my wiki is internationalized by ''config.php'', how do I revert a specific group to English?

A: Use [@$XLLangs = array('en');@] in the group's [[per group customization(s)]] file.

Q: If my wiki is in English and I want just one page, or group, in Spanish do I say [@XLPage('es','PmWikiEs.XLPage');@] in the group or page configuration file?

A: Yes, that is usually the best method. If you were doing this with many scattered pages, or with several languages, you might find it easier to maintain if you load the translations all in config.php like this:

   XLPage('es','PmWikiEs.XLPage');
   XLPage('fr','PmWikiFr.XLPage');
   XLPage('ru','PmWikiRu.XLPage');
   $XLLangs = array('en');

A: Then in each group or page configuration file, you'd just use $XLLangs = array('es'); to set the language to use (in this case, Spanish). Note that though this method is easier to maintain, its somewhat slower because it loads all the dictionaries for each page view, even if they won't be used.

Q: What does the first parameter of this function stand for? How can it be used?

A: The XLPage mechanism allows multiple sets of translations to be loaded,
and the first parameter is used to distinguish them.  

For example, suppose I want to have translations for both normal French
and "Canadian" French.  Rather than maintain two entirely separate sets
of pages, I could do:

    XLPage('fr', 'PmWikiFr.XLPage');
    XLPage('fr-ca', 'PmWikiFrCa.XLPage');

PmWikiFr.XLPage would contain all of the standard French translations,
while PmWikiFrCA.XLPage would only need to contain "Canada-specific"
translations -- i.e., those that are different from the ones in the
French page.

The first parameter distinguishes the two sets of translations.
In addition, a ''config.php'' script can use the $XLLangs variable
to adjust the order of translation, so if there was a group or
page where I only wanted the standard French translation, I
can set

    $XLLangs = array('fr', 'en');

and PmWiki will use only the 'fr' and 'en' translations (in that order),
no matter how many translations have been loaded with XLPage().

!!Tools for PmWiki Localization

You can help to localize PmWiki in your language in the original site:
* [[(http://www.pmwiki.org/wiki/Localization/)Localization]] 
* [[(PmWiki:)Translation Portal]]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Introduction</pagename>
<data><![CDATA[>>faq<< [[#faq]]
Q: What is PmWiki?
A: PmWiki is a wiki-based system for collaborative creation and maintenance of websites. See [[PmWiki/PmWiki]].

Q: What can I do with it?
A: PmWiki pages look and act like normal web pages, except they have an "[[Main/WikiSandbox?action=edit|Edit]]" link that makes it easy to modify existing pages and add new pages into the website, using [[basic editing]] rules. You do not need to know or use any HTML or CSS. Page editing can be left open to the public or restricted to small groups of authors. Feel free to experiment with the [[PmWiki/Text Formatting Rules]] in the "[[Main/WikiSandbox?action=edit | Wiki sandbox]]". The website you're currently viewing is built and maintained with PmWiki.

Q: What are the requirements?
A: See the [[PmWiki.Requirements | PmWiki requirements]] page.

Q: Where can I find documentation?
A: See the [[PmWiki.DocumentationIndex | documentation index]] page.

Q: How can I download PmWiki?
A: See the [[PmWiki:Download | download]] page.

Q: How do I install PmWiki?
A: Instructions for installation are on the [[PmWiki.Installation | installation page]].

Q: How do I get help with PmWiki?
A: See [[(PmWiki:)Mailing lists]] and [[(PmWiki:)How to get assistance]].
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.LayoutVariables</pagename>
<data><![CDATA[(:Summary:variables that control page layout:)

Variable substitutions in the skin template are all managed by the `FmtPageName() function from pmwiki.php. Pmwiki variable substitutions available on pages are managed by the {$var} substitutions from stdmarkup.php or superseded in local/config files. 

:$ActionSkin:This array is used to override the current skin when performing a given action. The most common use is to set @@$ActionSkin['print']='foo'@@ to use the 'foo' skin when printing, regardless of what the @@$Skin@@ variable is set to.

:$WikiTitle:A variable which contains the Wiki title as displayed by the browser

:$HTMLStylesFmt:An array of CSS statements to be included in the page's output along with other HTML headers.  This array provides an easy place for scripts to add custom CSS statements.

:$HTMLHeaderFmt:An array of HTML text to be included in the page's <head> section, at the point where the [[skin template(s)]] specifies a [@<!--HTMLHeader-->@] directive.  This array provides an easy place for scripts to add custom HTML headers.

->For example, if you want to specify a logo for all the pages of your wiki (a png image for Firefox (and others...), an ico for Internet Explorer):
-->[@ 
$HTMLHeaderFmt['logo'] =
  '<link href="http://path/to/logo.png" type="image/png" rel="icon" />
  <link href="http://path/to/logo.ico" type="image/x-icon" rel="shortcut icon" />';
@]

->Another example, if you want to get the rss notification on some browsers (the rss icon in firefox for instance):
-->[@ 
$HTMLHeaderFmt['rss'] =
  '<link rel="alternate" type="application/rss+xml" title="Rss All recent Changes" 
     href="$ScriptUrl/Site/AllRecentChanges?action=rss" />';
@]

:$HTMLFooterFmt:Like $HTMLHeaderFmt above, this contains an array of HTML text to be included near the end of an HTML document, at the point where the [[skin template(s)]] specifies a [@<!--HTMLFooter-->@] directive (usually just before a closing </body> tag).  Primarily used by scripts to add custom HTML output after the body of the page output. 

:$MetaRobots:Sets the value of the [@<meta name='robots' ... />@] tag generated by PmWiki to control search engine robots accessing the site.  PmWiki's default setting tells robots to not index anything but the normal page view, and to not index pages in the PmWiki [[wiki group]].  Explicitly setting $MetaRobots overrides this default.
        # never index this site
        $MetaRobots = 'noindex,nofollow';
        # disable the robots tag entirely
        $MetaRobots = '';

:$MessagesFmt:An array of HTML text to be displayed at the point of any [@(:messages:)@] markup.  Commonly used for displaying messages with respect to editing pages.

:$RecentChangesFmt:An array specifying the format of the RecentChanges listing.

->The format can be specified in your config.php using the following:
-->[@
$RecentChangesFmt['$SiteGroup.AllRecentChanges'] = 
  '* [[{$Group}.{$Name}]]  . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]';
$RecentChangesFmt['$Group.RecentChanges'] =
  '* [[{$Group}/{$Name}]]  . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]';
@]

->Note that changes made to the format will only affect new edits. In other words, you will need to edit a page for your new format to be visible.  Note also that you need to have two spaces between the page name and the other information about the edit.

->Also note that this variable has other uses, such as not reporting at all to RecentChanges and AllRecentChanges as found here [[PmWiki:Questions|PmWiki Questions]].

:$DraftRecentChangesFmt:An array specifying the format of the RecentChanges listing when saving Draft pages.

->$RecentChangesFmt is set to $DraftRecentChangesFmt when a Draft page is saved.  For example, you could save drafts in a separate Recent Draft Changes page and not list in the normal group's Recent Changes page:
-->[@
$DraftRecentChangesFmt['$Group.RecentDraftChanges'] =
  '* [[{$Group}/{$Name}]]  . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]';
$DraftRecentChangesFmt['$Group.RecentChanges'] = '';
@]

:$RCLinesMax:The maximum number of lines to be stored in RecentChanges pages.  The default is zero, meaning "no limit".
        $RCLinesMax = 1000;       # maintain at most 1000 recent changes

:$PageRedirectFmt:The text to be used when a page is redirected via the [@(:redirect:)@] markup.
-->[@
$PageRedirectFmt = '<p><i>redirected from $FullName</p>';
$PageRedirectFmt = '';
@]
->For display options, see also the FAQ on [[(PmWiki:)PageDirectives(#faq)]].

:$WikiStyle:An array which contains the predefined WikiStyles which can be used on a textpage.[[<<]]See: [[PmWiki.CustomWikiStyles]]

:$MaxIncludes:Controls the number of times that pages can be included via the [@(:include:)@] and other directives, used to control recursion and otherwise pose a sanity check on page contents.  $MaxIncludes defaults to 50, but can be set to any value by the wiki administrator.
        $MaxIncludes = 50;            # default
        $MaxIncludes = 1000;          # allow lots of includes
        $MaxIncludes = 0;             # turn off includes

:$[=Skin=]:Lists the name(s) of skins to load, unless overridden by $ActionSkin. Normally $Skin contains a single string which is a the name of a skin directory, but it may also be an array of names, in which case the first skin found from the list is used.

:$SkinDirUrl:Set by ''scripts/skins.php'' to be the base url of the current skin's directory (i.e., within a 'pub/skins/' directory).  This variable is typically used inside of a skin .tmpl file to provide access to .css files and graphic images associated with the skin.

:$SkinLibDirs:An array which, given the filesystem path (array key) to a skin (or a directory containing several skins), provides the corresponding URL (array value).

->The array key is the directory containing the skin.tmpl and skin.php files, as seen by the PmWiki program. It does not have to be publicly accessible.

-> The value is the URL (web address) of the directory containing the .css, .gif, and other files which appear in the HTML code sent by PMWiki to the browser. This directory must be publicly accessible.

->By default $SkinLibDirs is set to:\\
[@
$SkinLibDirs = array(
  "./pub/skins/\$Skin" => "$PubDirUrl/skins/\$Skin",
  "$FarmD/pub/skins/\$Skin" => "$FarmPubDirUrl/skins/\$Skin");
@]

->Extra details: When PMWiki is searching for a skin it looks for a directory named for the skin in the array index/keys, and if it finds it then it will use the files in that directory and also the files in the matching array value url. The two sides normally point to the same publicly accessible directory, but they do not have to.

:$PageLogoUrl: is the url that refers to a logo image which most skins display somewhere in the page's header (top left usually).

:$EnablePathInfo:Changes the handling of the page URL. When set to @@1@@ page URL will be @@...wiki.php/Main/Main@@, when set to @@0@@ (default) it will be @@...wiki.php?n=Main.Main@@.

:$EnableFixedUrlRedirect:When PmWiki is given a partial page name (e.g., just the name of a WikiGroup), it uses $PagePathFmt in order to make a complete page name from the partial one, then issues a "redirect" to the browser to tell it to reload the page with the correct full page name.  Setting $EnableFixedUrlRedirect=0; blocks the redirect, so that PmWiki continues processing with the adjusted page name rather than issuing the redirect. 

:$GroupHeaderFmt:Defines the markup placed at the top of every page. Default value is:
        [@$GroupHeaderFmt = '(:include $Group.GroupHeader:)(:nl:)';@]

:$GroupFooterFmt:Defines the markup placed at the bottom of every page. Default value is:
        [@$GroupFooterFmt = '(:include $Group.GroupFooter:)(:nl:)';@]

:$PageNotFoundHeaderFmt:Specifies the HTTP header to send when attempting to browse a page that doesn't exist.  Some webserver packages (notably Microsoft's "Personal Web Server") require that this variable be changed in order to work.

-->[@
# default
$PageNotFoundHeaderFmt = 'HTTP/1.1 404 Not Found';
# return all pages as found
$PageNotFoundHeaderFmt = 'HTTP/1.1 200 Ok';
@]

->Beware when expecting to return the content of a Group(header|footer) for an non existent page!  By default PmWiki returns 404 (because the page does not exist), despite there is some content to show.  Firefox shows the content, while Internet Explorer displays its default 404 page.  $PageNotFoundHeaderFmt MUST be set to return 200 as described above in order to get the expected behaviour with all browsers.

:$HTMLVSpace:Setting [@$HTMLVSpace = '';@] in a local customizationfile (e.g., [@local/config.php@]) prevents insertion of spacer paragraphs ([@<p class='vspace'></p>@]) in generated HTML code. To limit this change to a single skin, place the [@$HTMLVSpace = '';@] statement in a skin.php file, preceded by the statement [@global $HTMLVSpace;@].

:$TableCellAttrFmt:For [[Tables]], defines the HTML attributes given to each @@<td>@@ or @@<th>@@ cell in the output.  Can contain references to $TableCellCount which holds the horizontal column number of the current cell.

:$TableRowAttrFmt:For [[Tables]], defines the HTML attributes given to each @@<tr>@@ element in the output.  Can contain references to $TableRowCount to give the absolute row number within the table, or $TableRowIndex to provide a repeating row index from 1 to $TableRowIndexMax.
        # Give each row a unique CSS class based on row number (tr1, tr2, tr3, ... )
        $TableRowAttrFmt = "class='tr\$TableRowCount'";
        # Give each row alternating CSS classes (ti1, ti2, ti1, ti2, ti1, ... )
        $TableRowIndexMax = 2;
        $TableRowAttrFmt = "class='ti\$TableRowIndex'";

:$TableRowIndexMax:The maximum value for $TableRowIndex in [[Tables]].
        # Set rows indexes as 1, 2, 3, 1, 2, 3, 1, 2, ...
        $TableRowIndexMax = 3;
 
:$FmtV['$TableCellCount']:PMWiki internal variable - Horizontal column number of the current cell. For use in $TableCellAttrFmt and $TableRowAttrFmt.  Administrators can use in $TableCellAttrFmt and/or $TableRowAttrFmt.
        [@Example: $TableCellAttrFmt = 'class=col\$TableCellCount';@] 

:$FmtV['$TableRowCount']:PMWiki internal variable - Current row number.  Administrators can use in $TableCellAttrFmt and/or $TableRowAttrFmt.
        [@Example: TableRowAttrFmt = "class='row\$TableRowCount'";@] 

:$FmtV['$TableRowIndex']:PMWiki internal variable - Row index number derived from $TableRowIndexMax.  (1,2,3,1,2,3,...). Administrators can use in $TableCellAttrFmt and/or $TableRowAttrFmt.
        [@Example: $TableRowAttrFmt = "class='ind\$TableRowIndex'";@]

See also: [[Edit Variables]]]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.LinkVariables</pagename>
<data><![CDATA[(:Summary:variables that control the display of links in pages:)
(:Audience: admins (advanced):)
:$EnableLinkPageRelative:When enabled, causes PmWiki to use relative urls for page links instead of absolute urls.
        $EnableLinkPageRelative = 1;

:$PagePathFmt: This array lists the order in which PmWiki looks for the page that you ''most likely'' are attempting to link to. The default is listed below. Look at Cookbook:PagePaths for some ideas.
        [=array('{$Group}.$1','$1.$1'.'$1.{$DefaultName}')=]

:$LinkPageExistsFmt:The (HTML) string to output for links to already existing wiki pages.  Defaults to 
        <a class='wikilink' href='\$LinkUrl'>\$LinkText</a>

:$LinkPageCreateFmt:The (HTML) string to output for links to non-existent wiki pages.  The default is to add a '?' after the link text with a link to the page edit/create form.  Defaults to
        <a class='createlinktext' href='\$PageUrl?action=edit'>\$LinkText</a>
        <a class='createlink' href='\$PageUrl?action=edit'>?</a>

:$LinkPageCreateSpaceFmt:Same as $LinkPageCreateFmt, but used when the link text has a space in it. 

:$LinkPageSelfFmt:The (HTML) string to output for self-referencing links (i.e. links to the page itself).  Defaults to
        <a class='selflink' href='\$LinkUrl'>\$LinkText</a>

:$UrlLinkFmt:The (HTML) string to output for URL-links that begin with 'http:', 'ftp:', etc.  Defaults to
        <a class='urllink' href='\$LinkUrl' rel='nofollow'>\$LinkText</a>

:$IMapLinkFmt: an array of link formats for various link "schemes". Not set as default.
->Examples of custom formats to allow different styling via classes: 
->Links to http: standard url links:
         $IMapLinkFmt['http:'] = "<a class='httplink urllink' href='\$LinkUrl'>\$LinkText</a>";  
->Links to https: secure pages:
         $IMapLinkFmt['https:'] = "<a class='httpslink urllink' href='\$LinkUrl'>\$LinkText</a>";   
->Links to PmWiki: InterMap shortcut:
         $IMapLinkFmt['PmWiki:'] = "<a class='pmwikilink urllink' href='\$LinkUrl'>\$LinkText</a>";

:$InterMapFiles:An array consisting a list of files and pages containing InterMap entries to be loaded (see [[CustomInterMap]]).

:$MakePageNameFunction:Name of a custom function to replace `MakePageName(), which converts strings into valid page names.

:$MakePageNamePatterns: $MakePageNamePatterns is an array of regular expression replacements that is used to map the page link in a ''free link'' such as [@[[free link]]@] into a page name. Currently the default sequence is: [@
    "/'/" => '',                           # strip single-quotes
    "/[^$PageNameChars]+/" => ' ',         # convert non-alnums to spaces
    "/((^|[^-\\w])\\w)/e" 
      => "strtoupper('$1')",               # initial caps after spaces
    "/ /" => ''                            # strip spaces
@]
: :Note that if you change $MakePageNamePatterns, the documentation links may break. This can be fixed by re-setting $MakePageNamePatterns to the default in local/PmWiki.php.

:$WikiWordCountMax:The maximum number of times to convert each WikiWord encountered on a page.  Defaults to 1,000,000.  Common settings for this variable are zero (disable WikiWord links) and one (convert only the first occurrence of each WikiWord).
        $WikiWordCountMax = 0;     # disable WikiWord links
        $WikiWordCountMax = 1;     # convert only first WikiWord

:$WikiWordCount:An array that allows the number of WikiWord conversions to be set on a per-WikiWord basis.  The default is to use $WikiWordCountMax unless a value is set in this array.  By default PmWiki sets @@$WikiWordCount['PmWiki']=1@@ to limit the number of conversions of "PmWiki".
        $WikiWordCount[=['PhD']=0;     # Don't convert "PhD"=]
        $WikiWordCount['WikiWord']=5;  # Convert WikiWord 5 times
        # the following lines keep a page from linking to itself
        $title = [=FmtPageName=]('$Title_',$pagename);
        $WikiWordCount[$title]=0;   
 
:$EnableRedirectQuiet:Enable the @@quiet=1@@ parameter for the [[PmWiki.PageDirectives#redirect|redirect directive]]. On publicly edited wikis it is advisable not to enable quiet redirects.
        $EnableRedirectQuiet = 0;     # disable quiet redirects (default)
        $EnableRedirectQuiet = 1;     # enable quiet redirects
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Links</pagename>
<data><![CDATA[(:Summary:Linking within and between wiki pages:)
(:Audience: authors (basic) :)
A key feature of [[Wiki Wiki Web]]s is the ease of creating %newwin%[[Wikipedia:Hyperlink|hyper links]]%% in the text of a document.  
PmWiki provides multiple mechanisms for creating such links.

!! Links to other pages in the wiki

To create a link to another page, simply enclose the name of the page inside double square brackets, as in [@[[wiki sandbox]]@] or [@[[installation]]@].  These result in links to [[wiki sandbox]] and [[installation]], respectively.

PmWiki creates a link by using the text inside the double brackets. It does this by removing spaces between words, and automatically capitalizing words following spaces or other punctuation (like ~). Thus [@[[Wiki sandbox]]@], [@[[wiki sandbox]]@], and [@[[WikiSandbox]]@] all display differently but create the same link to the page titled ''WikiSandbox''.

In other words, PmWiki will automatically create the link path name using title case as a rule, but link text will display in the format you have entered it.

A suffix can also be added to the end of a link, which becomes part of the link text but not the target.  Thus [@[[wiki sandbox]]es@] is a link to ''[=WikiSandbox=]'' but displays as [[wiki sandbox]]es.

Link text in (parentheses) will not be not displayed, so that [@[[(wiki) sandbox]]@] links to ''[=WikiSandbox=]'' and displays as [[(wiki) sandbox]].

Finally, you can specify the link text via a vertical brace, thus  [@[[WikiSandbox | a play area]]@], which links to ''WikiSandbox'' but displays as [[WikiSandbox | a play area]].  You can use an arrow ([@->@]) to reverse the order of the text and target, as in [@[[a play area -> WikiSandbox]]@]  ([[a play area -> WikiSandbox]]).

Some sites also recognize [[WikiWord]] links, in which a camel case (capitalised) ''[=WikiWord=]'' appearing in the text is automatically treated as a link to a page of the same name.

!!! [[#linkshortcuts]]Link shortcuts

Use of special characters in title is not a problem for PmWiki, but sometimes the character set is different from your computer and the server computer or the client computer that is used to read your wiki. Specially UTF-8 gives some problems. So it's better not to use these and keep ASCII characters if possible. Any page can have a [=(:title <name>:)=] directive to display a localized title instead of the page file name. In this case, the following tip is important and usefull.

'''[@[[PageName|+]]@]''' creates a link to PageName and uses that page's title as the link text, eg [=[[PmWiki.BasicEditing|+]]=] where the page Installation has the directive [=(:title=] {PmWiki/BasicEditing$Title}:)=] gives [[PmWiki.BasicEditing|+]].  

[@[[PageName|#]]@] creates a [[#reference|reference]] link as shown below'^[[#reference|#]]^'.

[@[[!PageName]]@] creates a link to the PageName in the group called Category. See [[PmWiki/Categories]].

[@[[~Author]]@] link creates a link to the page in the page called Author in the Profiles group.  PmWiki will automatically generate that link for the current Author when it encounters three tilde characters ([@~@]) in a row ([@~@][@~@][@~@]).  Adding a fourth tilde ([@~@][@~@][@~@][@~@]) appends the current date and time.

!!! [[#anchors]]Links to specific locations within a page -- "anchors"

To define a location within a page to which you may jump directly, use the markup [@[[#name]]@].  This creates an "anchor" that uniquely identifies that location in the page.  Then to have a link jump directly to that anchor, use one of

* [@[[#name|link text]]@] within the same page, or
* [@[[PageName#name]]@] or [@[[PageName#name|link text]]@] for a location on another page
* The form [@[[PageName(#name)]]@] may be useful for hiding the anchor text in a link. 

For example, here's a link to the [[#intermaps | Intermaps]] section, below. 

Notes:
* %red%the anchor itself must begin with a letter%%, '''not a number'''
* a link to an anchor must have the '''same capitalization as the anchor''' itself. 
* Spaces are not allowed in an anchor:  "[@[[#my anchor]]@]" won't work,  "[@[[#myanchor]]@]" will.

!! Links outside the wiki
[[#externallinks]]
!!! Links to external sites ([=URLs=])

Links to external sites simply begin with a prefix such as 'http:', 'ftp:', etc.  Thus [@http://google.com/@] and [@[[http://google.com/]]@] both link to Google.  As with the above, an author can specify the link text by using the vertical brace or arrow syntax, as in [@[[http://google.com/ | Google]]@] and [@[[Google -> http://google.com]]@].

If the external link includes (parentheses), escape these using [=%28=] for "(" and [=%29=] for ")" : 
(:markup:)[=[[http://en.wikipedia.org/wiki/Wiki_%28disambiguation%29 | link to "Wiki (disambiguation)" ]]=]

!!! Links to intranet (local) files

You can link to a file system by including the prefix [@'file:///'@] (for Internet Explorer at least). So [@file:///S:\ProjPlan.mpp@] and [@[[Shared S drive->file:///S:\]]@] are both valid links. On a Windows file system you may want to use network locations (eg \\server1\rootdirectory\subdirectory) rather than drive letters which may not be consistent across all users. Not all browsers will follow such links.

!! Link characteristics
!!! [[#reference]]Links as References

Links may also be specified as '''References''', so the target appears as an anonymous ''numeric'' reference rather than a ''textual'' reference. The following markup is provided to produce sequential reference numbering within a PmWiki page:

Formatting the link as: [@[[http://google.com |#]]@] produces: [[http://google.com |#]] as the link.

Subsequent occurrence of the reference link format on the same page will be incremented automatically as per the following example: Entering [@[[http://pmwiki.com |#]]@] produces [[http://pmwiki.com |#]], [@[[#intermaps |#]]@] produces [[#intermaps |#]], and so on for further reference links.

!!! [[#intermaps]]Intermaps

[[Inter Map]] links are also supported (see [[Inter Map]]).  In particular, the [@Path:@] InterMap entry can be used to create links using relative or absolute paths on the current site (e.g., [@Path:../../somedir/foo.html@] or [@Path:/dir/something.gif@]).

!!! Links to pages in other [[wiki group]]s

See [[Wiki Group]].

!!! Links that open a new browser window

To have a link open in another window, use [@%newwin%...%%@]:

* [@%newwin%  http://pmichaud.com %%@] produces %newwin%  http://pmichaud.com %%
* [@%newwin% [[http://google.com/ | Google]] %%@] produces %newwin% [[http://google.com/ | Google]]%%
* [@%newwin% [[Main.WikiSandbox]] %%@] produces %newwin%  [[Main.WikiSandbox]]%%

You can also specify that links should open in a new window via the @@[=%target=_blank%...%%=]@@ attribute:

(:markup class=horiz:)
The following link %target=_blank% http://pmichaud.com %%
will open in a new window.
(:markupend:)

!!! [[#robots]]Links that are not followed by [[(PmWiki:)robots]]

Prefix a link with [=%rel=nofollow%=] to advise %newwin rel=nofollow%[[http://robotstxt.org/|robots]] and [[http://validator.w3.org/checklink|link checkers]]%% not to follow it.

!! Links and CSS Classes

PmWiki automatically gives classes to several types of links. Among other things, this enables you to format each type differently.

Note: This may be an incomplete list.
:.selflink:A link to the current page. Useful in sidebars to show "you are here".
:.wikilink:A link to another page within the wiki.
:.urllink:A link to a page outside the wiki.

You can create a the class [@.anchor@] for anchor links\\
[@[[#target]]@], aka  <A name='target'></A>\\
by putting the following in config.php :

 Markup('[[#','<[[','/(?>\\[\\[#([A-Za-z][-.:\\w]*))\\]\\]/e',
    "Keep(TrackAnchors('$1') ? '' : \"<a name='$1' id='$1' class='anchor'></a>\", 'L')");

!! Notes

'''Note:''' The default behavior of "+" above can be overridden to display the spaced title, rather than simply the title by adding the following to config.php:
->[@
## [[target |+]] title links
Markup('[[|+', '<[[|',
  "/(?>\\[\\[([^|\\]]+))\\|\\s*\\+\\s*]]/e",
  "Keep(MakeLink(\$pagename, PSS('$1'),
                 PageVar(MakePageName(\$pagename,PSS('$1')), '\$Titlespaced')
                ),'L')");
@]

>>faq<< [[#faq]]

Q: How do I create a link that will open as a new window?

A: Use the [@%newwin%@] wikistyle, as in:
(:markup class=horiz:) [=%newwin% http://example.com/ %%=]

Q: How do I create a link that will open a new window, and configure that new window?

A: This requires javascript. See [[Cookbook:PopupWindow]].

Q: How do I place a mailing address in a page?

A: Use the [@mailto:@] markup, as in one of the following:

(:markup class="horiz":)
* mailto:myaddress@example.com
* [[mailto:myaddress@example.com]]
* [[mailto:myaddress@example.com | email me]]
* [[mailto:myaddress@example.com?subject=Some subject | email me]]@]
(:markupend:)
The markup @@[=[[mailto:me@example.=]com?%red%cc=%%someoneelse@example.com%red%&bcc=%%else@example.com%red%&subject=%%Pre-set Subject%red%&body=%%Pre-set body | display text]] =]@@ lets you specify more parameters like the message body and more recipients (may not work in all browsers and e-mail clients).

See also [[Cookbook:EProtect]] or [[Cookbook:ProtectEmail]] for information on protecting email addresses from spammers.

Q: How can I enable links to other protocols, such as nntp:, ssh:, xmpp:, etc?

A: See [[Cookbook:Add Url schemes]] {Cookbook.AddUrlSchemes$:Summary}

Q: How do I make a WikiWord link to an external page instead of a WikiPage?

A: Use link markup.  There are two formats:

->[@[[http://example.com/ | WikiWord]]
[[WikiWord -> http://example.com/]]@]

Q: How do I find all of the pages that link to another page (i.e., backlinks)?

A: In the wiki search form, use @@link=Group.Page@@ to find all pages linking to Group.Page.

A: Use the [@link=@] option of the [[[@(:pagelist:)@] directive -> PmWiki/PageLists#pagelistlink]], as in

->[@(:pagelist link=SomePage list=all:)   -- show all links to SomePage
(:pagelist link={$FullName} list=all:)  -- show all links to the current page@]

Q: What link schemes does PmWiki support?
A: See [[PmWiki:Link schemes]] {PmWiki.LinkSchemes$:Summary}

Q: How do I open external links in a new window or mark them with an icon?
A: See [[Cookbook:External links]] {Cookbook.ExternalLinks$:Summary}

Q: How can I use an image as a link?
A: Use [=[[Page| Attach:image.jpg ]] or [[ http://site | http://site/image.jpg ]]=]  See [[PmWiki/Images#links]]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.LocalCustomizations</pagename>
<data><![CDATA[(:Summary:Customize your PmWiki installation through @@config.php@@ and @@local.css@@:)
A [[Wiki Administrator]] can make a lot of customizations simply by setting variables in the ''/local/config.php'' and defining cascading style sheets in ''/pub/css/local.css'' files.  Any group or page can also have [[PerGroupCustomizations|its own configuration file and configuration css file]].

From its inception, PmWiki has been designed so that [[Wiki Administrator]]s can greatly customize the way PmWiki displays pages and the markup sequences used to generate pages.  (This is even mentioned explicitly in [[PmWiki Philosophy]] #4.)  As a result, the core ''pmwiki.php'' script makes extensive use of [[PmWiki.Variables]] to determine how markup sequences will be processed and what each individual page will output.

The bulk of this page describes how customizations work in general, see [[PmWiki.Documentation Index]] for specific customizations that are commonly performed at many PmWiki installations, including:

* [[Skins]] - {Skins$:Summary}
* [[Internationalizations]] - {Internationalizations$:Summary}
* [[Custom Markup]] - {CustomMarkup$:Summary}
* [[Custom InterMap]]s - {CustomInterMap$:Summary}

The simplest type of customization is merely setting a variable to 1 (or TRUE).  Here's an example that enables ?action=diag and ?action=phpinfo actions:

->[@$EnableDiag = 1;@]

You can begin a line with a "#"  (an octothorpe, a.k.a. a hash symbol or pound sign) to add a comment.  Additionally, some built-in PmWiki variables take values other than 1 or 0 (true or false).  Here's another example that customizes the wiki's behavior with respect to search engine web robots (see [[Cookbook:ControllingWebRobots]]):

->[@
# Remove the default "rel='nofollow'" attribute for external links.
$UrlLinkFmt = "<a class='urllink' href='\$LinkUrl'>\$LinkText</a>";
@]

The ''scripts/'' subdirectory (below the directory holding the ''pmwiki.php'' script) has many customizations.
The PmWiki [[(Cookbook:)Cookbook]] contains many example customizations (recipes) that you can download into the ''cookbook/'' subdirectory,
The first few lines of each of these scripts generally contain instructions about how to enable (and use) the feature provided by the script.

These customizations are included in your ''config.php'' site configuration. For most scripts this is done by simply adding lines like:
->[@include_once("cookbook/recipefile.php");@]
and
->[@include_once("scripts/scriptfile.php");@]
at the end of the ''config.php'' file to enable them.  

Some of the scripts are automatically enabled for you via the ''scripts/stdconfig.php'' script unless you disable it by setting @@$EnableStdConfig=0;@@ in ''local/config.php''.

Note that you should strongly resist the temptation to directly modify the ''pmwiki.php'' script or the files in the ''scripts/'' subdirectory.  Any modifications you make to these files will probably be overwritten whenever you perform a [[PmWiki.Upgrade(s)]].  Instead, look at some of the sample scripts for examples of customizations that can be performed from ''config.php''. You can even create your own script to do a customization and use @@include_once(...)@@ to include it from ''config.php''.  If you do make your own customization script, you can safely put it in the ''cookbook/'' subdirectory--it won't get overwritten by an upgrade there.  You might also want to submit your customization to the [[MailingLists|pmwiki-users mailing list]] or the [[(Cookbook:)Cookbook]] so that others can benefit from your effort and so that it can perhaps be included in future releases of PmWiki.

>>faq<< [[#faq]]
Q: There's no "config.php"; it's not even clear what a "local customisation file" is!
A: The "sample-config.php" file in the "docs" folder, is given as an example. Copy it to the "local" folder and rename it to "config.php". You can then remove the "#" symbols or add other commands shown in the documentation. See also [[PerGroup Customizations]].

Q: Can I change the default page something other than Main.HomePage ($DefaultPage)?
A: Yes, just set the $DefaultPage variable to the name of the page you want to be the default.  You might also look at the $DefaultGroup and $DefaultName configuration variables.

->[@$DefaultPage = 'ABC.StartPage';@]

Q: How do I get the group / page name in a local configuration file (e.g. ''local/config.php'')?
A: Use the following markup in pmwiki-2.1.beta21 or newer:

->[@
## Get the group and page name
$pagename = ResolvePageName($pagename);
$page = PageVar($pagename, '$FullName');
$group = PageVar($pagename, '$Group');
$name = PageVar($pagename, '$Name');
@]

Q: Can I remove items from the wikilib.d folder on my site?
A: Yes, the files in ''wikilib.d/'' can be safely removed.  They'll reappear again when you upgrade, however.

Q: How do I customize my own 404 error page for non-existent pages?
A: To change the text of the message, try editing the [[Site.PageNotFound]] page.

Q: [[#configphp-order]] Is the order of customizations in config.php important?  Are there certain things that should come before or after others in that file?
A: Yes, the following has been recommended on the mailing list:

* first define any custom PageStore class, like SQLite, CompressedPageStore or PerGroupSubDirectories,
* next include_once scripts/xlpage-utf-8.php,
* next call XLPage() which needs the definitive (rw) $WikiDir already set in order to find the wiki page containing the translations,
* next include authuser.php (if needed), because PmWiki caches some group and page authorization levels when a page is accessed,
* next include any other scripts and recipes,
* any direct function call in config.php, like ResolvePageName(), PageTextVar(), PageVar(), RetrieveAuthPage(), or others, if possible, should be done near the end of config.php.

''Note, each part is '''not''' required, but if your wiki needs it, this is the recommended order in config.php.'']]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Scott Connard</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.MailingLists</pagename>
<data><![CDATA[(:Summary:The email discussion lists available and their archives:)
There are several mailing lists available for [[PmWiki]].
 
:[ [[(http://pmichaud.com/lists/)pmwiki-users]] ]: This is a great resource where a very helpful group of people will answer questions and discuss PmWiki development. Traffic is around 20-40 messages a day (on slow days). 
->''If you ask a question on the list and it doesn't get answered, don't feel let down. Just'' '''''ask it again'''''. It probably slipped by unnoticed.

->Archives are available from:
-->http://pmichaud.com/pipermail/pmwiki-users/
-->http://news.gmane.org/gmane.comp.web.wiki.pmwiki.user ([[http://search.gmane.org/search.php?group=gmane.comp.web.wiki.pmwiki.user|searchable]])
-->http://groups.google.com/group/pmwiki-users  (searchable)
-->http://www.mail-archive.com/pmwiki-users@pmichaud.com/info.html (searchable)

-->(:input form action='http://search.gmane.org/' method='get':)(:input text query:)(:input hidden group gmane.comp.web.wiki.pmwiki.user:) (:input submit value='Search pmwiki-users archives at gmane':)(:input end:)

:[ [[(http://pmichaud.com/lists/)pmwiki-users-de]] ]: A mailing list for german-speaking users of PmWiki.  Archived at
-->http://pmichaud.com/pipermail/pmwiki-users-de

:[ [[(http://pmichaud.com/mailman/listinfo/)pmwiki-users-es]] ]: Lista de usuarios PmWiki en Español.

:[ [[(http://pmichaud.com/mailman/listinfo/)pmwiki-users-fr]] ]: A mailing list for french-speaking users of PmWiki.

:[ [[(http://pmichaud.com/mailman/listinfo/)pmwiki-devel]] ]: This list was created to lower the traffic on pmwiki-users, it focuses on discussions surrounding code development for PmWiki (both core and recipe development).

->Archives are available from:
-->http://pmichaud.com/pipermail/pmwiki-devel/
-->http://news.gmane.org/gmane.comp.web.wiki.pmwiki.devel ([[http://search.gmane.org/search.php?group=gmane.comp.web.wiki.pmwiki.devel|searchable]])
-->http://groups.google.com/group/pmwiki-devel  (searchable)
-->http://www.mail-archive.com/pmwiki-devel@pmichaud.com/info.html (searchable)

:[ [[(http://pmichaud.com/lists/)pmwiki-announce]] ]: Announcements of new version releases and urgent information. If you use PmWiki in a production environment, this low-volume list is highly recommended. The archive is at:
-->http://pmichaud.com/pipermail/pmwiki-announce

Suggestions:
* If you reply to a digest message, please remove the messages irrelevant to your reply before sending it back to the list.  
** It's also helpful (but less important) to change "Re: pmwiki-users Digest, Vol [...]" to "Re: [the original subject]" because some mail programs determine threads based on the subject.
* If you address a reply to a single list member, please take the [pmwiki-users] off the subject line, or it's possible for your message to get lost in the mailing list traffic. Many people filter list traffic to a separate mailbox.

!! Changing mail list settings

Here are some tips regarding changing the mailing list settings:

* Logging in...
** First go to [[http://pmichaud.com/mailman/listinfo/pmwiki-users]]
   and enter your e-mail address in the field at the bottom of the page,
   to the left of the button ''Unsubscribe or edit options''.
** Next you need to enter your password. As you've probably forgotten this,
   use the button ''Remind'' at the bottom of the page to get a new password.
** Finally enter the password you should get momentarily via e-mail.

* You can directly go to the options web page through a URI such as the
  following:
-> [@http://host.pmichaud.com/mailman/options/pmwiki-users/<user>%40<domain>@]
-> where [@<user>@] is everything before the [@@@] in an e-mail address,
   and [@<domain>@] is everything after (
   For those who wonder, the [@%40@] in the URI just stands for '[@@@]'.

* You can also obtain various help by sending an email to
  mailto:pmwiki-users-request@pmichaud.com with the text [@help@] in either
  the subject or the body.

!! Newsgroups (NNTP)
You may be interested, that the lists are also accessible as newsgroups.

The NNTP server is:
* news.gmane.org '^[[http://news.gmane.org/search.php?match=pmwiki|#]]^'

The groups are:
* gmane.comp.web.wiki.pmwiki.user
* gmane.comp.web.wiki.pmwiki.announce
* gmane.comp.web.wiki.pmwiki.user.de
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.MarkupExpressions</pagename>
<data><![CDATA[(:Summary:String and formatting operations:)
(:Audience: authors (advanced) :)

The [@{(...)}@] "expression markup" allows for a variety of string and formatting operations to be performed from within markup.  Operations defined by this recipe include ''[[#substr|substr]]'', ''[[#ftime|ftime]]'', ''[[#strlen|strlen]]'', ''[[#rand|rand]]'', ''[[#to|toupper / tolower]]'', ''[[#ucfirst|ucfirst]]'', ''[[#ucwords|ucwords]]'', ''[[#pagename|pagename]]'' and ''[[#asspaced|asspaced]]''.

[[#substr]]
!! ''substr''

The "substr" expression extracts portions of a string.  The arguments are
# the string to be processed. Always quote the string to be processed.
# the initial position of the substring.  Note that the initial position argument is zero-based (i.e., the first character is referenced via a "0").
# the number of characters to extract
(:markup class="horiz":)
 {(substr "PmWiki" 2 3)}
 {(substr "PmWiki" 2)}
 {(substr "PmWiki" 0 1)}
 {(substr "PmWiki" 0 -3)}
 {(substr "PmWiki" -3)}
(:markupend:)

To obtain the last n characters of a string use [@{(substr "string" -n)}@]
[[<<]]
To truncate the last n characters of a string use [@(substr "string" 0 -n)}@]

[[#ftime]]
!! ''ftime''

"Ftime" expressions are used for date and time formatting.  The generic form is

->[@{(ftime "fmt" "when")}@]
->[@{(ftime fmt="fmt" when="when")}@]

where ''fmt'' is a formatting string and ''when'' is the time to be formatted.  The arguments can be in either order and may use the optional "fmt=" and "when=" labels.

Examples:
(:markup class="horiz":)
 {(ftime)}
 {(ftime fmt="%F %H:%M")}
 {(ftime %Y)}
 {(ftime fmt=%T)}
 {(ftime when=tomorrow)}
 {(ftime fmt="%Y-%m-%d" yesterday)}
 {(ftime week %F)}
 {(ftime fmt=%D month)}
 {(ftime fmt="%a%e %b" when="next week")}
(:markupend:)

The ''fmt'' parameter is whatever is given by "fmt=", the first parameter containing a '%', or else the site's default. The formatting codes are described at %newwin% http://php.net/strftime. In addition to those, '%F' produces ISO-8601 dates, and '%s' produces Unix timestamps.
Some common formatting strings:

    [= %F            =]    # ISO-8601 dates      "{(ftime %F)}"
    [= %s            =]    # Unix timestamp      "{(ftime %s)}"
    [= %H:%M:%S      =]    # time as hh:mm:ss    "{(ftime %H:%M:%S)}"
    [= %m/%d/%Y      =]    # date as mm/dd/yyyy  "{(ftime %m/%d/%Y)}"
    [= "%A, %B %d, %Y" =]  # in words            "{(ftime "%A, %B %d, %Y")}"

The ''when'' parameter understands many different date formats.  The when parameter is whatever is given by "when=", or whatever parameter remains after determining the format parameter.  Some examples:

    2007-04-11            # ISO-8601 dates
    20070411              # dates without hyphens, slashes, or dots
    2007-03               # months
    @1176304315           # Unix timestamps (seconds since 1-Jan-1970 00:00 UTC)
    now                   # the current time
    today                 # today @ 00:00:00
    yesterday             # yesterday @ 00:00:00
    "next Monday"         # relative dates
    "last Thursday"       # relative dates
    "-3 days"             # three days ago
    "+2 weeks"            # two weeks from now

'''Note:''' If you want to convert a Unix timestamp you '''must''' prefix with the @. Thus, [@"{(ftime "%A, %B %d, %Y" @1231116927)}"@].

The ''when'' parameter uses PHP's %newwin%[[(http://www.php.net/)strtotime]] function to convert date strings according to the GNU [[http://www.gnu.org/software/tar/manual/html_node/Date-input-formats.html|date input formats]]; as of this writing it only understands English phrases in date specifications.

The variable $FTimeFmt can be used to override the default date format used by the "ftime" function.  The default $FTimeFmt is $TimeFmt.

[[#strlen]]
!! ''strlen''

The "strlen" expression returns the length of a string.  The first argument is the string to be measured.

(:markup class="horiz":)
 {(strlen "{$:Summary}")}
(:markupend:)

[[#rand]]
!! ''rand''

The "rand" expression returns a random integer.  The first argument is the minimum number to be returned and the second argument is the maximum number to be returned.  If called without the optional min, max arguments rand() returns a pseudo-random integer between 0 and RAND_MAX. If you want a random number between 5 and 15 (inclusive), for example, use rand (5, 15).

(:markup class="horiz":)
 {(rand)}
(:markupend:)

[[#to]]
!! ''toupper'' / ''tolower''

The "toupper" and "tolower" expressions convert a string into uppercase or lowercase.  The first argument is the string to be processed.

(:markup class="horiz":)
 {(toupper "{$:Summary}")}
 {(tolower "{$:Summary}")}
(:markupend:)

[[#ucfirst]]
!!''ucfirst''

The "ucfirst" expression converts the first character of a string to uppercase.  The first argument is the string to be processed.

(:markup class="horiz":)
 {(ucfirst "{$:Summary}")}
(:markupend:)

[[#ucwords]]
!! ''ucwords''

The "ucwords" expression converts the first character of each word in a string to uppercase.  The first argument is the string to be processed.

(:markup class="horiz":)
 {(ucwords "{$:Summary}")}
(:markupend:)

[[#pagename]]
!! ''pagename''

The "pagename" expression builds a pagename from a string.  The first argument is the string to be processed.

(:markup class="horiz":)
 {(pagename "{$:Summary}")}
(:markupend:)

[[#asspaced]]
!! ''asspaced''

The "asspaced" expression formats wikiwords.  The first argument is the string to be processed.

(:markup class="horiz":)
 {(asspaced "{$FullName}")}
(:markupend:)

[[#nesting]]
!! Nesting expressions

Markup expressions can be nested:

(:markup class="horiz":)
 {(tolower (substr "Hello World" 2))}
(:markupend:)

[[#notes]]    
!! Notes

* Some of the string-processing markups may not work properly on UTF-8 characters or escaped sequences.
* The ftime markup does not work with some [[http://mcs.vuw.ac.nz/technical/software/SGML/doc/iso8601/ISO8601.html | ISO 8601]] dates (because a time of 24:00 [[http://gnu.org/software/tar/manual/html_node/tar_114.html | is invalid]])such as: 
(:markup class=horiz:)
 {(ftime fmt="%m/%d/%Y @ %H:%M:%S" when="20070626T2400")}
 {(ftime fmt="%H:%M:%S" when="20070626T2400")}
(:markupend:)
* is it possible to display the time in another [[http://gnu.org/software/tar/manual/html_node/tar_122.html#SEC122 | time zone]], eg
(:markup class=horiz:)
NowTime: {(ftime fmt="%F %H:%M")}
 {(ftime when='TZ=:Europe/London" ')}
 {(ftime when='TZ=Europe/London" 0 days')}
 {(ftime when="TZ='Pacific/Auckland' 2004-10-31 08:30")}
 {(ftime when='TZ="Pacific/Auckland" {$:NowTime}')}
(:markupend:)

!! See also
* [[Page variables]], [[Page text variables]]
* [[Conditional markup]]
* Cookbook:MarkupExprPlus
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.MarkupMasterIndex</pagename>
<data><![CDATA[(:title Markup Master Index:)
(:Summary:Tabulation of all PmWiki markup:)
>>rframe font-size:smaller noprint<<
'''Table of contents'''
* [[#LinkMarkups|Links]]
** [[#ExternalLinks|To external urls]]
** [[#InternalLinks|To internal pages and more]]
** [[#WikiPageLinks|To wiki pages]]
** [[#SpecialGroupLinks|To Special Groups]]
** [[#IntermapLinks|To Intermap Destinations]]
** [[#UploadLinks|To uploaded files]]
** [[#EmailLinks|To email addresses]]
* [[#Images|Images]]
** [[#ImagesAsImages|as images]]
** [[#ImagesAsLinks|as links]]
* [[#StartOfLine|Start-of-line markup]]
** [[#Lists|Lists]]
** [[#Headings|Headings]]
** [[#BlockMarkups|Paragraph blocks]]
** [[#DivisionBlocks|Division blocks]]
* [[#Text|Text]]
** [[#InlineMarkups|Character format]]
** [[#PostingMarkups|Posting markup]]
* [[#Tables|Tables]]
** [[#PlainTables|Plain tables]]
** [[#TablesAndDivs|Structured tables]]
* [[#Directives|Directives]]
** [[#PageDirectives|Page directives]]
** [[#Display|Display]]
** [[#Metadata|Metadata]]
** [[#IncludeOtherPages|Include other pages]]
** [[#ConditionalMarkup|Conditional markup]]
** [[#PageLists|Page lists]]
** [[#OtherDirectives|Other directives]]
* [[#Forms|Forms]]
** [[#Forms|Forms]]
** [[#EditForms|Edit Forms]]
* [[#WikiTrails|WikiTrails]]
* [[#PageVariables|Page variables]]
* [[#Expressions|Expressions]]
>><<
This page contains the most frequently used wiki markup, briefly. Follow the links in each section to learn more.

!! [[#LinkMarkups]] Links

See [[Links]]
!!![[#ExternalLinks]]External links
-< [@http://example.com@]
-< [@ [[http://example.com]] @]
-< [@ [[http://example.com | link text]] @]
-< [@ [[link text -> http://example.com]] @]

[[#InternalLinks]]
!!! Page links
-< [@ [[PageName]] @]
-< [@ [[page name]] @]
-< [@ [[page (name)]] @]
-< [@ [[PageName | link text]] @]
-< [@ [[PageName | + ]] @] ''(titled link)''
-< [@ [[PageName | # ]] @] ''(anonymous numerical reference link)''
-< [@ [[link text -> PageName]] @]
-< [@ [[#anchor]] @] ''(to create an anchor)''
-< [@ [[#anchor | link text]] @] ''(to refer to an anchor)''
-< [@ [[PageName#anchor | link text]] @] ''(to refer to an anchor in another page)''

[[#WikiPageLinks]]
!!! Wiki page links
See [[Wiki word]] and [[Wiki group]]
-< [@WikiWord@]
-< [@`NonWikiWord@]
-< [@Group/PageName@]
-< [@Group.PageName@]
-< [@ [[GroupName/]] @]
-< [@ [[GroupName.]] @]

[[#SpecialGroupLinks]]
!!! Special group links
See [[Links]] and [[Categories]] 
-< [@ [[~Author Name]] @]
-< [@ [[!Category Name]] @]

[[#IntermapLinks]]
!!! Intermap links
See [[Inter map]]
-< [@ [[Path:/path/local_document.html]] @]
-< [@ [[Wikipedia:WikiWikiWeb]] @]

[[#UploadLinks]]
!!! Upload links
See [[Uploads]]
-< [@ [[Attach:file with spaces.pdf]] @]
-< [@ [[Attach:Groupname/file with spaces.pdf]] @]

[[#EmailLinks]]
!!! Email links
-< [@ [[mailto:someone@example.com]] @]
-< [@ [[mailto:someone@example.com | display text]] @]
-< [@ [[display text -> mailto:someone@example.com]] @]

!! [[#Images]] Images

See [[Images]] and [[Uploads]]
!!! [[#ImagesAsImages]] Images as Images
-< [@http://example.com/image.gif@]
-< [@http://example.com/image.gif"alt text"@]
-< [@Attach:image.gif"My image"@]
-< [@Attach:Groupname/image.gif"image in another group"@]
-< [@Attach:Groupname.Pagename/image.gif"image on another page"@]
-< [@%lfloat% Attach:image.gif@]
-< [@%rfloat% Attach:image.gif@]
-< [@%center% Attach:image.gif@]
-< [@%rframe% Attach:image.gif | Caption@]
-< [@%lframe% Attach:image.gif | Caption@]
-< [@%width=200px% Attach:image.gif@]
-< [@%thumb% Attach:image.gif@]

!!! [[#ImagesAsLinks]] Images as links

-< [@ [[Attach:image.gif]] @]
-< [@ [[(Attach:)image.gif]] @]
-< [@ [[PageName | Attach:image.gif"alt text"]] @]
-< [@ [[http://example.com/ | Attach:image.gif"alt text"]] @]
-< [@%rframe thumb% [[Attach:image.gif | Attach:image.gif"alt text"]] | Caption @]

!! [[#StartOfLine]] Start-of-line markup

See [[Text formatting rules]]

!!! [[#Lists]] [[PmWiki/TextFormattingRules#BulletedLists| Lists]]

See [[(PmWiki:)List Styles]], [[Wiki styles]] and [[Cookbook:Outline lists]]
-< [@* unordered list@]
-< [@** deeper list@]
-< [@# ordered list@]
-< [@# %item value=#%@] arbitrary start number
-< [@# %decimal%, %roman%, %ROMAN%, %alpha%, %ALPHA% @]
-< [@:term:definition@]
Also
-< [@Q:@] start a question paragraph
-< [@A:@] start an answer paragraph

!!! [[#Headings]] Headings

-< [@!! Heading@]
-< [@!!! Deeper heading@]

!!! [[#BlockMarkups]] Paragraph blocks

-< [@-> indented text@]
-< [@-< hanging indent@]
-< [@<space> preformatted text@]
-< @@[=[@...@]=]@@ preformatted block
-< [@----@] (horizontal rule)
-< [@blank line@] is vertical space
-< [@\@] at end of line joins next line
-< [@\\@] at end of line produces a line break
-< [@\\\@] at the end of a line produces a blank line, even within a list item
-< [@ [[<<]] @] produces a line break that clears floating content

!!! [[#DivisionBlocks]] Division blocks

See [[Wiki styles]] and [[Page directives]]
-< [@>>wikistyle<<@]
-> [@ (:div attr:) @]
-> [@ (:divend:) @]
-< [@>><<@]

!! [[#Text]] Text markup

See [[Text formatting rules]]
!!! [[#InlineMarkups]] Character format

-< [@''emphasized''@] 
-< [@'''strong'''@]
-< [@'''''strong emphasis'''''@]
-< [@'~italic~'@] [-''(if enabled in config.php)''-]
-< [@'*bold*'@] [-''(if enabled in config.php)''-]
-< [@@@monospaced@@@]
-< [@[-small-], [--smaller--]@]
-< [@[+big+], [++bigger++]@]
-< [@'-small-', '+big+'@]
-< [@'^superscript^', '_subscript_'@]
-< [@{+inserted+} (underscore)@]
-< [@{-deleted-} (strikethrough)@]
-< @@[=[@escaped code@]=]@@
-< [@[=escaped text=]@]

!!! [[#PostingMarkups]] Posting markup

-< @@~~@@@@~@@ (author's signature)
-< @@~~@@@@~~@@ (author's signature and date)
-< @@[=(:encrypt=] ''phrase''[=:)=]@@ -- replaced with encrypted form of ''phrase''

!! [[#Tables]] Tables

!!!  [[#PlainTables]] Plain rows and columns of text

See [[Tables]]
-< [@||table attributes@]
-< [@||!table caption!||@]
-< [@||left aligned  || centered ||  right aligned||@]
-< [@||!column heading||@]
-< [@||spanned columns ||||||@]

!!! [[#TablesAndDivs]]  Structured tables

See [[Table directives ]]
-< [@ (:table attr:) @]
-< [@ (:cellnr attr:) @]
-< [@ (:cell attr:) @]
-< [@ (:tableend:) @]

!! [[#Directives]] Directives

!!! [[#PageDirectives]] Page directives

See [[Page directives]]
-< [@ (:redirect PageName:) @]

-< [@ (:(no)spacewikiwords:) @]
-< [@ (:(no)linkwikiwords:) @]
-< [@ (:(no)linebreaks:) @]
-< [@ (:nl:) @] insert newline in the *markup* only if one isn't present.  The purpose of [@ (:nl:) @] is to be able to write things like:
--> [@ (:include Page1:)(:nl:)(:include Page2:) @]
-> which guarantees that the first line of Page2 is treated as a separate line from the last line of Page1, but without inadvertently generating a blank line between them.

!!! [[#Display]] Display

See [[Page directives]] [[Group headers]]
-< [@ (:noheader:), (:nofooter:) @]
-< [@ (:notitle:) @]
-< [@ (:noleft:), (:noright:) @]
-< [@ (:nogroupheader:), (:nogroupfooter:) @]
-< [@ (:noaction:) @]

!!! [[#Metadata]] Metadata

See [[Page directives]], [[(PmWiki:)Comment markup]],  [[Page text variables]]
-< [@ (:title text:) @]
-< [@ (:keywords word, ...:) @]
-< [@ (:description text:) @]
-< [@ (:comment text:) @]
-< [@{Group/PageName$:Var}@] [-includes from [@ (:name:text:) @]-]

!!! [[#IncludeOtherPages]] Include

See [[Include other pages]], [[Page text variables]]
-< [@ (:include PageName:) @]
-< [@ (:include PageName #start#end lines=n paras=n:) @]
-< [@ (:include Page1 Page2 Page3:) @]
-< [@{Group/PageName$:Var}@] [-includes from [@ (:name:text:) @]-]

!!! [[#ConditionalMarkup]] Conditional markup

See [[Conditional markup]]
-< [@ (:if (!)@] ''cond param''[@:)...(:ifend:)@]
-< [@ (:if (!)@] ''cond param''[@:)...(:else:)...(:ifend:)@]
-< [@ (:if (!)@] ''cond param''[@:)...(:elseif (!)@] ''cond param''[@:)...(:ifend:) @]

!!! [[#PageLists]] Pagelists

See [[Page lists]]
-< [@ (:searchbox label=label order=-time:) @]
-< [@ (:searchresults incl -excl group=abc fmt=def:) @]
-< [@ (:pagelist incl -excl group=abc fmt=def:) @]

!!! [[#OtherDirectives]] Other directives

See [[Page directives]]
-< [@ (:@][[PageDirectives#attachlist|attachlist]][@:) @]
-< [@ (:@][[PageDirectives#markup]][@:) @] [@ [=...=] @]
-< [@ (:markup:)...(:markupend:) @]
-< [@ (:markup class=horiz:)...(:markupend:) @]
-< [@ (:markup caption='...':)...(:markupend:) @]

!! [[#Forms]] Forms

See [[PmWiki/Forms]]
-< [@ (:input form method=get action=url enctype=multipart/form-data:) @]
-< [@ (:input end:) @]
-< [@ (:input text name=first value="Bob" size=20:) @]
-< [@ (:input submit name=post value="Go" accesskey=g:) @]
-< [@ (:input reset:) @]
-< [@ (:input hidden name=action value=edit:) @]
-< [@ (:input radio name=xyz value="abc" checked=1:) @]
-< [@ (:input checkbox name=xyz value="abc" checked=1:) @]
-< [@ (:input password name=authpw:) @]
-< [@ (:input file name=upload:) @]
-< [@ (:input image name=xyz src="http:..." alt="Alt Text":) @]
-< [@ (:input select name=xyz value="val1" label="Value 1":) @]
-< [@ (:input select name=xyz value="val2" label="Value 2":) @]
-< [@ (:input default name=xyz value="abc":) @]

!!! [[#EditForms]] Edit forms

See [[PmWiki/Forms#pageeditcontrols]]
-< [@ (:messages:) @]
-< [@ (:input e_form:) @]
-< [@ (:e_guibuttons:) @]
-< [@ (:e_preview:) @]
-< [@ (:input e_textarea rows=24 cols=60:) @]
-< [@ (:input e_author value={$Author} size=40:) @]
-< [@ (:input e_changesummary value="Summary" size=60:) @]
-< [@ (:input e_savebutton value=$[Save]:) @]
-< [@ (:input e_saveeditbutton value=$[Save and edit]:) @]
-< [@ (:input e_previewbutton value=$[Preview]:) @]
-< [@ (:input e_resetbutton value=$[Reset]:) @]

!! [[#WikiTrails]] Wiki trails

See [[Wiki trails]]
-< [@<<|[[TrailPage]]|>>@]
-< [@<|[[TrailPage]]|>@]
-< [@^|[[TrailPage]]|^@]

!! [[#PageVariables]] Page variables

See [[Page variables]], [[Page text variables]], [[PmWiki/PageLists#pagetextvariables|Page lists]]
-< [@ {@]''[@$variable@]''[@} @]
-< [@ {@]''[@pagename$variable@]''[@} @]
-< [@ (:name:description:) @] [-sets a [[page text variable(s)]]-]

!! [[#Expressions]] Expressions

See [[Markup expressions]]
-< [@ {(@]''[@function args@]''[@)} @]

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Notify</pagename>
<data><![CDATA[(:Summary:Allows a site administrator to configure PmWiki to send email messages whenever pages are changed on the wiki site:)
(:Audience: administrators (basic) :)
The ''notify.php'' script allows a site administrator to configure PmWiki to send email messages whenever pages are changed on the wiki site.  Notifications can be configured so that multiple page changes over a short period of time are combined into a single email message (to avoid flooding mailboxes).

This feature is useful for sites and pages that have infrequent updates, as it eliminates the need to frequently check `RecentChanges pages just to see if anything has changed.

In order for notifications to work, the notify.php script must be enabled in the site's [[local customization(s)]].  Usually this is as simple as placing the following in ''local/config.php'':

->$EnableNotify = 1;

If you have safe_mode enabled in your PHP configuration, notify.php will fail silently. See the [[PITS:00976]] for a little hack that fixes the issue.

!! Notification configuration
Once enabled, the notification system gets its configuration from the [[SiteAdmin.NotifyList]] wiki page.  The SiteAdmin.NotifyList page contains entries of the form:

->notify=alice@example.com

This says that information about page changes should be periodically emailed to ''alice@example.com''.  The SiteAdmin.NotifyList page can contain multiple "notify=" lines to cause notifications to be sent to multiple addresses; the "notify=" lines can be concealed by placing them inside of an [@(:if false:)@] conditional section on the page.

NOTE: Do not put any spaces around the equal sign! Notifications will fail silently if you have
->notify = fred@example.com
rather than
->notify=fred@example.com
(:comment this is a really easy mistake to make because all of the other assignments have spaces around the equal sign.:)

!! Notification options
The basic syntax is 
->@@notify=''email@address'' \
  [[#notifyname|name]]=''abc'' \
  [[#notifygroup|group]]=''def''  \
  [[#notifytrail|trail]]=''ghi'' \
  [[#notifysquelch|squelch]]=''123'' \
  [[#notifydelay|delay]]=''123'' \
  @@

A number of options exist for limiting the pages that result in a notification.  The [@group=@] and [@name=@] parameters can be used to restrict notifications to specific pages or groups:

[[#notifygroup]]
-># send notifications about the Main group to alice@example.com
->notify=alice@example.com '''group'''=Main

[[#notifyname]]
-># notify bob@example.com of any changes to the home page
->notify=bob@example.com '''name'''=Main.HomePage

-># notify charles@example.com of changes to pages except in Main
->notify=charles@example.com '''group'''=-Main

(Note: The options are similar to [[PmWiki/PageLists | the PageList syntax]].)

[[#notifytrail]]
For maintaining arbitrary lists of pages, i.e., "watchlists", it's generally easier to build a [[trail -> WikiTrails]] of pages to be watched.  The following entry in SiteAdmin.NotifyList will send alice@example.com an email containing changes to any of the pages listed in the Profiles.Alice trail:

-># notify Alice of changes to pages listed in Profiles.Alice
->notify=alice@example.com '''trail'''=Profiles.Alice

Note that once this entry has been added to SiteAdmin.NotifyList, Alice can easily change her watchlist by editing the Profiles.Alice page, and doesn't need to edit the SiteAdmin.NotifyList page.  In particular, this means that an administrator can restrict editing of SiteAdmin.NotifyList, yet allow individuals to maintain custom watchlists in other pages. 

Limitations of this feature:
* only manually-added links on a trail will be acknowledged by the Notify List (no "group=" or other pagelist syntax, nor any "Group.RecentChanges" links, will generate notifications)
* using an [@(:include:)@] directive on the page SiteAdmin.NotifyList is not an operational work-around.

This is probably a good place to point out that edit access to SiteAdmin.NotifyList should be controlled, otherwise malicious persons can use the notification capability to flood others' electronic mailboxes.  By default, SiteAdmin.Notify is blocked against reading or edits except by the admin (as is the case for most pages in the SiteAdmin group).

!! Adding notification entries via local customizations

Notification entries can also be added via the $NotifyList array in ''local/config.php''.  Simply add a line like the following:
->$EnableNotify = 1;
->$NotifyList[] = 'notify=alice@example.com group=Main';
->$NotifyList[] = 'notify=bob@example.com name=Main.HomePage';

[[#controlling_notification_frequency]]
[[#notifysquelch]]
!! Controlling notification frequency

To prevent flooding of recipients' mailboxes, the notify script uses a "'''squelch'''" value as the minimum amount of time that must elapse between messages sent to any given email address.  The ''default squelch setting is 10800 seconds (three hours)'', which means that once a recipient address is sent a notification message, it will not receive another for at least three hours.  Any edits that occur during the squelch interval are queued for the next notification message.

The site administrator can change the default squelch interval via the $NotifySquelch parameter 

-># enable notifications
->$EnableNotify = 1;
->$NotifySquelch = 86400;    # wait at least one day (in seconds) between notifications

In addition, individual addresses can specify a custom squelch parameter in the SiteAdmin.NotifyList page:

-># Alice receives at most one email per day
->notify=alice@example.com '''squelch'''=86400

-># Bob can get notifications hourly
->notify=bob@example.com trail=Profiles.Bob '''squelch'''=3600

-># Charles uses the site default squelch
->notify=charles@example.com 

[[#notifydelay]]
!! Controlling notification delay
Because a page will often receive several edits in rapid succession (e.g., a long post followed by several minor edits), a site administrator can also set a $NotifyDelay value that specifies how long to wait after an initial post before sending notifications:

-># enable notifications
->$EnableNotify = 1;
->$NotifySquelch = 86400;    # wait at least one day between notifications
->$NotifyDelay = 300;        # wait five minutes after initial post

Note that the squelch and delay values are minimums; notifications are sent on the first execution of PmWiki after the delay period has expired.  For inactive sites, this could be much longer than the specified delay periods.  This isn't really considered an issue since timely notifications are less important on relatively inactive sites. However, changes within the squelch time after the last notification will remain unnoticed if the wiki is not even visited for a long period after. If this matters it might be necessary to make the server call pmwiki.php regularly (e.g. [[Wikipedia:Cron | cron job]]).

Custom delay parameters cannot be specified for individual addresses in the [[SiteAdmin.NotifyList]] page:

-># the @@delay=@@ parameter will be ignored
->notify=edgar@example.com trail=Profiles.Edgar '''delay'''=600

!! Note for Windows installations

Sites running PHP under Windows may not have PHP's [[http://php.net/mail | mail]] function configured correctly.  Such sites may need to add a line like

->ini_set('SMTP','smtp.server.com');

to ''config.php'', where ''smtp.server.com'' is the name of your host's preferred outgoing mail server. You may also need to set the sendmail_from value if that is not configured:

->ini_set('sendmail_from','noreply@foo.com');

!![[#variables]] Notify Variables

:$EnableNotify:Tells ''stdconfig.php'' to enable the notify script.
: :$EnableNotify = 1;          # enable notify
: :$EnableNotify = 0;          # disable notify

:$NotifyFrom:Return email address to be used in the sent email.
: :$NotifyFrom = 'wiki@example.com';
: :$NotifyFrom = 'Wiki server <wiki@example.com>';

:$NotifyDelay:The length of time (seconds) to wait before sending mail after the first post.  Defaults to zero - posts are sent as soon as any squelch period has expired.
: :$NotifyDelay = 300;    # send mail 5+ min after first post

:$NotifySquelch:The default minimum time (seconds) that must elapse between sending mail messages.  Useful when $NotifyDelay is set to a small value to keep the number of mail notification messages down.  Defaults to 10800 (three hours).  Individual recipients can override this value in the SiteAdmin.NotifyList page.
: :$NotifySquelch = 43200;  # wait 12+ hours between mailings

:$NotifyItemFmt:The text to be sent for each changed item in the post.  The string "$PostTime" is substituted with the time of the post (controlled by $NotifyTimeFmt below).
: :# default
: :$NotifyItemFmt = ' * $FullName . . . $PostTime by $Author';

: :# include the page's URL in the message
: :$NotifyItemFmt =
: :" * \$FullName . . . \$PostTime by \$Author\n     \$PageUrl";

: :# include the change summary and link to the page's history in the message
: :$NotifyItemFmt = 
: :" * {\$FullName} . . . \$PostTime by {\$Author}
: :\n    Summary: {\$LastModifiedSummary}\n    {\$PageUrl}?action=diff";

:$NotifyTimeFmt:The format for dates/times in $PostTime above.  Defaults to the value of $TimeFmt.
: :$NotifyTimeFmt = [='%Y-%m-%d %H:%M'=];  # 2004-03-20 17:44

:$NotifyBodyFmt:The body of the message to be sent.  The string "$NotifyItems" is replaced with the list of posts (as formatted by $NotifyItemFmt above). Use single quotation marks ' to prevent substring "$NotifyItems" from being untimely evaluated as variable in config.php. 
: :$NotifyBodyFmt = "Changed items:\n\n" . '$NotifyItems' . "\n\n Best regards...";

:$NotifySubjectFmt:The subject line of the mail to be sent.

:$NotifyHeaders:String of extra mail headers to be passed to the mail() function.

:$NotifyParameters:String of additional parameters to be passed to PHP's mail() function [[http://www.php.net/mail|#]].

:$NotifyFile:The scratch file where Notify keeps track of recent posting information.  Defaults to @@[="$WorkDir/.notifylist"=]@@.  Note that this file must generally be writable by the webserver process.

:$NotifyListPageFmt:The name of the page containing [@notify=@] lines for use by ''notify.php''.  Defaults to [@$SiteAdminGroup.NotifyList@].

:$NotifyList:An array of [@notify=@] specifications that can be specified from a local customization file (used in addition to entries in SiteAdmin.NotifyList).
: :# send notifications to alice@example.com
: :$NotifyList[] = 'notify=alice@example.com';

:$EnableNotifySubjectEncode:Apply a standard (base64) encoding for the e-mail subject. Notify e-mails from international wikis may otherwise have unreadable subjects (added for version 2.2.2).
: :$EnableNotifySubjectEncode = 1;          # encode subject
: :$EnableNotifySubjectEncode = 0;          # use subject as is (default)
: : To fix encodings with the message body, add to config.php the following line (after XLPage and/or [[UTF-8]]):\\
    @@$NotifyHeaders = "Content-type: text/plain; charset=$Charset";@@

!! Notification only for major edits

It is possible to send notifications only in case of major edits. In your config.php, recplace "$EnabelNotify=1;" with the following:  

if ( @$_POST['diffclass'] != 'minor' ) $EnableNotify=1;

This way, only 'major' edits send notify messages (when the author doesn't select the checkbox for minor edit). If you want minor edits and not major edits to send the message then you would use:

if ( @$_POST['diffclass'] == 'minor' ) $EnableNotify=1;

instead. 
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.OtherVariables</pagename>
<data><![CDATA[(:Summary:Variables not yet classified:)
[[#FmtV]]
:$FmtV: 
: :This variable is an array that is used for string substitutions at the end of a call to @@[[FmtPageName]]()@@. For each element in the array, the "key" (interpreted as a string) will be replaced by the corresponding "value".  The variable is intended to be a place to store substitution variables that have frequently changing values (thus avoiding a rebuild of the variable cache making @@[[FmtPageName]]()@@ faster). Also see $FmtP. %green%''Values of $FmtV are set by the internal functions FormatTableRow, LinkIMap, HandleBrowse, PreviewPage, HandleEdit, PmWikiAuth, and PasswdVar, apparently to set values for system generated string substitutions like PageText.''%%

[[#FmtP]]
:$FmtP:
: :This variable is an array that is used for pattern substitutions near the beginning of a call to [@FmtPageName@]. For each element in the array, the "key" (interpreted as a pattern) will be replaced by the corresponding value evaluated for the name of the current page. This is for instance used to handle $-substitutions that depend on the pagename passed to [@FmtPageName()@].  Also see $FmtV. %green%From robots.php: ''If $EnableRobotCloakActions is set, then a pattern is added to $FmtP to hide any "?action=" url parameters in page urls generated by PmWiki for actions that robots aren't allowed to access.  This can greatly reduce the load on the server by not providing the robot with links to pages that it will be forbidden to index anyway.''

[[#FmtPV]]
:$FmtPV:
: :This variable is an array that is used for defining [[Page Variables]]. New variables can be defined with [@$FmtPV['$VarName'] = 'variable definition';@] which can be used in markup with [@{$VarName}@]. Please note that the contents of [@$FmtPV['$VarName']@] are [@eval()@]ed to produce the final text for [@$VarName@], so the contents must be a PHP expression which is valid at the time of substitution. In particular, %red%this does not work:%%

:: :%red%[@#This doesn't work@]%%
:: :[@$FmtPV['$MyText'] = "This is my text."; # WARNING: Doesn't work!@]

: :The problem is that the text %blue%[@This is my text.@]%% is not a valid PHP expression. To work it would need to be placed in quotes, so that what actually gets stored in [@$FmtPV['$MyText']@] is %blue%[@"This is my text."@]%% which '''is''' a valid PHP expression for a text string. Thus the correct way to do this would be with an extra set of quotes:

:: :[@#This will work@]
:: :[@$FmtPV['$MyText'] = '"This is my text."';@]

: :This also has implications for how internal PHP or PmWiki variables are accessed. To have the page variable [@$MyVar@] produce the contents of the internal variable [@$myvar@], many folks try the following %red%which does not work:%%

:: :%red%[@#This doesn't work either!@]
:: :[@$myvar = SomeComplexFunction();@]
:: :[@$FmtPV['$MyVar'] = $myvar; # WARNING: Doesn't work!@]

: :There are several correct ways to do this, depending on whether you need the value of the [@$myvar@] variable as it was at the time the [@$FmtPV@] entry was created, or at the time that a particular instance of [@$MyVar@] is being rendered on a page. For most simple page variables that don't change during the processing of a page its more efficient to set the value when the entry is created:

:: :[@$myvar = SomeComplexFunction();@]
:: :[@$FmtPV['$MyVar'] = "'" . $myvar . "'"; #capture contents of $myvar@]

: :NOTE: If [@$myvar@] should contain single quotes, the above won't work as is, and you'll need to process the variable to escape any internal quotes.

: :For more complex cases where an internal variable may have different values at different places in the page (possibly due to the effects of other markup), then you need to make the [@$FmtPV@] entry make an explicit reference to the global value of the variable (and the variable had better be global) like this:

:: :[@global $myvar;@]
:: :[@$FmtPV['$MyVar'] = '$GLOBALS["myvar"]';@]

: :Finally, there's nothing to stop you from simply having the evaluation of the [@$FmtPV@] entry execute a function to determine the replacement text:

:: :[@# add page variable {$Today}, formats today's date as yyyy-mm-dd@]
:: :[@$FmtPV['$Today'] = 'strftime("%Y-%m-%d", time() )';@]

: :See [[Cookbook:MoreCustomPageVariables]] for more examples of how to use [@$FmtPV@].

:$MaxPageTextVars: This variable prevents endless loops in accidental recursive [[PageTextVariables]] which could lock down a server. Default is 500 which means that each PageTextVariable from one page can be displayed up to 500 times in one wiki page.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PageDirectives</pagename>
<data><![CDATA[(:description PmWiki Page Directives:)(:Summary: Directives to specify page titles, descriptions, keywords, and display:)(:Keywords description, keywords, markup, header, redirect:)
PmWiki uses a number of directives to specify page titles, descriptions, page keywords, and control the display of various components.
Keywords are not case sensitive.

[[#attachlist]]
:[@(:attachlist:)@]:
->Shows a list of attachments of the current group or page, depending on whether attachments are organised per group or per page. The attachlist is displayed at the foot of the [[uploads]] page form.
->The parameter to [=(:attachlist:)=] always resolves to a pagename. The directive then displays all of the attachments currently available for that page.

::Options: [@(:attachlist NAME:)@] shows a list of attachments of the group or page NAME. 
-->[@(:attachlist ext=xxx:)@] specifies an extension for filtering by type of file. 
-->[@(:attachlist *:)@] shows the uploads directory and permits browsing of all uploaded files by directory (''will not work if $EnableDirectDownload is set to 0'').

[[#description]]
:[@(:description text:)@]:Descriptive text associated with the page.  (Generates a [@<meta name='description' content='...' />@] element in the page output.)

[[#keywords]]
:[@(:keywords word1, word2, ...:)@]:Identifies keywords associated with the page.  These are not displayed anywhere, but are useful to help search engines locate the page.  (Essentially, this generates a [@<meta name='keywords' content='...' />@] element in the output.)

[[#linebreaks]]
:[@(:linebreaks:)@], [@(:nolinebreaks:)@]: Honors any newlines in the markup; i.e., text entered on separate lines in the markup will appear as separate lines in the output.  Use [@(:nolinebreaks:)@] to cause text lines to automatically join again.

[[#linkwikiwords]]
:[@(:linkwikiwords:), (:nolinkwikiwords:)@]: Enables/disables WikiWord links in text.

[[#markup]]
:[@(:markup:) ... (:markupend:)@] or [@(:markup:)@][@[=...=]@]: Can be used for markup examples, showing first the markup and then the result of the markup.  

::Options: [@(:markup class=horiz:)@] will show the markup side by side instead of one upon the other.
-->[@(:markup caption='...':)@] adds a caption to the markup example.
-->[@(:markupend:)@] is not required when using [@(:markup:)@] [@[=...=]@].

->''Note'' that the placement of newlines is very important for this markup.  If you are using the [@[=...=]@] option then the opening [@[=@] MUST occur on the same line as the [@(:markup:)@].  If you are using the full [@(:markup:) ... (:markupend:)@] form then your markup code must appear AFTER a newline after the initial [@(:markup:)@].

[[#noaction]]
:[@(:noaction:)@]: Turns off the section of the skin marked by <!--PageActionFmt--> thru <!--/PageActionFmt-->.  In the pmwiki skin, this turns off the display of the actions at the top-right of the page (other skins may locate the actions in other locations).

[[#nogroupheader]]
:[@(:nogroupheader:)@]:
:[@(:nogroupfooter:)@]: Turns off any groupheader or groupfooter for the page.  (See [[GroupHeaders]].)

[[#noheader]]
:[@(:noheader:), (:nofooter:)@]: 
:[@(:noleft:), (:noright:), (:notitle:)@]: If supported by the [[skin(s)]], each of these turns off the corresponding portion of the page.

[[#redirect]]
:[@(:redirect PageName:)@]: Redirects to another wiki page.
:[@(:redirect PageName#anchor:)@]: Redirects to an [[PmWiki/Links#anchors|anchor]] within a page
:[@(:redirect PageName status=301 from=name quiet=1:)@]:Redirects the browser to another page, along with a redirect message.  For security reasons this only redirects to other pages within the wiki and does not redirect to external urls.  The [@status=@] option can be used to return a different HTTP status code as part of the redirect.  The [@from=@] option limits redirects to occuring only on pages matching the wildcarded ''name'' (helpful when [@(:redirect:)@] is in [[include other pages|another page]]). The [@quiet=1@] option allows the target page not to display a link back to the original page ($EnableRedirectQuiet variable should be set to 1).

[[#spacewikiwords]]
:[@(:spacewikiwords:), (:nospacewikiwords:)@]:
->Enables/disables automatic spacing of WikiWords in text.

[[#title]]
:[@(:title text:)@]: Sets a page's title to be something other than the page's name.  The title text can contain apostrophes and other special characters.  If there are multiple titles in a page, the last one encountered wins.

[[#nl]]
:[@(:nl:)@]:Creates a new line if there isn't one already there. See [[http://thread.gmane.org/gmane.comp.web.wiki.pmwiki.user/15031/focus=15079 | this thread]] for more info.
: : Similar to [@[[<<]]@]

>>faq<< [[#faq]]
Q: Can I get [@(:redirect:)@] to return a "moved permanently" (HTTP 301) status code?
A: Use [@(:redirect PageName status=301:)@].

Q: Is there any way to prevent the "redirected from" message from showing at the top of the target page when I use [@(:redirect:)@]?
A: From version 2.2.1 on, set in config.php @@$EnableRedirectQuiet=1;@@ and in the page @@[=(:redirect OtherPage quiet=1:)=]@@ for a quiet redirect.

Q: Is there any method for redirecting to the equivalent page in a different group, i.e. from BadGroup/thispage => GoodGroup/thispage using similar markup to (:redirect Goodgroup.{Name}:)?
A:
->[=(:redirect Goodgroup.{$Name}:)=] works if you want to put it in one page. 

->If you want it to work for the entire group, put [=(:redirect Goodgroup.{*$Name}:)=] into Badgroup.GroupHeader - however, that only works with pages that really exist in Goodgroup; if you visit a page in Badgroup without a corresponding page of the same name in Goodgroup, instead of being redirected to a nonexistant page, you get the redirect Directive at the top of the page.

->With [=(:if exists Goodgroup.{*$Name}:)(:redirect Goodgroup.{*$Name}:)(:ifend:)=] in Badgroup.GroupHeader you get redirected to Goodgroup.Name if it exists, otherwise you get Badgroup.Name without the bit of code displayed.]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PageFileFormat</pagename>
<data><![CDATA[(:Summary:Create wiki formatted pages in bulk and for upload to your pmwiki site:)
You may have many documents that you would like to use a local program to format in a format PmWiki can display.

You could open each document and copy/paste the content to new pmwiki pages or you could format the document in advance and upload it using a FTP client.

Only two lines are necessary in a PmWiki page file:

->[@
version=pmwiki-2.1.0 urlencoded=1
text=Markup text
@]

"version=" tells PmWiki that the values are urlencoded.  The actual value doesn't matter, as long as "urlencoded=1" appears somewhere in the line.

"text=" ''needs'' to have the markup text with newlines converted to "%0a" and percent signs converted to "%25".

-> In addition, ''PmWiki writes'' pages with '<' encoded as "%3c" (to help with security), but it doesn't require that <'s be encoded that way in order to be able to read the page. More conversions are possible to be added in the future.

In order to let the [@(:pagelist :)@] markup work, make sure the filename begins with an uppercase letter.

In order to have the [@(:pagelist link= ... :)@] markup on other pages list this page, a third attribute is required:

->[@
targets=GroupName1.Pagename1,GroupName2.Pagename2,...
@]

"targets=" is a comma delimited list of all links from the current page.

----

Keys you could see in a raw PmWiki file:

:'''version''': Version of PmWiki used to create the file %comment% More??? (ordered, urlencoded)%%
:'''agent''': Author's browser when saving the page
:'''author''': Last author to save page
:'''charset''': The character encoding of the page text, may be used by future upgrades
:'''csum''': Change summary
:'''ctime''': Page creation time
:'''host''': Host created this page
:'''name''': Name of the page (e.g., [@Main.WikiSandbox@])
:'''rev''': Number of times the page has been edited
:'''targets''': Targets for links in the page
:'''text''': The page's wiki markup
:'''time''': Time the page was last saved (seconds since 1 Jan 1970 00:00 UTC)
:'''title''': Page title set via [@(:title The Page Title:)@].
:'''newline''': Character used for newlines (deprecated)
:'''passwdedit''': encrypted version of the password

Below these you will see information used to keep track of the page's revision history.

!![[#creating]] Creating a Page for Distribution

A simple way to create a wikipage file to use for distribution (for example with a recipe or a skin) is to create the page with PmWiki and then use a text editor to delete all lines but ''version'', ''text'', and ''ctime''.  Example:

->[@
version=pmwiki-2.1.0 ordered=1 urlencoded=1
text=This is a line.%0aThis is another.
ctime=1142030000
@]

!! Keeping track of page history

Inside of a page file, PmWiki stores the latest version of the markup text, and uses this to render the page.  The page history is kept as a sequence of differences between the latest version of the page and each previous version.

PmWiki normally puts the page history at the end of each page file in reverse chronological sequence, and sets the "ordered=1" items in the header.  If an operation needs only the most recent version of a page, then PmWiki will stop reading and processing a page file at the point where the history begins, potentially saving a lot of time and memory.  If the "ordered=1" flag isn't present, PmWiki makes no assumptions about the ordering of items in the pagefile and processes the entire file.

!! Load pages from text files
See [[Cookbook: Import text]]. {Cookbook/ImportText$:Summary}

!! Unix utility to extract wiki text

The following unix script (tested on MacOSX) will extract and decode the current text from a wiki file:

->[@
#!/bin/tcsh
# wtext - extract wiki text
#
# wtext wikifile > output

set fn = "$1"
if ("$fn" == "") then
  echo "need input file parameter"
  exit 999
endif
if (! -f $fn) then
  echo "$fn does not exist"
  exit 999
endif
rm sedin.$$ >& /dev/null
set ch = `grep ^newline= $fn | cut -d= -f2`
if ("$ch" == "") set ch = "%0a"
cat <<eof > sedin.$$
s/^text=//
s/$ch/\
/g
s/%3c/</g
s/%25/%/g
eof
grep "^text=" "$1" | sed -f sedin.$$
rm sedin.$$ >& /dev/null
@]

!!See also
* Cookbook:AdminByShell

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PageHistory</pagename>
<data><![CDATA[(:Summary: History of previous edits to a page:)
(:Audience: authors (basic) :)
When PmWiki is called with '?action=diff', it displays a summary of past edits on a page. Each past edit is shown in a box which shows lines added, changed or deleted during that edit in a before & after format.

Below each box is a "Restore" link. Clicking the link will open an edit box with the page as it was ''before'' that edit.  You can make changes or simply click Save to restore the text.

There are two additional options specific to Page''''History:

* '''Hide minor edits''' - hides any edit that the author marked as 'minor'. - This is done by adding "&minor=n" to "?action=diff".  The default value for this is to show minor edits with "&minor=y"

* '''Show changes to markup'''- It shows changes to the markup (as opposed to the normal display which shows changes to the output). This is done by adding "&source=y" to "?action=diff".  You can show changes to output (the default behavior) with "&source=n".

* You can set both by using "?action=diff&source=y&minor=y".

A page's history is kept for the number of days given by the $DiffKeepDays variable (set by the site's [[wiki administrator]]).  When a page is edited, any page history information older than this value is automatically discarded.

Note that a specific page revision isn't removed from the page until the first edit ''after'' the time specified by $DiffKeepDays has elapsed. Thus, it's still possible for some pages to have revisions older than $DiffKeepDays -- such revisions will be removed the next time those pages are edited.

!! See also
* Cookbook:ExpireDiff
* Cookbook:LimitDiffsPerPage, Cookbook:InlineDiff
* Cookbook:TrackChanges

>>faq<< [[#faq]]

Q: [[#removepagehistory]] Is there a way to remove page history from page files?
A: 1. Administrators can clean page histories using the Cookbook:ExpireDiff recipe. 

A: 2. Administrators with FTP file access can download individual pages from the wiki.d directory, open them in a text editor, manually remove history, and re-upload the files to wiki.d/ directory. Care must be exercised, when manually editing a page file, to preserve the minimum required elements of the page and avoid corrupting its contents. See [[PmWiki/PageFileFormat#creating]].

A: 3. Edit the page. Select ''all'' the contents of the edit text area and cut them to the clipboard. Enter @@delete@@ into the text area and  click on the ''save and edit'' button. Select ''all'' the contents of the edit text area and paste the contents of the clipboard over them. Click on the ''save'' button. This will remove all of the page's history up to the final save in which the pasted material is re-added.

Q: [[#restrictpagehistory]] How can I restrict viewing the page history [@(?action=diff)@] to people with edit permission?
A: In the ''local/config.php'' file, set

->[@$HandleAuth['diff'] = 'edit'@];

In case of this restriction is set up on a farm, and you want to allow it on a particular wiki, set in your local/config.php :

->[@$HandleAuth['diff'] = 'read'@];
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PageListTemplates</pagename>
<data><![CDATA[(:Summary: Creating [[PmWiki/page list(s)]] format templates:)
!! Default [[page list(s)]] templates

PmWiki's default templates for [[page lists]] are in [[Site.PageListTemplates]], which is replaced during upgrades.  
These default templates can be supplemented or overridden with custom templates stored in other locations. 
 
If the page name is not specified as part of the template name, PmWiki's default configuration looks for templates in the following locations in the following order
# the current page
# [[Site.LocalTemplates]], 
# [[Site.PageListTemplates]]
Administrators can change those locations by using the $FPLTemplatePageFmt variable.  

If the template is on the current page, the current page must be saved for changes involving the template to show up ''(preview alone will not work)''.

!! Custom page list templates
Custom templates are used in the same way as default templates: by referencing the desired format with the @@fmt=#''anchor''@@ option.  
There are several ways to indicate which template to use:
* [@fmt=#custom@] uses the #custom section from the current page, [[Site.LocalTemplates]], or [[Site.PageListTemplates]], (sections are denoted by [@[[#custom]]@] anchors.
* [@fmt=MyTemplatePage#custom@] uses a custom format from page @@MyTemplatePage@@ from its @@#custom@@ section.
* [@fmt=MyTemplatePage@] uses a custom format from the entire page @@MyTemplatePage@@.
* [@fmt=custom@] uses custom format which is defined in a cookbook script as ''custom''.

See Cookbook:PagelistTemplateSamples for examples of custom pagelist formats.

!! Creating page list templates
A pagelist template contains standard pmwiki markup.  
When creating pagelist output, pmwiki iterates over each page returned from the pagelist and will include the pagelist template markup once for every page in the list. 

[[#specialreferences]]
!!! Special references 
During the page list iteration pmwiki sets 3 special page references: '''=''', '''<''' and '''>'''.  
These special page references are updated on each pagelist iteration and can be used with the [[page variables]] syntax, such as ''{=$variable}'',  to define a pagelist template which will format the pagelist output.  The meaning of the special references are:
||width=*
||  = ||current page  ||so ''[@{=$Title}@]'' ||displays the title of the current page in the iteration
||  < ||previous page ||so ''[@{<$Group}@]'' ||displays the group of the previous page in the iteration
||  > ||next page     ||so ''[@{>$Name}@]''  ||displays the name of the next page in the iteration

The > and < references are most useful to help structure pagelist output before and after the actual pagelist.  Some common tests used to structure pagelist output are:
(:table class=frame:)
(:cellnr:)[@(:template first:)@]
(:cell:)[- {- [@(:if equal {<$Group}:)@] -} -]
(:cell:)Iteration is at the beginning of list
(:cellnr:)[@(:template last:)@]
(:Cell:)[- {- [@(:if equal {>$Group}:)@] -} -]
(:cell:)Iteration is at the end of list
(:cellnr:)[@(:template first {=$Group}:)@]
(:cell:)[- {- [@(:if ! equal {=$Group} {<$Group}:)@] -} -]
(:cell:)Iteration is at the first item in a group
(:cellnr:)[@(:template last  {=$Group}:)@]
(:cell:)[- {- [@(:if ! equal {=$Group} {>$Group}:)@] -} -]
(:cell:)Iteration is at the last item in a group 
(:cellnr:)[@(:template defaults:)@]
(:cell:)
(:cell:)Default options to be used in the pagelist command
(:cellnr:)[@(:template each:)@]
(:cell:)
(:cell:)Signifies the repeated part
(:tableend:)
[[#specialreferencesend]]
''Note'': the markup in column 2 is deprecated

!! Page list template special markup
Pagelist templates may have special 
* [@(:template first ...:)@]
* [@(:template last ...:)@] sections to specify output for the first or last page in the list or a group. 
There's also a 
* [@(:template defaults ...:)@] 
to allow a template to specify default options, and
* [@(:template each ...:)@]
to signify the repeated part.

These allow Pagelist templates to be easily separated into "sections"
that are included or not included in the output based on a variety of
conditions.  These are intended to be improved versions of the
[=(:if ...:)=] conditions that have traditionally been used to control
pagelist output (however, the [=(:if:)=] conditions still work as before).

!!! First, Each, Last
The simplest versions of the directives are:
-> [@
(:template first:)      # markup to display only for first page in list
(:template each:)       # markup to display for each page in list
(:template last:)       # markup to display only on last page in list@]

So, a pagelist template can specify:

->[@(:template first:)
Pages in the list:
(:template each:)
* [[{=$FullName}]]
(:template last:)
Displayed {$$PageCount} pages.@]

In addition, the "first" and "last" options can have control break
arguments that identify markup to be displayed on the first or last
page within a particular control section.  For example, to specify
markup to be displayed upon reaching the first or last page of
a group, one can use

->[@(:template first {=$Group}:)
(:template last {=$Group}:)@]

Thus, instead of writing control breaks using (:if:) directives, as in

->[@(:if ! equal {<$Group} {=$Group}:)
Group: {=$Group}
(:ifend:)
* [[{=$FullName}]]@]

one can now write

->[@(:template first {=$Group}:)
Group: {=$Group}
(:template each:)
* [[{=$FullName}]]@]

!!! Default options
In addition, a template may specify default options to be used
in the pagelist command.  For example, a pagelist template to
display a list of pages by their titles (and sorted by title)
might use:

->[@[[#bytitle]]
(:template default order=title:)
* [[{=$FullName}|+]]
[[#bytitleend]]@]

Then an author could write [=(:pagelist fmt=#bytitle:)=] and the
pages would automatically be sorted by title without having to
specify an additional "order=title" option to the [=(:pagelist:)=]
directive.

To specify multiple parameters to an option enclose the parameters in double quotes, eg to sort by a [[page text variable(s)]] and then the page name
-> [@ (:template defaults order="$:Database,name" :) @]

!!! Examples
:[=(:template defaults ... :)=]   :  default options for pagelists using this template
:[=(:template each:)=]            :  markup for each page in the pagelist
:[=(:template first:)=]           :  markup output only for the first page in the pagelist
:[=(:template last:)=]            :  markup output only for the last page in the pagelist
:[=(:template first {=$Group}:)=] :  markup output only for a page where the value of {=$Group} has just changed
:[=(:template last {=$Group}:)=]  :  markup output only for a page where the value of {=$Group} will change with the next page

So, we have:

->[@[[#template]]
(:template defaults order=name:)
(:template first:)
Pages ordered by group
(:template first {=$Group}:)

Pages in group [[{=$Group}/]]
(:template each:)
* [[{=$FullName}]]
(:template last {=$Group}:)
   {=$Group} contains {$$GroupPageCount} pages.
(:template last:)
   {$$PageCount} pages total.
[[#templateend]] @]

!! Page list template additional page variables
Additional [[Page Variables]] that are only available during pagelist are: 
->[@
{$$PageCount}       The current page count of this iteration
{$$GroupCount}      The current group count of this iteration
{$$GroupPageCount}  The current page count within the current group of this iteration 
{$$option}          The argument option values from (:pagelist:)@]

Use of {$$option}: For example {$$trail} returns the page name entered in the trail= option of the pagelist directive. You can make up custom "options" with no other purpose than being displayed in the pagelist.

[[#redirect]]
!! Redirect 
To enable searches that return only one page to automatically redirect to that page add the following to a pagelist template where the "jump to a page" functionality is desired:

-> [@(:template last:)
(:if equal {$$PageCount} 1:)(:redirect {=$FullName}:)(:ifend:)
@]

[[#closure]]
!! Closure of markup
Any open tables, divs, or other
structures inside of [=(:pagelist:)=] are, by default, automatically closed at the
end of the pagelist command.  In other words, [=(:pagelist:)=] acts like
its own complete page, as opposed to generating markup that is then
inserted into the enclosing page.

For example a table generated by the [=(:cell:)=]
directive in the first [=(:pagelist:)=] command is automatically closed
at the end of the pagelist.  The [=(:cell:)=] in the second [=(:pagelist:)=]
command then starts a new table.

Note that the [=(:table:)=] directive doesn't actually start a new table,
it's the [=(:cell:)=] or [=(:cellnr:)=] directive that does it.  All that the
[=(:table:)=] directive does is set attributes for any tables that follow.

!! Usage
It is advisable to not modify the page [[Site.PageListTemplates]] directly so that you will still benefit from upgrades.  
Instead, modify your [[Site.LocalTemplates]] page (which is not part of the PmWiki distribution).  Cookbook:PagelistTemplateSamples has many examples of custom pagelist formats.

!! Other recipes
In addition, the [[(Cookbook:)Cookbook]] has other recipes for special [@fmt=@] options, including [[Cookbook:DictIndex | [@fmt=dictindex@] ]] (alphabetical index) and [[Cookbook:SimpleForum | [@fmt=forum@] ]] (forum postings).
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PageLists</pagename>
<data><![CDATA[(:Audience: authors, admins (intermediate) :)
(:Summary:Listing pages by multiple criteria with templated output:)
PmWiki comes with two directives for generating lists of pages -- [@(:pagelist:)@] and @@[=(:=]searchresults:)@@.  Both directives are basically the same and each accepts the parameters documented below.  The primary difference between the two is that searchresults generates the "Results of search for ..." and "### pages found out of ### searched" messages around the results.

The [@(:searchbox:)@] directive generates a search form (input text box) to submit search queries.  The markup generally accepts the same parameters as [@(:pagelist:)@], which makes it possible to restrict, order and format searchresults in the same ways that are described below for a [@(:pagelist:)@].  For more information about the [@(:searchbox:)@] directive, and the ways in which it differs from a [@(:pagelist:)@], skip to the section [[#searchbox|below]].

!! Basic syntax

* [@(:pagelist:)@] 
->without any arguments shows a bulleted list of all pages, as links, ordered alphabetically and in groups.
* @@[=(:=]pagelist [[#pagelistgroup|group]]=''abc'' \
  [[#pagelistname|name]]=''def'' \
  [[#pagelistfmt|fmt]]=''[[page list templates|template]]''  \
  [[#pagelistlist|list]]=''ghi'' \
  [[#pagelistorder|order]]=''jkl'' \
  [[#pagelistcount|count]]=''123'' \
  [[#pagelistlink|link]]=''mno'' \
  [[#pagelisttrail|trail]]=''pqr''  \
  [[#pagelistwrap|wrap]]=''stu''  \
  [[#pagelistpasswd|passwd]]=''vwx''  \
  [[#pagelistif|if]]=''yz''  \
  [[#pagetextvariables|$:''ptv'']]=''yz'' \
  [[#pagevariables|$''pv'']]=''za'' \
  [[#pagelistcache|cache]]=0 \
  ''[[#pagelistarg|argument]]1''&nbsp;-''[[#pagelistarg|argument]]2'' ''etc'' \
  [[#includevariable|variable]]=''value'' \
  [[#pagelistclass|class]]=''class'' \
  :)@@ 
->shows a pagelist according to the  parameters supplied. Parameters are optional.
* @@[=(:=][[#searchbox|searchbox]] value=''abc'' size=''99'' target=''def'':)@@
* @@[=(:=][[#searchresults|searchresults]] [[#pagelistreq|''request=1 req=1'']] :)@@

!! Parameters
[[#pagelistarg]]
Any argument supplied within [@(:pagelist:)@] that isn't in the form @@'key=value'@@ is treated as text that either must (or must not) exist in the page text.

The minus sign (-) or exclamation mark (!) can be used to indicate the logical ''not''. Thus
->[@(:pagelist trail=PmWiki.DocumentationIndex list=normal apple !pie:)@]
lists all "normal" pages listed in the [[Documentation Index ]] trail that contain the word "apple" but not "pie".

!!![[#pagetextvariables]]With page text variables
You can also use [[page text variables]] as a ''key'' to list pages according to the existence of a page text variable. Eg : 
->[@(:pagelist $:pagetextvar=avalue:)@]
lists pages having ''$:pagetextvar'' set to ''avalue''.
[[<<]]
Minus sign (-), wildcards (?*) and a comma separated list of values also works when specifying a selection based on pagetextvariables. Eg :
->[@(:pagelist $:apagetextvar=t*,-test:)@]
lists pages having $:apagetextvar like 't*' but not 'test'.
[[<<]]
Examples:
||width=* class="tabtable" rules=rows
||PTV is set (is not empty): ||[@(:pagelist $:MyPageTextVariable=- :)@]||
||PTV is empty or not set:[[<<]]&nbsp;(ie, is not set to one char followed by 0 or more chars) ||[@(:pagelist $:MyPageTextVariable=-?* :)@]||
||PTV is not VALUE:          ||[@(:pagelist $:MyPageTextVariable=-VALUE :)@]||
||PTV is set and not YES:    ||[@(:pagelist $:MyPageTextVariable=?*,-YES :)@]||
Be aware that if using [@(:pagelist $:MyPTV=$:YourPTV :)@] PTVs include PmWiki formatting, so you may not get the matches you expect. Currently the only way around this is to use wild cards, so if the formatting is embedded you may be out of luck.

!!![[#pagevariables]]With page variables (PV)

Page variables can be used within pagelists in the same way as page text variables.  See [[#pagetextvariables|Page Text Variables]] above for more details.  Simply use $var instead of $:var.

!!![[#pagelistgroup]] group= and [[#pagelistname]]name= 

The "[@group=@]" and "[@name=@]" parameters limit results to pages in a specific group or with a specific name:
(:table class='tabtable' rules=rows:)
(:cellnr:)All pages in the Pmwiki group:
(:cell:)[@(:pagelist group=PmWiki :)@]
(:cellnr:)All pages except those in the PmWiki or Site groups:
(:cell:)[@(:pagelist group=-PmWiki,-Site :)@]
(:cellnr:)All RecentChanges pages
(:cell:)[@(:pagelist name=RecentChanges :)@]
(:cellnr:)All pages except RecentChanges
(:cell:)[@(:pagelist name=-RecentChanges :)@]
(:tableend:)

!!! Wildcards
Name and group parameters can contain ''wildcard'' characters that display only pages matching a given pattern:
* An asterisk (*) represents zero or more characters
* A question mark (?) represents exactly one character

Examples:
(:table class='tabtable' rules=rows:)
(:cell:)All pages in any group beginning with "PmWiki"
(:cell:)[@(:pagelist group=PmWiki* :)@]
(:cellnr:)All pages in any group beginning with "PmWiki", except for Chinese
(:cell:)[@(:pagelist group=PmWiki*,-PmWikiZh :)@]
(:cellnr:)All pages in the PmCal group with names starting with "2005":
(:cell:)[@(:pagelist name=PmCal.2005* :)@]
(:cellnr:)All Cookbooks with names beginning with a A and a B letter
->note the different separators used for the same result
(:cell:)[@
(:pagelist group=Cookbook name=A*,B*   :)
(:pagelist group=Cookbook name="A* B*" :)
(:pagelist group=Cookbook name=[AB]*   :)
(:pagelist group=Cookbook, name=[AB]*   :)@]
(:tableend:)

If you want to use multiples conditions in name you need to use quotes or commas to delimit the string. 

!!![[#pagelisttrail]] trail= 
The "[@trail=@]" option obtains the list of pages to be displayed from a [[WikiTrail(s)]]:
* Display pages in the documentation by modification time
->[@(:pagelist trail=PmWiki.DocumentationIndex order=-time:)@]
* Display five most recently changed pages
-<[@(:pagelist trail=RecentChanges count=5:)@]

!!![[#pagelistlist]] list= 

The "[@list=@]" option allows a search to include or exclude pages according to predefined patterns set by the administrator.  
* "[@list=normal@]" is predefined, and which excludes things like AllRecentChanges, RecentChanges, GroupHeader, GroupFooter, GroupAttributes, and the like from being displayed in the list results.  Note that list=normal also excludes the current page.
* "[@list=all@]" over-rides a "default" list that may be set by the wiki's administrator to exclude groups such as PmWiki or Site from regular search results.
* Wiki administrators can define custom lists via the $SearchPatterns array (see [[Cookbook:SearchResults]]).

!!![[#pagelistfmt]] fmt= 

The "[@fmt=@]" option determines how the resulting list should be displayed.  
PmWiki [[Site/PageListTemplates|predefines]] several formats:
* @@fmt=#bygroup@@ - Display pages within groups (default format)
* @@fmt=#simple@@  - Display a simple ordered list of pages in the form Group.Name
* @@fmt=#title@@   - Display a list of pages by page title.  Use "[@order=title@]" to have them sorted by title (default is to order by page name).
* @@fmt=#group@@   - Display a list of wikigroups (without listing the pages in the groups)
* @@fmt=#include@@ - Display the contents of each page in the list (note, this could take a very long time for long lists!)
These formats are defined by [[page list templates]], which can be customized.

This format is not predefined by a page list template:
* @@fmt=count@@ - Display the number of pages in the list (note the absence of the "#").
* @@fmt=authtable@@ - Display a table of pages with ''read'', ''edit'', ''attr'', ''upload'', and ''publish'' settings (note the absence of the "#").

!!![[#pagelistlink]] link= 

The "[@link=@]" option implements "backlinks" -- i.e., it returns a list of pages with a link to the target.  It's especially useful for [[categor(ies)]]y pages and finding related pages.

* all pages with a link to PmWiki.DocumentationIndex
->[@(:pagelist link=PmWiki.DocumentationIndex:)@]
* all pages with links to the current page
->[@(:pagelist link={$FullName}:)@]
* all pages in the "Skins" category
->[@(:pagelist link=Category.Skins:)@]

!!![[#pagelistcount]] count= 

The "[@count=@]" option provides the ability to
* limit the pagelist to a specific number of pages
* subsets of a list
* return items from the end of a list, subsets of a list
* display pages in reverse sequence

(:table class=tabtable rules=rows:)
(:cellnr:)A simple bullet list of ten most recently modified pages
(:cell:)
[@(:pagelist trail=Site.AllRecentChanges count=10 fmt=#simple:)@]
(:cellnr:)Display the first ten pages of a list
(:cell:)
[@count=10          # display the first ten pages of list@]
(:cellnr:)Negative numbers specify pages to be displayed from the end of the list:
(:cell:)
[@count=-10         # display last ten pages of list@]
(:cellnr:)Ranges may be specified using '..', thus:
(:cell:)
[@count=1..10       # first ten pages of list
count=5..10       # 5th through 10th pages of list@]
(:cellnr:)Negative numbers in ranges count from the end of the list:
(:cell:)
[@count=-10..-5     # 10th from end, 9th from end, ..., 5th from end@]
(:cellnr:)Omitting the start or end of the range uses the start or end of the list:
(:cell:)
[@count=10..        # skip first ten pages
count=..10        # 1st through 10th page of list
count=-10..       # last ten pages of list
count=..-10       # all but the last nine pages@]
(:cellnr:)Ranges can be reversed, indicating that the order of pages in the output should likewise be reversed:
(:cell:)
[@count=5..10       # 5th through 10th pages of list
count=10..5       # same as 5..10 but in reverse sequence
count=-1..1       # all pages in reverse sequence@]
(:cellnr:)"Reverse sequence" here refers to the sequence ''after'' any sorting has taken place.  Therefore the three directives to the right are equivalent:
(:cell:)
[@(:pagelist order=-name count=10:)
(:pagelist order=-name count=1..10:)
(:pagelist order=name count=-1..-10:) @]
(:tableend:)

!!![[#pagelistwrap]] wrap=
The "[@wrap@]" option has the values, ''none'' and ''inline''.

With "wrap=inline" and "wrap=none", the output from pagelist (markup or HTML) is directly embedded in a page's markup without any surrounding <div> class=...</div> tags.

With "wrap=inline", any surrounding <ul> is continued. Without "wrap=inline", the HTML output starts a new <ul>. This is important if you want to get a second level <ul> produced by the page list since starting a new <ul> with "**" doesn't yield a second level <ul> but <dl><dd><ul>...

"wrap=inline" likely has other effects since it suppresses the call to $FPLTemplateMarkupFunction (being MarkupToHTML by default).

!!![[#pagelistclass]] class=
By default, a pagelist has the 'fpltemplate' class. The 'bygroup', 'simple', 'group' and 'title' page list formats have specific class names fplbygroup, fplsimple etc. You can set any class using the class= parameter or by setting the $FPLFormatOpt array.

!!![[#pagelistpasswd]] passwd=
The "[@passwd@]" option returns only those pages that have some sort of password attribute on them.

!!![[#pagelistif]] if=
The "[@if@]" option allows a condition to be specified as part of the pagelist processing, rather than from within the [[page list template(s)]]. Only those pages for which the condition is true are retrieved. Anything that could [[ConditionalMarkup | go within an [@(:if ...:)@]]] can be used as a condition. For example

  [@(:pagelist if="date {(ftime %GW%V {*$Name})} {=$Name}" :)@]

returns all of the pages where the name is in the same week as that of the current page.

!!![[#pagelistorder]] order=

The "[@order=@]" option allows the pages in the list to be sorted according to different criteria.  Use a minus sign to indicate a reverse sort.  Multiple sorting criteria can be specified using a comma, and you can create your own [[(PmWiki:)custom pagelist sort order]]:
* [@order=name@] - alphabetically by name (default order)
* [@order=title@] - alphabetically by title rather than names
* [@order=time@] - most recently changed pages '''last'''
* [@order=ctime@] - time of page creation (see note)
* [@order=size@] - page size (not file size), smallest pages first
* [@order=group,title@] - by multiple criteria, in this instance sort by title within groups
* [@order=random@] - shuffle the pages into random sequence
* [@order=$:pagetextvarname@] - alphabetically by [[PageTextVariables|page text variable]] value

Also, the [@order=@] option allows custom ordering functions to be written.
->Note: fmt=trail results in an unordered pagelist, i.e. the trail order is preserved in the pagelist. So PmWiki's alphabetical default order does not apply in this case.
->Note: ctime was added to pages only from pmwiki 2.1.beta15 onwards, pages created by earlier versions don't carry a ctime attribute and can't be sorted that way.

[[#pagelistcache]]
!!! cache=0
Pagelist has the capability to cache lists which greatly speeds up processing.  Every once in a while this caching can result in undesired results.  Specifying @@cache=0@@ disables caching.

[[#includevariable]]
!!!! Specifying variables as parameters
You can also specify variable values inline with the pagelist statement, and refer to the variables in the template using the [@{$$variable1}@] format:
-> [@(:pagelist fmt=#pagelist variable1="value" variable2="value2":)@]

This assumes that a site has $EnableRelativePageVars enabled, which is recommended in PmWiki 2.2.0 -- but disabled by default to help people upgrading from 2.1.x.

For example, in the template:

(:markup:)
>>comment<<
[[#tvars]]
(:template default count=1 ParamName=Simon:)
Hi, {$$ParamName}, how are you today?
[[#tvarsend]]
>><<
(:markupend:)

This gives:

(:markup class=horiz:)
(:pagelist fmt=#tvars ParamName="Sam":)

(:pagelist fmt=#tvars ParamName="Sally":)

(:pagelist fmt=#tvars:)
(:markupend:)

!! Examples

Include the contents of a random page from the Banners group:
->[@(:pagelist group=Banners order=random count=1 fmt=#include list=normal:)@]

Display a simple list of the last ten recently changed pages:
->[@(:pagelist trail=Site.AllRecentChanges count=10 fmt=#simple:)@]

Display the "top twenty" biggest cookbook pages:
->[@(:pagelist group=Cookbook order=-size count=20 :)@]

!![[#searchbox]] The Searchbox Directive

The [@(:searchbox:)@] directive generally accepts the same parameters as [@(:pagelist:)@] and [@(:input text:)@] directives:
* Pagelist parameters can be added to the input text of a searchbox (or to the markup, or both)
* Input text box parameters can be added to the searchbox markup
** An initial search string can be specified in the searchbox markup, but it must be in the form @@value='search string'@@.  That search string is displayed in the input text and can be modified by when the search is run.
** The size of the text input field can be specified with the size parameter, where "size=40" would specify the current default value.
*** Tip:  If more than one searchbox appears on a page, adding a blank initial value like this @@value=''@@, to the markup for each searchbox will prevent a search string for one box from populating all of the other boxes.
* The target page for displaying searchbox results can be set with the parameter @@target=''GroupName.PageName''@@.  The default is the current page. 
* The entire searchbox form can be overridden by defining the $SearchBoxFmt variable in one's configuration file.  If $SearchBoxFmt is defined, then the parameters to [@(:searchbox:)@] are ignored, and the content of the $SearchBoxFmt variable are used instead.

[[#searchresults]]
!! The Searchresults directive
The [@(:searchresults:)@] directive generally accepts the same parameters as [@(:pagelist:)@] and [@(:input text:)@] directives:

!!![[#pagelistreq]] request=1 req=1
[=(:searchresults:)=] without the introductory line that says "Results of search for..."

!! See Also

* [[PageDirectives#attachlist]] - display a list of attachments
* [[Site.PageListTemplates]] - default pmwiki pagelist templates
* [[Cookbook:PagelistTemplateSamples]] - contributed pagelist template samples
* [[PmWiki/PageListTemplates]] - how to create custom pagelist templates for the fmt= option
* [[(PmWiki/)PagelistVariables]] - ''local/config.php'' customizations
* [[Cookbook:Forms]] - documentation for [@(:input text:)@] markup, which applies to [@(:searchbox:)@]
* [[(PmWiki:)CustomPagelistSortOrder]] - creating custom order sort functions
* [[Cookbook:CustomPagelistSortOrderFunctions]] - {Cookbook.CustomPagelistSortOrderFunctions$:Summary}
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PageTextVariables</pagename>
<data><![CDATA[(:Summary:Page variables automatically made available through natural or explicit page markup:)

>>rframe font-size:smaller noprint clear=right<<
!!!! Table of contents
* [[#defining | Defining page text variables]]
* [[#usage | Usage]]
** [[#usagesamepage | On the same page]]
** [[#usageotherpage | From other pages]]
** [[#usageincludedpage | On included pages]]
** [[#nested | Nested]]
** [[#pagelists | With pagelists]]
** [[#templates | In templates]]
** [[#conditionals| With conditionals]]
** [[#usageother | Other usage]]
** [[#withincode | Within code]]
** [[#usagenotes | Usage notes]]
>><<

Page Text Variables were introduced in 2.2.0 beta 2.  
These are string variables automatically made available through [[PmWiki/TextFormattingRules | natural page]] markup or explicitly with [[PmWiki/PageDirectives | page directive]] markup within the wiki text of the page.

[[#defining]]
!! Defining Page Text Variables

There are three ways to define automated Page Text Variables:

* use a [[TextFormattingRules#DefinitionLists | definition list]] - the normal pmwiki markup for a definition list will create a page text variable
(:markup caption='Example:' class="horiz":)
:Name: Crisses
"{$:Name}"
(:markupend:)
->This creates a new variable that can be accessed by [@{$:Name}@] (becomes: "{$:Name}") in the page.

* use a simple colon delimiter in normal text
(:markup caption='Example:' class="horiz":)
Address: 1313 Mockingbird Lane

"{$:Address}"
(:markupend:)
->This creates the [@{$:Address}@] variable (variable markup becomes: "{$:Address}") in the page.

* hidden [[PmWiki/PageDirectives | directive]] form - PmWiki markup that doesn't render on the page, but defines the variable
(:markup caption='Example:' class="horiz":)
(:Country: Transylvania :)
"{$:Country}"
(:markupend:)
->This creates the [@{$:Country}@] variable (variable markup becomes: "{$:Country}") in the page.

[[#usage]]
!! Usage
[[#usagesamepage]]
!!! Usage on the same page

On the same page you can resolve page text variables through the [@{$:Var}@] format (shown above).

!!! Usage in headers and footers

If you want a GroupHeader, GroupFooter, SideBar, etc to call on page text variable in the main page, you need to include reference information.  
To explicitly reference the page text variable from the page being displayed add an asterisk to the page text variable's markup:  [@{*$:Address}@] on the GroupFooter or GroupHeader page.  
(:markup caption='Example' class=horiz:)
{*$:City}
(:markupend:)
To include a page text variable ''from'' a header or footer see [[#usageotherpage |usage from other pages]] below.

[[#usageotherpage]]
!!! Usage from other pages

If you want to pull the data from another page, use the [@{Group/PageName$:Var}@] format.
(:markup caption='Example:' class="horiz":)
Suburb: Khandallah
(:Lake:Taupo:)
:Mountain:Mt Ruapehu

->"{PmWiki/PageTextVariables$:Suburb}"
->"{{$FullName}$:Lake}"
->"{PmWiki/PageTextVariables$:Mountain}"
(:markupend:)

[[#usageincludedpage]]
!!! Usage from included pages

Page text variables are never [[IncludeOtherPages|included]] from their source page.
See [[#usageotherpage|Usage from other pages]] above to refer to a page text variable on another page.

[[#nested]]
!!! Nested page text variables

Page text variables can be nested
(:markup caption='Example:' class="horiz":)
: MailingAddress : {$:Address}, {$:City}, {$:Country}
"{$:MailingAddress}"
(:markupend:)

Another way you may nest PTVs is to make (part of) the variable name a variable in itself:
(:markup caption='Example:' class="horiz":)
x:Test/Ptvb
Contents of y on page {$:x}:
{{$:x}$:y}
(:markupend:)

[[#pagelists]]
!!! Usage with pagelists

[[Page lists]] can also access the page text variables:
(:markup caption='Example:' class="horiz":)
(:pagelist group=PmWiki order=$:Summary count=8 fmt=Cookbook/PagelistTemplateSamples#oneline:)
(:markupend:)

And to create pagelist formats (such as those documented at [[Site.Page List Templates]], [[PmWiki/Page Lists]], [[PmWiki/Page List Templates]], [[PmWiki/Page Variables]].  Store custom pagelists at [[Site.Local Templates]]).

[[Page lists]] can also use page text variables to select pages :
(:markup caption='Example:' class="horiz":)
(:pagelist group=PITS $:Category=Feature count=8 fmt=Cookbook/PagelistTemplateSamples#oneline order=-name:)
(:markupend:)
->lists pages having '$:Category' set to 'Feature'.

(:markup caption='Example: multiple selections' class="horiz":)
(:pagelist group=Cookbook $:Version=1,2 order=-$:Version count=8 fmt=Cookbook/PagelistTemplateSamples#oneline:)
(:markupend:)
->lists pages having a '$:Version' of '1' or '2'.

(:markup caption='Example: multiple selections with spaces' class="horiz":)
(:pagelist group=PmWiki $:City="Addis Ababa,Paris" order=-$:Version count=8 fmt=Cookbook/PagelistTemplateSamples#oneline:)
(:markupend:)
->'quotes' must surround ''all'' the selections.

(:markup caption='Example: Pages with City variable set' class="horiz":)
City: Addis Ababa
(:pagelist group=PmWiki $:City=- count=10 fmt=Cookbook/PagelistTemplateSamples#oneline:)
(:markupend:)
->City variable is set.

* When using page text variables for selection or ordering, don't put the curly braces around the variable name. The curly forms do a replacement before the pagelist command is evaluated. 

[[#set]]
!!! Testing if set or not set
(:table:)
(:cellnr:)'''=-''' 
(:cell:)PTV is set (is not empty), eg [@(:pagelist $:MyPageTextVariable=- :)@]
(:cellnr:)'''=-?*''' 
(:cell:)PTV is not set (is empty), ie is not set to one char followed by 0 or more  chars, eg [@(:pagelist $:MyPageTextVariable=-?* :) @]
(:cellnr:)'''=*''' 
(:cell:)display ''all'' pages, the page text variable is irrelevant
(:cellnr:)'''=-*''' 
(:cell:)display ''no'' pages, the page text variable is irrelevant
(:tableend:)

(:markup caption='Example: Pages without a summary' class="horiz":)
(:pagelist group=PmWiki $:Summary=-?* count=10  fmt=Cookbook/PagelistTemplateSamples#oneline:)
(:markupend:)

[[#templates]]
!!! Use page text variable in a template
Display pages by Country page text variable.
(:markup caption='Example:' class="horiz":)
[@
[[#bycountry]]
(:if ! equal {{=$FullName}$:Country} {{<$FullName}$:Country} :)
-<'''[[{{=$FullName}$:Country}]]''':  
(:ifend:)
[[{=$FullName}]]
[[#bycountryend]]
@]
(:pagelist group=PmWiki count=6 fmt={$FullName}#bycountry:)
(:markupend:)
->[-''some parts of this example are not working correctly, should not display all pages''-]

[[#conditionals]]
!!! Use page text variables in [[PmWiki/conditional markup]]
Page text variables will be assigned/evaluated before any conditional markup is evaluated. That means you can use page text variables with conditional markup, but not conditional markup within page text variables. For instance a PTV will have a value even if it is set within a [@(:if false:)....(:if:)@] condition. 

[[#usageother]]
!!! Usage - other

Data relevant to a page (the "Base" page) may now also be found in other groups.  If the Base page is Main/HomePage, the data page could be Data-Main/HomePage.  A new variable called $BaseName, which automatically calculates the Base page name from the Data page name, and can be defined by including the following in config.php:

->[@// The pattern for figuring out the basename of a page
$BaseNamePatterns['/^Data-/'] = '';@]

Your pattern may vary.

[[#withincode]]
!!! Usage - from within code (developers only)

The standard @@PageVar($pagename,$varname)@@ function can return page text variables, but remember to include the dollar and colon like this:

->@@$var=PageVar($pagename,'$:City')@@

Actually, for text variables, @@PageVar@@ just calls @@PageTextVar($pagename,$varname)@@, so your code can be sped up slightly by calling it directly, but it takes just the raw variable name without any leading characters, like this: 

->@@$var=PageTextVar($pagename,'City')@@

It works by caching all page text-variables it finds in a page (in @@$PCache@@) and returns the one requested.

@@PageTextVar@@ relies on the @@$PageTextVarPatterns@@ variable (which can be used to extend the recognized formats for page text variables in a page). In the older 2.2.0 Beta versions of PmWiki, this variable wasn't initialized until stdmarkup.php was run, ''after'' config.php was executed. Thus, if you needed to use page text variables inside config.php, you had to initialize it yourself. This is no longer necessary, but for those who are still running earlier versions of the beta series, here's the value to use:

->[@ SDVA($PageTextVarPatterns, array(
    'var:' => '/^:*\\s*(\\w[-\\w]*)\\s*:[ \\t]?(.*)$/m',
    '(:var:...:)' => '/\\(: *(\\w[-\\w]*) *:(?!\\))\\s?(.*?):\\)/s'));
 @]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>HansB</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PageVariables</pagename>
<data><![CDATA[(:title Page specific variables:)
(:description Documentation for "variables" that are associated with pages. :)
(:Summary: variables that are associated with pages:)
(:Audience: authors (intermediate) :)

[[#desc]]This page describes the "variables" that are associated with pages.  Page variables have the form @@{$''variable''}@@, and can be used in page markup or in certain formatting strings in PmWiki.  For example, the markup "[@{$Group}@]" renders in this page as "{$Group}".

Note: Do not confuse these variables (set and used only in PmWiki pages) with [[PmWiki/Variables|PHP variables]].  Page variables can be read in PHP with the [[Cookbook:Functions#PageVar|PageVar()]] function.

Note that these variables do not necessarily exist in the PHP code, because they have to be determined for a specific page.  (However, they are usable in [[FmtPageName]] strings.)

There is also the form @@{''pagename''$''variable''}@@, which returns the value of the variable for another page.  For example, "[@{MarkupMasterIndex$Title}@]" displays as "{MarkupMasterIndex$Title}".

[[#specialreferences]]
!! Special references
Special referenced variables are used to retain the context of the target page or main page for a [[variable(s)]] when:
* the variable is [[PmWiki/IncludeOtherPages|included]] into a destination (target) page)
* the variable is part of a sidebar, header, or footer for a main page

Prefixing the variable name with an asterisk (*) means the variable reflects the value related to the target page or main page.
* '''[@*$@]'''PageVariablename - prefixed by an asterisk (*) - value reflects target page context
Without the asterisk it reflects the value of the page in which it originates.
* '''[@$@]'''PageVariablename -  retains value in source page context

Special references are also used in [[page list templates(#specialreferences)]].

For example you can test to see if the page is part of another page
(:markup:)
(:if ! name {$FullName}:) 
%comment% name of this page is not the same as the page this text was sourced from
->[[{$FullName}#anchor | more ...]]
(:ifend:)
(:markupend:)
or refer to the main page in a sidebar, footer, or header
(:markup class=horiz:)
This page is [[{*$FullName}]]
(:markupend:)

[[#specialreferencesend]]

!! Default page variables

The page variables defined for PmWiki are:

->[@{$Group}@] - page's group name, as in "`{$Group}"
->[@{$Groupspaced}@] - spaced group name, as in "{$Groupspaced}"
->[@{$DefaultGroup}@] - default group name, as in "{$DefaultGroup}"
->[@{$SiteGroup}@] - default group name for e.g. RecentChanges, as in "{$SiteGroup}"
->[@{$Name}@] - page name, as in "`{$Name}"
->[@{$Namespaced}@] - spaced page name, as in "{$Namespaced}"
->[@{$DefaultName}@] - name of default page, as in "`{$DefaultName}"
->[@{$FullName}@] - page's full name, as in "`{$FullName}"
->[@{$BaseName}@] - page's "base" form (stripping any prefixes or suffixes defined via @@$BaseNamePatterns@@) as in "`{$BaseName}"
->[@{$Title}@] - page title (may differ from Name), as in "{$Title}"
->[@{$Titlespaced}@] - title/spaced page name, as in "{$Titlespaced}"
->[@{$Description}@] - page's description from the [@(:description:)@] markup, as in "{$Description}"

->[@{$LastModified}@] - date page was edited, as in "{$LastModified}"
->[@{$LastModifiedBy}@] - page's last editor, as in "{$LastModifiedBy}"
->[@{$LastModifiedTime}@] - time page was edited in unix-style timestamp, as in "{$LastModifiedTime}" %green%added version 2.2 beta 67%%
-->This can be used (preceded by '@') in [@{(ftime)}@] and other date/time markups.
->[@{$LastModifiedHost}@] - IP of page's last editor, as in "{$LastModifiedHost}"
->[@{$LastModifiedSummary}@] - Summary from last edit, as in "{$LastModifiedSummary}"
->[@{$PageUrl}@] - page's url, as in "{$PageUrl}"
->[@{$Action}@] - page's url action argument, as in "{$Action}"
->[@{$PasswdRead}@] - current password for read attr. e.g. "{$PasswdRead}"
->[@{$PasswdEdit}@] - current password for read attr. e.g. "{$PasswdEdit}"
->[@{$PasswdAttr}@] - current password for read attr. e.g. "{$PasswdAttr}"

In addition to the above, there are some page-invariant variables available through this markup:

->[@{$Author}@] - the name of the person currently interacting with the site, as in "{$Author}"
->[@{$AuthId}@] - current authenticated id, as in "{$AuthId}" %red%Please note the lower case 'd'.  [@{$AuthID}@] returns nothing

->[@{$Version}@] - PmWiki version, as in "{$Version}"
->[@{$VersionNum}@] - The internal version number, as in "{$VersionNum}"
->[@{$ScriptUrl}@] - The url to the pmwiki script, as in "{$ScriptUrl}"

!! Custom page variables

You may add custom page variables as a local customization. In a local configuration file or a recipe script, use the variable $FmtPV:

->[@
$FmtPV['$VarName'] = "'variable definition'";
$FmtPV['$CurrentSkin'] = '$GLOBALS["Skin"]';
$FmtPV['$WikiTitle'] = '$GLOBALS["WikiTitle"]';
@]

Defines new Page Variable of name $CurrentSkin, which can be used in the page with [@{$CurrentSkin}@] (also for [[Conditional markup]]).  It's necessary to use the single quotes nested inside double-quotes as shown above (preferred) or a double-quoted string nested inside single-quotes like ''[@'"this"'@]''.

If you want to have a Page Variable that returns the currently used password (more precisely, the last password entered), you can use

->[@
$FmtPV['$AuthPw'] = 'reset(array_keys((array)@$_SESSION["authpw"]))';
@]

!! See also

* [[Cookbook:More custom page variables]]
* [[PmWiki.Variables]] &mdash; about variables internal to PmWiki.
* [[PmWiki.MarkupMasterIndex]] &mdash; complete list of PmWiki markups.
* [[PmWiki/PageTextVariables]] &mdash; page variables automatically made available through natural page markup or explicit page markup within the wiki text of the page.
* [[PmWiki.Markup Expressions]] &mdash; markup expressions can manipulate page variables

>>faq<< [[#faq]]

Q:Is there a variable like $LastModified, but which shows me the creation time?
A:No, but you can create one in config.php. For instance:
->[@# add page variable {$PageCreationDate} in format yyyy-mm-dd
$FmtPV['$PageCreationDate'] = 'strftime("%Y-%m-%d", $page["ctime"])';@]

If you like the same format that you define in config.php with $TimeFmt use
[@ $FmtPV['$Created'] = "strftime(\$GLOBALS['TimeFmt'], \$page['ctime'])";
@]]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PagelistVariables</pagename>
<data><![CDATA[(:Summary:variables used with [[PmWiki/page lists]] and search results:)
:$EnablePageListProtect:When set to 1 (which is the default), causes [@(:pagelist:)@] and [@(:searchresults:)@] to exclude listing any pages for which the browser does not currently have read authorization.  Setting this to zero means that read-protected pages can appear in a listing, but can also speed up searches considerably (because page permissions do not need to be checked).

:$SearchPatterns:An array of page name patterns to be required or excluded from search and [[PmWiki/PageLists|pagelist]] results.  In order to be included in a search listing or page listing, a page's name must not match any pattern that is delimited by exclamation points (!) and must match all other patterns.  See [[Cookbook:SearchPatterns]].
--> [@# Limit all searches to Main group
$SearchPatterns['default'][] = '/^Main\\./';
# Exclude the Main group from search results
$SearchPatterns['default'][] = '!^Main\\.!';
# Exclude RecentChanges pages from search results
$SearchPatterns['default'][] = '!\\.(All)?RecentChanges$!';
# Prevent a page from listing itself in (:pagelist:) or (:searchresults:)
$SearchPatterns['default'][] = FmtPageName('!^$FullName$!', $pagename);
@]

:$SearchBoxOpt:
--> For example [@ $SearchBoxOpt ['target'] = '$DefaultGroup.Search'; @]

:$EnablePageIndex:When set to 1, causes PmWiki to maintain a "link and word index" in $PageIndexFile which significantly speeds up categories, backlinks, and searches.

:$PageIndexFile:The location of the "page index" file for [@(:pagelist:)@], defaults to @@$WorkDir/.pageindex@@.

:$PageListCacheDir:The name of a writable directory where PmWiki can cache results of [@(:pagelist:)@] directives to speed up subsequent displays of the same list.  Default is empty, which disables the pagelist cache.
--> [@# Enable pagelist caching in work.d/
$PageListCacheDir = 'work.d/';
@]

:$PageSearchForm:The page to be used to format search results for [@?action=search@] (unless the current page has a "searchresults" directive in it).  This variable can be an array, in which case the first page found from the array is used.
--> [@# Use Search page in current group if it exists, otherwise use Site.Search
$PageSearchForm = array('$Group.Search', '[=$[$SiteGroup/Search]=]');
@]

:$FPLTemplatePageFmt:The pages to be searched for a pagelist template specified by a [@fmt=#xyz@] parameter.  Defaults to searching the current page, [[Site.LocalTemplates]] and [[Site.PageListTemplates]].

--> [@# PMWiki default setup
global $FPLTemplatePageFmt;
$FPLTemplatePageFmt = array(
    '{$FullName}', 
    '{$SiteGroup}.LocalTemplates', 
    '{$SiteGroup}.PageListTemplates');@]

-> It can be customized to look in other pages.

--> [@# Search a Group.Templates page as well as the Site templates
global $FPLTemplatePageFmt;
$FPLTemplatePageFmt = array(
    '{$Group}.Templates',
    '{$SiteGroup}.LocalTemplates',
    '{$SiteGroup}.PageListTemplates');@]

-> Or declare defaults for the template array:
--> [@# Search a Group.Templates page as well as the Site templates
global $FPLTemplatePageFmt;
SDV($FPLTemplatePageFmt, array('{$FullName}',
    '{$Group}.Templates',
    '{$SiteGroup}.LocalTemplates', '{$SiteGroup}.PageListTemplates')
   );@]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Passwords</pagename>
<data><![CDATA[(:Summary:General use of passwords:)
(:Audience: authors :)
[[PmWiki]] has built-in support for password-protecting various areas of the wiki site.  Authors generally want to be able to apply passwords to individual pages or to [[wiki group]]s.  Wiki Administrators can apply passwords to individual pages, to wiki groups, or to the [[PasswordsAdmin#settingsitewidepasswords|entire site]].  As with any access control system, the password protection mechanisms described here are only a small part of overall system and wiki [[security]].

!!As an author editing pages...

An author will generally set 3 types of passwords:
# to control who can see a page or group, use  @@read@@ passwords
# to control who can edit a page or group, use @@edit@@ passwords
# to control who can alter the passwords used to protect a page or group, use @@attr@@ passwords

'''''To set a password on an individual wiki page,''''' add 

->@@?action=attr@@ 

to the page's URL (address) to access its attributes.  Using the form on the attributes page, you can set or clear the @@read@@, @@edit@@, or @@attr@@ passwords on the page.  In the form you enter the passwords as cleartext; PmWiki encrypts them for you automatically when it stores them. 

Additional options:

* Leaving a field blank will leave the attribute unchanged. 
* To remove a password from a page (''reverting back'' to the group's or site's default), enter 

->clear

* To indicate that the page can be edited ''even if a group or site password is set'', enter 

->@nopass

* To lock a page for everybody but the admin, enter 

->@lock

* To assign the site's site-wide edit-password to the @@read@@, @@edit@@, or @@attr@@ password for the page, enter 

->@_site_edit

'''''To set a password on a wiki group''''' is slightly more difficult -- you just set the passwords on a special page in each group called 

->`GroupAttributes

First, you can get to the attributes page for `GroupAttributes by entering a URL (address) like 

->[@http://www.example.com/pmwiki/pmwiki.php?n=GroupName.GroupAttributes?action=attr@]

Replace www.example.com with your domain name, and GroupName with the name of the group

Then, using the form on the attributes page, you can set or clear the @@read@@, @@edit@@, or @@attr@@ passwords for the entire group.  In the form you enter the passwords as cleartext; PmWiki encrypts them for you automatically.

Additional options:

* To remove a password from a group (''reverting back'' to the site's default), enter 

->clear

* To indicate that the group can be edited ''even if a site password is set'', enter 

->@nopass

* To lock a group for everybody but the admin, enter 

->@lock

'''''Multiple passwords for a page, group or site''''' are allowed. Simply enter multiple passwords separated by a space. This allows you to have a read password, a write password, and have the write password allow read/write access.  In other words, if the read password is 

->alpha

and the edit password is 

->beta

then enter

-> [@
Set new read password: alpha beta
Set new edit password: beta
@]

This says that either 

->alpha

or 

->beta

can be used to read pages, but only 

->beta

may edit. Since PmWiki checks the passwords you've entered since the browser has been opened, entering a read password that is also a write password allows both reading and writing.

%audience% administrator

!!As an administrator ...

You can set passwords on pages and groups exactly as described above for authors. You can also:
# set site-wide passwords for pages and groups that do not have passwords
# use @@attr@@ passwords to control who is able to set passwords on pages
# use @@upload@@ passwords to control access to the file [[upload(s)]] capabilities (if uploads are enabled)
# use an @@admin@@ password to override the passwords set for any individual page or group  
For more information on password options available to administrators, see [[PasswordsAdmin]].

!!Which password wins?

In PmWiki, page passwords override group passwords, group passwords override the ''default'' passwords, and the @@admin@@ password overrides all passwords.  This gives a great deal of flexibility in controlling access to wiki pages in PmWiki. 

!!Opening access to pages in protected groups/sites

Sometimes we want to "unprotect" pages in a group or site that is otherwise protected.  In these cases, the special password 

->@nopass

is used to indicate that access should be allowed to a page without requiring a password.  

For example, suppose `Main.GroupAttributes has an edit password set, thus restricting the editing of all pages in Main.  Now we want `Main.WikiSandbox to be editable without a password.  Using 

->clear

for the edit password for `Main.WikiSandbox ''doesn't unprotect the page'', because the password is being set by the group.  Instead, we set the edit password for `Main.WikiSandbox to the special value 

->@nopass

which tells PmWiki to ignore any site-wide or group-level passwords for that page.

>>faq<< [[#faq]]

Q:  How can I password protect all the pages and groups on my site?  Do I really have to set passwords page by page, or group by group?

A:  Administrators can set passwords for the entire site by editing the config.php file; they don't have to set passwords for each page or group.  For example, to set the entire site to be editable only by those who know an "edit" password, an administrator can add a line like the following to local/config.php:

    $DefaultPasswords['edit'] = crypt('edit_password');

For more information about the password options that are available only to administrators, see [[PasswordsAdmin]].

Q:  I get http error 500 "Internal Server Error" when I try to log in. What's wrong?

A:  This can happen if the encrypted passwords are not created on the web server that hosts the PmWiki.\\
The crypt function changed during the PHP development, e.g. a password encrypted with PHP 5.2 can not be decrypted in PHP 5.1, but PHP 5.2 can decrypt passwords created by PHP 5.1.\\
This situation normally happens if you prepare everything on your local machine with the latest PHP version and you upload the passwords to a webserver which is running an older version.\\
The same error occurs when you add encrypted passwords to local/config.php.

Solution: Create the passwords on the system with the oldest PHP version and use them on all other systems.

Q:  How can I create private groups for users, so that each user can edit pages in their group, but no one else (other than the admin) can?

A:  Administrators can use the [[(PmWiki:)AuthUser]] recipe and add the following few lines to their local/config.php file to set this up:

    $group = FmtPageName('$Group', $pagename); \\
    $DefaultPasswords['edit'] = 'id:'.$group; \\
    include_once("$FarmD/scripts/authuser.php");

This automatically gives edit rights to a group to every user who has the same user name as the group name.

Q: [[#farm]] How come when I switch to another wiki within a farm, I keep my same authorization?

A: PmWiki uses PHP sessions to keep track of authentication/authorization information, and by default PHP sets things up such that all interactions with the same server are considered part of the same session.

An easy way to fix this is to make sure each wiki is using a different cookie name for its session identifier.  Near the top of one of the wiki's local/config.php files, before calling authuser or any other recipes, add a line like:

    session_name('XYZSESSID');

You can pick any alphanumeric name for XYZSESSID; for example, for the cs559-1 wiki you might choose

    session_name('CS559SESSID');

This will keep the two wikis' sessions independent of each other.

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PasswordsAdmin</pagename>
<data><![CDATA[(:Summary:More password options for the administrator:)(:Audience: administrators (basic) :)
PmWiki has built-in support for [[Passwords|password-protecting]] various areas of the wiki site.  Passwords can be applied to individual pages, to [[Wiki Group]]s, or to the entire wiki site.  Note that the password protection mechanisms described here are only a small part of overall system (and wiki) security, see [[PmWiki.Security]] for more discussion of this.

Authors can use PmWiki to add passwords to individual pages and WikiGroups as described in [[Passwords]].  However, [[WikiAdministrator]]s can also set passwords in ''local/config.php'' as described below. (Please note that one cannot set passwords reliably in per group or per page customization files. See the [[#faq | FAQ section]] for details.)

[[#authlevel]]
!! Password basics

PmWiki supports several levels of access to wiki pages, known as authorisation level:
* '''@@read@@''' passwords allow viewing the contents of wiki pages
* '''@@edit@@''' passwords control editing and modification of wiki pages
* '''@@attr@@''' passwords control who is able to set passwords on pages (and potentially other future attributes)
* '''@@upload@@''' password, if uploads are enabled, controls uploading of files and attachments
* in addition all [[available actions]] can be password authorised
* '''@@admin@@''' password allows an administrator to override the passwords set for any individual page or group.

By default, PmWiki has the following password settings:
* The @@admin@@ and @@upload@@ passwords are locked by default.
* The Main and PmWiki groups have a locked @@attr@@ password (in their respective `GroupAttributes pages).
* The pages in the Site group except `Site.SideBar are locked against editing; by default the Site.SideBar page requires the admin or the site-wide edit password.

An @@admin@@ password can be used to overcome "locked" passwords, other than that, no password will allow access.

See [[Passwords]] for information about setting per-page and per-group passwords.  
The remainder of this page describes setting site-wide passwords from the ''local/config.php'' file.

[[#settingsitewidepasswords]]
!! Setting site-wide passwords

One of the first things an admin should do is set an @@admin@@ password for the site.  This is done via a line like the following in the ''local/config.php'' file:

-> $DefaultPasswords['admin'] = crypt('secret_password');

Note that the crypt() call is required for this -- PmWiki stores and processes all passwords internally as encrypted strings.  See the [[#crypt | crypt section]] below for details about eliminating the cleartext password from the configuration file.

To set the entire site to be editable only by those who know an "edit" password, add a line like the following to ''local/config.php'':

-> $DefaultPasswords['edit'] = crypt('edit_password');

Similarly, you can set a password for any [[available action(s)]], viz [@$DefaultPasswords['read']@], [@$DefaultPasswords['edit']@], and [@$DefaultPasswords['upload']@] to control default @@read@@, @@edit@@, and @@upload@@ passwords for the entire site.  The default passwords are used only for pages and groups which do not have passwords set.  Also, each of the $DefaultPasswords values may be arrays of encrypted passwords:

-> $DefaultPasswords['read'] = array(crypt('alpha'), crypt('beta'));
-> $DefaultPasswords['edit'] = crypt('beta');

This says that either "alpha" or "beta" can be used to read pages, but only the "beta" password will allow someone to edit a page.  Since PmWiki remembers any passwords entered during the current session, the "beta" password will allow both reading and writing of pages, while the "alpha" password allows reading only.  A person without either password would be unable to view pages at all.

!! Identity-based authorization (username/password logins, [[AuthUser]])

Unlike many systems which have '''identity-based''' systems for controlling access to pages (e.g., using a separate ''username'' and ''password'' for each person), PmWiki defaults to a ''password-based'' system as described above.  In general password-based systems are often easier to maintain because they avoid the administrative overheads of creating user accounts, recovering lost passwords, and mapping usernames to permitted actions.

However, PmWiki's ''authuser.php'' script augments the password-based system to allow access to pages based on a username and password combination.  See [[AuthUser]] for more details on controlling access to pages based on user identity.

!!Security holes ...

Administrators need to carefully plan where passwords are applied to avoid opening inadvertent security holes. If your wiki is open (anyone can read and edit), this would not seem to be a concern, '''except''', a malicious or confused user could apply a read password to a group and make the group completely unavailable to all other users. At the very least, even an open wiki should have a site-wide "admin" password and a site-wide "attr" password set in config.php. The ''sample-config.php'' file distributed with PmWiki indicates that the PmWiki and Main groups have "attr" locked by default, but if anyone creates a new group, "attr" is unlocked. Administrators must remember to set "attr" passwords for each new group (if desired) in this case. An easier solution is to include these lines in ''config.php'' :

-> [@
$DefaultPasswords['admin'] = crypt('youradminpassword');
$DefaultPasswords['attr'] = crypt('yourattrpassword');
@]

!! Encrypting passwords in ''config.php'' [[#crypt]]

One drawback to using the crypt() function directly to set passwords in ''config.php'' is that anyone able to view the file will see the unencrypted password.  For example, if ''config.php'' contains

-> $DefaultPasswords['admin'] = crypt('mysecret');

then the "mysecret" password is in plain text for others to see.  However, a wiki administrator can obtain and use an encrypted form of the password directly by using [@?action=crypt@] on any PmWiki url (or just jump to [[{$Name}?action=crypt]]).  This action presents a form that generates encrypted versions of passwords for use in the ''config.php'' file.  For example, when [@?action=crypt@] is given the password "@@mysecret@@", PmWiki will return a string like

-> [@$1$hMMhCdfT$mZSCh.BJOidMRn4SOUUSi1@]

The string returned from [@?action=crypt@] can then be placed directly into config.php, as in:

-> $DefaultPasswords['admin'] = [='$1$hMMhCdfT$mZSCh.BJOidMRn4SOUUSi1'=];  

Note that in the encrypted form the ''crypt'' keyword and parentheses are removed, since the password is already encrypted.  Also, the encrypted password must be in single quotes.  In this example the password is still "@@mysecret@@", but somebody looking at ''config.php'' won't be able to see that just from looking at the encrypted form.  ''Crypt'' may give you different encryptions for the same password--this is normal (and makes it harder for someone else to determine the original password).

!! Removing passwords

To remove a site password entirely, such as the default locked password for uploads, just set it to empty:

-> $DefaultPasswords['upload'] = '';

You can also use the special password "@nopass" via @@?action=attr@@ to have a non-password protected page within a password-protected group, or a non-password protected group with a site-wide default password set.

!! Revoking or invalidating passwords

If a password is compromised and the wiki administrator wants to quickly invalidate all uses of that password on a site, a quick solution is the following in ''local/config.php'':

-> [@
$ForbiddenPasswords = array('secret', 'tanstaafl');
if (in_array(@$_POST['authpw'], $ForbiddenPasswords)) 
  unset($_POST['authpw']);
@]

This prevents "secret" and "tanstaafl" from ever being accepted as a
valid authorization password, regardless of what pages may be
using it.

!! See Also

* The $HandleAuth array, which sets the required authentication level that is necessary to perform an action.
* [[Cookbook:RequireAuthor]]

!! Protecting actions (example)

Each [[(available) action(s)]] can be password protected. Cookbook authors providing scripts with own actions can use this also, but I'll limit the example to a (by default) not protected [@?action=source@]. This action shows the wikisource of the actual page. Sometimes you don't want that especially to [[Cookbook:protect email]] or when using some [[PmWiki/conditional markup]] which should not be discovered easily or only by persons that are allowed to edit the page.

There are several solutions for that:
# Limit "source" only to editors add the following to your ''local/config.php'':
  
--> [@$HandleAuth['source'] ='edit';@]

# For using "source" with an own password, then add:

--> [@$HandleAuth['source'] ='source';@]
--> [@$DefaultPasswords['source'] = crypt(secret);@] # ''see above''

If you additionally want to set the password in the attributes page add:

--> [@$PageAttributes['passwdsource'] = "$['Set new source password']";@]

In general, adding the prefix 'passwd' to an action name in the [@$PageAttributes@] array indicates that you wish for the given field to be encrypted when saved to disk.

The full set of steps to add new password handling for an action such as "diff" would be:

->[@
# add a new (encrypted) field to the attr page
$PageAttributes['passwddiff'] = '$[Set new history password]';

# clear the default password for 'diff'
$DefaultPasswords['diff'] = '';

# Tell PmWiki that the 'diff' password allows action 'diff'.
$HandleAuth['diff'] = 'diff';

# Tell PmWiki that a 'read' password 
# (or optionally the 'edit') password
# is also sufficient to enable 'diff'.
# Of course, the 'admin' password will work too.
$AuthCascade['diff'] = 'read';    ## or 'edit'
@]

>>faq<< [[#faq]]

Q: There seems to be a default password.  What is it? [[#pwlocked]]
A: There isn't any valid password until you set one.  [[Passwords admin]] describes how to set one.

PmWiki comes "out of the box" with $DefaultPasswords['admin'] set to '*'.   This doesn't mean the password is an asterisk, it means that default admin password has to be something that encrypts to an asterisk.  Since it's impossible for the crypt() function to ever return a 1-character encrypted value, the admin password is effectively locked until the admin sets one in config.php.

Q: How do I use passwd-formatted files (like .htpasswd) for authentication?
A: See [[AuthUser]], Cookbook:HtpasswdForm or Cookbook:UserAuth.

Q: Is there anything I can enter in a GroupAttributes field to say 'same as the admin password'? If not, is there anything I can put into the config.php file to have the same effect?

A: Enter '@lock' in GroupAttributes?action=attr to require an admin password for that group.

Q: How do I edit protect, say, all RecentChanges pages?
A: see [[PmWiki/Security#wikivandalism]].

Q: How can I read password protect all pages in a group except the HomePage using configuration files?

A: As described in [[PmWiki.PerGroupCustomizations]] per-group or per-page configuration files should not be used for defining passwords. The reason is that per-group (or per-page) customization files are only loaded for the current page. So, if @@[=$DefaultPasswords['read']=]@@ is set in ''local/GroupA.php'', then someone could use a page in another group to view the contents of pages in GroupA. For example, Main.WikiSandbox could contain:

--> [=(:include GroupA.SomePage:)=]

and because the ''GroupA.php'' file wasn't loaded (we're looking at Main.WikiSandbox --> ''local/Main.php''), there's no read password set.

Q: How can I password protect the creation of new pages?
A: See Cookbook:LimitWikiGroups, Cookbook:NewGroupWarning, Cookbook:LimitNewPagesInWikiGroups.

Q: How do I change the password prompt screen?
A: If your question is about how to make changes to that page... edit [[Site.AuthForm]].  If your question is about how to change which page you are sent to when prompted for a password, you might check out the [[Cookbook:CustomAuthForm]] for help.

Q:  I get http error 500 "Internal Server Error" when I try to log in. What's wrong?
A:  This can happen if the encrypted passwords are not created on the web server that hosts the PmWiki.\\
The crypt function changed during the PHP development, e.g. a password encrypted with PHP 5.2 can not be decrypted in PHP 5.1, but PHP 5.2 can decrypt passwords created by PHP 5.1.\\
This situation normally happens if you prepare everything on your local machine with the latest PHP version and you upload the passwords to a webserver which is running an older version.\\
The same error occurs when you add encrypted passwords to local/config.php.

Solution: Create the passwords on the system with the oldest PHP version and use them on all other systems.

Q:  I only want users to have to create an 'edit' password, which is automatically used for their 'upload' & 'attr' passwords (without them having to set those independently). How do I do this?
A:  By setting [@$HandleAuth@] like so:
      $HandleAuth['upload'] = 'edit';
      // And to prevent a WikiSandbox from having it's 'attr' permissions changed 
      // except by the admin (but allowing editors to change it on their own pages/group)
      if(($group=="Site") || ($group=="Main") || ($group=="Category") || 
             ($group=="SiteAdmin") || ($group=="PmWiki") ) {
	$HandleAuth['attr'] = 'admin';  // for all main admin pages, set 'attr' to 'admin' password
      } else { 
	$HandleAuth['attr'] = 'edit';  // if you can edit, then you can set attr
      }

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PathVariables</pagename>
<data><![CDATA[(:Summary:variables used to specify various locations on the server:)

When dealing with file or path variables, one has to recognize the difference between working with URLs and files on disk.  For example:
* The include() statements are used to include other files (on disk) into the currently running PmWiki script.  Thus they require paths on the server's filesystem. 
* The $ScriptUrl and $PubDirUrl variables are used to tell a ''browser'', connecting via the webserver, how to execute the pmwiki script ($ScriptUrl) and the base url for getting files from PmWiki's pub/ directory ($PubDirUrl).

Note that a browser needs a URL (http://example.com/pmwiki/pub) while an include statement requires a server file path ($FarmD/scripts/something.php).

:$FarmD:The directory on the server where the farm is located (i.e., the directory containing the farm's copy of ''pmwiki.php'' and the ''scripts/'' directory).  This directory is automatically determined by pmwiki.php when it runs, and can be used to distinguish the farm's ''cookbook/'' and ''pub/'' subdirectories from a field's subdirectories.

:$FarmPubDirUrl:is the url that refers to the @@pub@@ directory for an entire farm. It defaults to the same value as $PubDirUrl. 

:$PageCSSListFmt:is an associative array which PmWiki uses to find any local css configuration files. It consists of a set of (''key'',''value'') pairs %green% that point to the same file%%. The ''key'' is a possible path to a file on disk holding the css data, while the ''value'' is the coresponding URL for that %green%same file%%. They keys are tested in turn, and for each named file that exists, the browser is instructed to load the corresponding URL. This allows for PMWiki to only load the css file if it exists. ([[PmWiki:WhySeeIfCSSExists|Why see if a CSS exists?]])  The default value for this variable is:

->[@
$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');
@]

->Note that the default (as of version pmwiki-2.1.beta26) makes no reference to $FarmPubDirUrl for css configuration files. If you wish to be able to place css configuration files in both the field's @@pub@@ directory, and the farm's @@pub@@ directory, you may want to add these lines to your @@local/config.php@@ file (as described in [[Cookbook:SharedPages]]):

->        %green%# this adds farm.css to all wikis
->[@
$PageCSSListFmt = array(
  '$FarmD/pub/css/farm.css' => '$FarmPubDirUrl/css/farm.css',
  'pub/css/local.css' => '$PubDirUrl/css/local.css',
  'pub/css/$Group.css' => '$PubDirUrl/css/$Group.css',
  'pub/css/$FullName.css' => '$PubDirUrl/css/$FullName.css');
@]

->        %green%# this enables farm css files in a similar manner to a local wiki
->[@
$PageCSSListFmt = array(
  '$FarmD/pub/css/local.css' => '$FarmPubDirUrl/css/local.css',
  '$FarmD/pub/css/$Group.css' => '$FarmPubDirUrl/css/$Group.css',
  '$FarmD/pub/css/$FullName.css' => '$FarmPubDirUrl/css/$FullName.css',
  'pub/css/local.css' => '$PubDirUrl/css/local.css',
  'pub/css/$Group.css' => '$PubDirUrl/css/$Group.css',
  'pub/css/$FullName.css' => '$PubDirUrl/css/$FullName.css');
@]

->Note the difference between CSS configuration files and CSS files associated with a skin. Skin files, including associated CSS, can be put in either the farm or the field @@pub/skins@@ directory, and the program will find them.

:$PubDirUrl: is the URL that refers to the @@pub@@ directory. That directory contains all the files and subdirectories that must be directly accessible from a browser (e.g. CSS and HTML files). Most prominent here is the @@skins@@ subdirectory.
->The following may work for you'^[[Cookbook:CleanUrls#multiviews|#]]^'
->[@  $ScriptUrl = 'http://'.$_SERVER['HTTP_HOST'].'/pmwiki/pmwiki.php';
  $PubDirUrl = 'http://'.$_SERVER['HTTP_HOST'].'/pmwiki/pub';@]

:$ScriptUrl: is the URL that you want people's browsers to use when accessing PmWiki, either as a field or farm.  It's used whenever PmWiki needs to generate a link to another PmWiki page or action. PmWiki is usually fairly good about "guessing" the correct value for $ScriptUrl on its own, but sometimes an admin needs to set it explicitly because of URL manipulations by the webserver (such as Cookbook:CleanUrls, mod_rewrite, bizarre PHP configurations, and so on).

:$SkinDirUrl:Set by ''scripts/skins.php'' to be the base url of the current skin's directory (i.e., within a 'pub/skins/' directory).  This variable is typically used inside of a skin .tmpl file to provide access to .css files and graphic images associated with the skin.

:$WorkDir:
: :This variable is a string that gives a local path to a directory where the pmwiki engine can create temporary files etc. PmWiki needs this for a variety of things, such as building merged edits, caching mailposts entries, keeping track of the last modification time of the site, other types of cache, etc.  Do not confuse this variable with $WikiDir; the reason that both $WorkDir and $WikiDir refer by default to the directory [@wiki.d/@] is merely to simplify things for the administrator. 

:$WikiDir: 
: :$WikiDir is a `PageStore-object that refers to how wiki pages are stored. This can be a simple reference to a directory (typically ''wiki.d/''), or something more advanced such as a `MySQL backend or a .dbm-file.  Do not confuse this variable with $WorkDir; the reason that both $WorkDir and $WikiDir refer by default to the directory [@wiki.d/@] is merely to simplify things for the administrator.
: :To store groups of pages in subdirectories add [@$WikiDir = new PageStore('wiki.d/$Group/$FullName');@] to the start of your config file. '^[[Cookbook:PerGroupSubDirectories|#]]^'

:$WikiLibDirs:
: :$WikiLibDirs is an array of `PageStore objects that specify where to look for pages.  By default it is set up to look in ''wiki.d/'' and ''wikilib.d/'', but can be changed to look other places.  
: :For example, to exclude the pages that are bundled in the PmWiki distribution, use the line below.  (Note that some features such as editing and search rely on having certain pages available, so you may need to copy them to the $WikiDir.)
        $WikiLibDirs = array(&$WikiDir);
: :Another example
->[@
 	## for any page name, use the version located in wiki.d if it exists,
 	## use the version located in wikilib2.d, if a wiki.d version does not, and
 	## the version located in wikilib.d, if neither of the above exists
	$WikiLibDirs = array(&$WikiDir,
	    new PageStore('wikilib2.d/{$FullName}'),
	    new PageStore('$FarmD/wikilib.d/{$FullName}'));
@]
: : See also [[(http://www.pmwiki.org/wiki/Category/)CustomPageStore]].

:$LocalDir:The filesystem location of the ''local/'' directory, holding [[local customization(s)]] and [[(PmWiki:)per group customizations]] files.  Typically set in a [[WikiFarm(s)]]'s ''farmconfig.php''.  (Note that farm configuration files always occur in ''$FarmD/local/farmconfig.php'', regardless of any setting for $LocalDir.)

!!See also
* [[Layout Variables]] for URL layout options
* [[Link Variables]] - variables that control the display of links in pages
* [[Edit Variables]] - variables used when editing pages
* [[Upload Variables]] - variables used for uploads/attachments
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PatrickMichaud</pagename>
<data><![CDATA[Patrick Michaud (Pm) is the author of PmWiki.  More information about him can be found at http://www.pmichaud.com.]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>HaganFox</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PerGroupCustomizations</pagename>
<data><![CDATA[(:Summary: How to customize a subset of your wiki:)
(:Audience: administrators (intermediate) :)
One of the purposes of [[Wiki Group]]s is to allow a [[Wiki Administrator]] to customize the features of PmWiki on a per-group basis.  Here is where ''per group customizations'' come into play.

* The ''local/'' subdirectory (typically in $FarmD) is used to hold local configuration files.  
* The ''css/'' subdirectory  (typically in $FarmD) is used to hold local css files.

To perform [[local customizations]] for a particular WikiGroup, 
* place the customizations in a file called "''<groupname>.php''" (where ''<groupname>'' is the actual name of the page group in question) in the ''local/'' subdirectory  
* place the css customizations in a file called "''<groupname>.css''" (where ''<groupname>'' is the actual name of the page group in question) in the ''css/'' subdirectory.
These files will be automatically processed after processing any local customizations in the ''config.php'' and ''local.css'' files.

For example, to change the image displayed in the upper-left corner of pages in the "GroupName" WikiGroup, one could create ''local/GroupName.php'' containing
-> [@
<?php
  $PageLogoUrl = "/myimages/chess.gif";
@]
The example's effect would cause all pages in the GroupName [[Wiki Group]] to use "/myimages/chess.gif" as the logo image instead of the default.

To add markup to the beginning or end of each page in a wiki group, see [[Group headers]].

!!! Per-page customizations
[[#PerPage]] PmWiki also allows per-page customizations, simply use the full name of the page to be customized instead of the group.  For example, one can use the file ''local/Chess.`HomePage.php'' to set local customizations for Chess.`HomePage.

Almost any customization that would be placed in ''config.php'' can be used as a per-group or per-page customization. 

An important exception to this is setting '''per-group or per-page customizations for recipe scripts''' included in config.php. Most recipe scripts would need any customization variables defined before the script is included. Instead of using a per-group or per-page customization php file, use a per-group or per-page conditional statement in config.php, before including the recipe script. Example:

>>frame<<
->[@$page = PageVar($pagename, '$FullName');
$group = PageVar($pagename, '$Group');
//per-group customizations:
if($group=='GroupName') {
   $RecipeVariable = 'valueA';
   etc. ...
}
//per-page customizations:
if($page=='GroupName.PageName) {
   $RecipeVariable = 'valueB';
   etc. ...
}
//include recipe after variables are set:
include_once('cookbook/recipescript.php');@]
>><<
  
!!! Processing order
For all local customizations, PmWiki first processes the ''local/config.php'' file, and then looks for a per-page customization file in the ''local/'' subdirectory to process, followed by any per-group customization file.  If no per-page or per-group customizations are loaded, then PmWiki loads ''local/default.php''.  If a per-page customization wants to have the per-group customizations loaded first, it can do so directly by using PHP's [@include_once()@] function.
For more information see [[(PmWiki:)wiki cascades]].

!!! Custom CSS styles per group or per-page
To apply CSS styles to pages of a specific group named [[Group Name]], create a file named ''GroupName.css'' in the ''pub/css/'' directory and add the CSS style rules there. To apply styles to a specific page, create a file ''GroupName.PageName.css'' in this directory with your style rules. Any CSS rules to be applied for all wiki pages can be put into ''pub/css/local.css''.

->[@/pub/css/GroupName.css:

  body { background: #F4C4B4; }
@]

!!! Preventing group-Level configurations
Any customization file can set $EnablePGCust=0; to prevent later page/group/default customizations from being automatically loaded.  If a per-page customization needs to have the per-group customizations loaded first, it can do so directly by using PHP's [@include_once()@] function.

!!! Authentication
Any passwords required for a group should be set in the group's [[Group Attributes]] page (see [[Passwords Admin]]istration) and not in a group customization file.

!!! Consider Wiki Farms
[[Wiki Group]]s are an easy way to host multiple sites in a single PmWiki installation by giving each site its own group.  Another approach is to use [[Wiki Farms]], which allows each site to have its own set of [[Wiki Group]] and local customization files. Read about 

If you are looking for nested group levels, you may want to consider [[PmWiki:HierarchicalGroups|Pm's design considerations on hierarchical groups]].

>>faq<< [[#faq]]
Q: How can I apply CSS styles to a particular group or page?

A: Simply create a ''pub/css/Group.css'' or ''pub/css/Group.Page.css'' file containing the custom CSS styles for that group or page.

Q: Why shouldn't passwords be set in group (or page) customization files?

A: The reason for this advice is that per-group customization files are only loaded for the current page. So, if @@[=$DefaultPasswords['read']=]@@ is set in ''local/GroupA.php'', then someone could use a page in another group to view the contents of pages in GroupA. For example, Main.WikiSandbox could contain:

--> [=(:include GroupA.SomePage:)=]

and because the ''GroupA.php'' file wasn't loaded (we're looking at Main.WikiSandbox --> ''local/Main.php''), there's no read password set.

The same is true for page customization files.

Q: Isn't that processing order strange? Why not load per page configuration last (that is after global configuration an per group configuration)?

A: Many times what we want to do is to enable a certain capability for a group of pages, but disable it on a specific page, as if it was never enabled.  If the per-group config file is processed first, then it becomes very difficult/tedious for the per-page one to "undo" the effects of the per-group page. So, we load the per-page file before the per-group.

If a per-page customization wants the per-group customizations to be performed first, it can use the techniques given in [[PmWiki.PerGroupCustomizations]] (using ''include_once()'' or setting @@[=$EnablePGCust = 0=]@@).]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PmWiki</pagename>
<data><![CDATA[PmWiki is a [[wiki(WikiWeb)]]-based system for collaborative creation and maintenance of websites.

PmWiki pages look and act like normal web pages, except they have an "[[Main/WikiSandbox?action=edit|Edit]]" link that makes it easy to modify existing pages and add new pages into the website, using [[basic editing]] rules. You do not need to know or use any HTML or CSS. Page editing can be left open to the public or restricted to small groups of authors.

!!Key PmWiki Features

-<'''Custom look-and-feel''': A site administrator can quickly change the appearance and functions of a PmWiki site by using different [[skins]] and HTML templates.  If you can't find an appropriate skin [[already made -> Cookbook:Skins]], you can easily modify one or create your own.

-<'''Access control''': PmWiki password protection can be applied to an entire site, to groups of pages, or to individual pages.  Password protection controls who can read pages, edit pages, and upload attachments.  PmWiki's access control system is completely self-contained, but it can also work in conjunction with existing password databases, such as ''.htaccess'', LDAP servers, and MySQL databases.

-<'''Customization and plugin architecture''': One principle of the [[PmWikiPhilosophy]] is to only include essential features in the core engine, but make it easy for administrators to customize and add new markup.  Hundreds of features are already available by using extensions (called "recipes") that are available from the PmWiki [[(Cookbook:)Cookbook]].

PmWiki is written in %newwin%[[http://php.net/|PHP]] and distributed under the %newwin%[[http://www.gnu.org/copyleft/gpl.html|General Public License]].  It is designed to be simple to [[PmWiki/install(ation)]], customize, and maintain for a variety of applications. This site is running {$Version}.

PmWiki is a registered trademark of [[http://www.pmichaud.com/ | Patrick R. Michaud ]].

PmWiki's home on the web is at [[(http://)pmwiki.org(/)]].
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Pm</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.PmWikiPhilosophy</pagename>
<data><![CDATA[(:Summary:This page describes some of the ideas that guide the design and implementation of PmWiki:)
This page describes some of the ideas that guide the design and implementation of PmWiki.  [[Patrick Michaud]] doesn't claim that anything listed below is an original idea; these are just what drive the development of PmWiki.  You're welcome to express your disagreement with anything listed below.  [[PmWiki.Audiences]] also describes much of the reasoning behind the ideas given below.

:''1. Favor writers over readers'':At its heart, PmWiki is a collaborative authoring system for hyperlinked documents.  It's hard enough to get people (including Pm) to contribute written material; making authors deal with HTML markup and linking issues places more obstacles to active contribution.  So, PmWiki aims to make it easier to author documents, even if doing so limits the types of documents being authored.

:''2. Don't try to replace HTML'':PmWiki doesn't make any attempt to do everything that can be done in HTML.  There are good reasons that people don't use web browsers to edit HTML--it's just not very effective.  If you need to be writing lots of funky HTML in a web page, then PmWiki is not what you should be using to create it.  What PmWiki does try to do is make it easy to link PmWiki to other "non-wiki" web documents, to embed PmWiki pages inside of complex web pages, and to allow other web documents to easily link to PmWiki.

: :This principle also follows from the "favor writers over readers" principle above--every new feature added to PmWiki requires some sort of additional markup to support it.  Pretty soon the source document looks pretty ugly and we'd all be better off just writing HTML.  

: :Another reason for avoiding arbitrary HTML is that ill-formed HTML can cause pages to stop displaying completely, and arbitrary HTML can be a security risk--more so when pages can be created anonymously.  See http://www.cert.org/advisories/CA-2000-02.html for more information.  

:''3. Avoid gratuitous features (or "creeping featurism")'':In general PmWiki features are implemented in response to specific needs, rather than because someone identifies something that "might be useful".  In any sort of useful system, it's hard to change a poorly designed feature once people have built a lot of structure based on it.  (Need an example?  Look at MS-DOS or Windows.)  One way to avoid poor design is to resist the temptation to implement something until you have a clearer idea of how it will be used.  

:''4. Support collaborative maintenance of public web pages'':Although this wasn't at all the original intent of PmWiki, it became quickly obvious that [[WikiWikiWeb]] principles could be used to make it easier for groups to collaboratively design and maintain a public web site presence.  PmWiki allows individual pages to be password protected, and a couple of local customizations makes it easy to protect large sections of PmWiki pages.  Furthermore, in many ways PmWiki provides "style sheets on steroids": you can quickly change the headers, footers, and other elements on a large group of pages without ever having to touch the individual page contents.  Finally, it's relatively easy to add [[custom markup]] for specialized applications.

:''5. Be easy to install, configure, and maintain'': With a gzip-compressed file size of just around 200K, uploading PmWiki to your server is a speedy operation. Do a chmod or two, update a few settings in config.php and you should be up and running. PmWiki stores all data in flat files, so there is no need for `MySQL or other utilities.  Upgrading is usually a simple matter of copying the latest version's files over the files of your existing PmWiki installation.  (One of the biggest reasons for the creation of PmWiki was that other wiki engines at the time required modifications to the distribution files, so admins ended up losing their customizations on every upgrade.)

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.RefCount</pagename>
<data><![CDATA[(:Summary: Link references counts on pages:)
RefCount performs link reference counts on pages in the PmWiki database (i.e., counts of links between pages).  Before using RefCount, it must be enabled by the [[wiki administrator]] by placing the following line in a [[local customization(s)]] file:

->[@include_once("$FarmD/scripts/refcount.php");@]

To use refcount add [@?action=refcount@] to the URL of any wiki page to bring up the reference count form. For example:

->%newwin%[[{$FullName}?action=refcount]]

The refcount form contains the following controls:
[[#refcountcontrols]]
*'''Show''' ~ This selects which pages will appear in the output
**all ~ Shows all references 
**missing ~ Shows only references to pages that don't exist
**existing ~ Shows only references to pages that do exist
**orphaned ~ Shows pages that exist but don't have any references to them.  There is no way to browse to an orphaned page.
*'''page names in group''' ~ Selects which group(s) to the referenced pages can be in
*'''referenced from pages in''' ~ Selects which group(s) the referencing pages can be in
*'''Display referencing pages''' ~ Includes a link to the referencing page -- this can make for a very long output unless you limit the groups searched
[[#refcountcontrolsend]]

The output is a table where each row of the table contains a page name or link reference, the number of (non-RecentChanges) pages that contain links to the page and the number of Recent Changes pages with links to the page.

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.ReleaseNotes</pagename>
<data><![CDATA[(:title Release Notes:)
(:Summary: PmWiki release notes:)
!! Version 2.2.4 (2009-07-16)
This release fixes a bug introduced earlier today with HTML entities in XLPages.

!! Version 2.2.3 (2009-07-16)
This release fixes six potential XSS vulnerabilities, reported by Michael Engelke. The vulnerabilities may affect wikis open for editing and may allow the injection of external JavaScripts in their pages. Public open wikis should upgrade.

A new variable $EnableUploadGroupAuth was added; if set to 1, it allows password-protected uploads to be checked against the Group password. 

It is now possible to use @@ @_site_edit, @_site_read, @_site_admin@@ or @@ @_site_upload@@ global passwords in GroupAttributes pages.

A number of other small bugs were fixed, and the documentation was updated.

!! Version 2.2.2 (2009-06-21)
The major news in this release is a fix of an AuthUser vulnerability.

The vulnerability affects only wikis that (1) rely on the AuthUser core module 
for User:Password authentication, -AND- (2) where the PHP installation runs 
with the variable "magic_quotes_gpc" disabled.

All PmWiki 2.1.x versions from pmwiki-2.1.beta6 on, all 2.2.betaX, 2.2.0, and 
2.2.1 are affected.

The PmWiki SiteAnalyzer can detect if your wiki needs to upgrade:
  http://www.pmwiki.org/wiki/PmWiki/SiteAnalyzer

If your wiki is vulnerable, you should do one of the following at the earliest 
opportunity:

* Upgrade to a version of PmWiki at least 2.2.2 or greater.
* Turn on magic_quotes_gpc in the php.ini file or in a .htaccess file.

Alternatively, you can temporarily disable AuthUser until you upgrade.

Note that even if your wiki does not have the AuthUser vulnerability at the 
moment, you are strongly encouraged to upgrade to PmWiki version 2.2.2 or 
later, as some future configuration of your hosting server might put you at 
risk.

This release also comes with minor updates in the local documentation; fixes 
were applied for international wikis - notably global variables in 
xlpage-utf-8.php and a new variable $EnableNotifySubjectEncode, which allows 
e-mail clients to correctly display the Subject header; and a number of other 
small bugs were fixed.

!! Version 2.2.1 (2009-03-28)
This release comes with an updated local documentation; wikiTrails now work cross-group; guiedit.php now produces valid HTML, and other small bugs were fixed.  We also added $EnableRedirectQuiet, which allows redirects to take place without any mention of "redirected from page ....".

!! Version 2.2.0 (2009-01-18)

This is a summary of changes from 2.1.x to 2.2.0.

* Several pages that were formerly in the [[Site]].* group are now in a separate [[SiteAdmin]].* group, which is read-restricted by default.  The affected pages include Site.AuthUser, Site.AuthList, Site.NotifyList, Site.Blocklist, and Site.ApprovedUrls .  If upgrading from an earlier version of PmWiki, PmWiki will prompt to automatically copy these pages to their new location if needed.  If a site wishes to continue using the old Site.* group for these pages, simply set

-> $SiteAdminGroup = $SiteGroup;

-> when carrying out this upgrade inspect your config files for lines such as
--> $BlocklistDownload['Site.Blocklist-PmWiki'] = array('format' => 'pmwiki');
->as you may wish to fix then, eg
--> $BlocklistDownload[$SiteAdminGroup . '.Blocklist-PmWiki'] = array('format' => 'pmwiki');

* Important Change in Passwords in PmWiki 2.2 indicating that the group can be edited even if a site password is set will be done by @@"@nopass"@@ prior it was done by @@"nopass"@@
-> When migrating a wiki you will have to manually modify the permission or by a script replace in all the page concerned @@passwdread=nopass:@@ by @@passwdread=@nopass@@ (see PITS:00961) --isidor

* PmWiki now ships with WikiWords entirely disabled by default.  To re-enable them, set either $LinkWikiWords or $EnableWikiWords to 1.  To get the 2.1 behavior where WikiWords are spaced and parsed but don't form links, use the following:
-> $EnableWikiWords = 1;
-> $LinkWikiWords = 0;

* It's now easy to disable the rule that causes lines with leading spaces to be treated as preformatted text -- simply set $EnableWSPre=0; to disable this rule.

--> '''Important:''' There is ongoing discussion that the leading whitespace rule may be disabled ''by default'' in a future versions of PmWiki.  If you want to make sure that the rule will continue to work in future upgrades, set $EnableWSPre=1; in ''local/config.php''.

* The $ROSPatterns variable has changed somewhat -- replacement strings are no longer automatically passed through FmtPageName() prior to substitution (i.e., it must now be done explicitly).

* Page variables and page links inside of [@(:include:)@] pages are now treated as relative to the included page, instead of the currently browsed page.  In short, the idea is that links and page variables should be evaluated with respect to the page in which they are written, as opposed to the page in which they appear.  This seems to be more in line with what authors expect.  There are a number of important ramifications of this change:

[[#relativeurls]]
** We now have a new [@{*$var}@] form of page variable, which always refers to "the currently displayed page".  Pages such as Site.PageActions and Site.EditForm that are designed to work on "the currently browsed page" should generally switch to using [@{*$FullName}@] instead of [@{$FullName}@].

** The $EnableRelativePageLinks and $EnableRelativePageVars settings control the treatment of links and page variables in included pages.  However, to minimize disruption to existing sites, $EnableRelativePageVars defaults to '''disabled'''.  This will give existing sites an opportunity to convert any absolute [@{$var}@] references to be [@{*$var}@] instead.

** Eventually $EnableRelativePageVars will be enabled by default, so we highly recommend setting [@$EnableRelativePageVars = 1;@] in ''local/config.php'' to see how a site will react to the new interpretation.  Administrators should especially check any customized versions of the following:
---> [[Site.PageActions]]
---> [[Site.EditForm]]
---> [[Site.PageNotFound]]
---> SideBar pages with ?action= links for the current page
---> $GroupHeaderFmt, $GroupFooterFmt
---> [[Page lists]] that refer to the current group or page, etc in sidebars, headers, and footers

** The [@(:include:)@] directive now has a [@basepage=@] option whereby an author can explicitly specify the page upon which relative links and page variables should be based.  If no basepage= option is specified, the included page is assumed to be the base.

* Sites that want to retain the pre-2.2 behavior of [@(:include:)@] and other items can set [@$Transition['version'] = 2001900;@] to automatically retain the 2.1.x defaults.

* Text inserted via [@(:include:)@] can contain "immediate substitutions" of the form [@{$$option}@] -- these are substituted with the value of any options provided to the include directive.

* PmWiki now recognizes when it is being accessed via "https:" and switches its internal links appropriately.  This can be overridden by explicitly setting $ScriptUrl and $PubDirUrl.

* A new $EnableLinkPageRelative option allows PmWiki to generate relative urls for page links instead of absolute urls.

* Draft handling capabilities have been greatly improved.  When $EnableDrafts is set, then the "Save" button is relabeled to "Publish" and a "Save draft" button appears.  In addition, an $EnablePublishAttr configuration variable adds a new "publish" authorization level to distinguish editing from publishing.  See [[PmWiki:Drafts]] for more details.

[[#ptvstart]]
* There is a new [@{$:var}@] "page text variable" available that is able to grab text excerpts out of markup content.  For example, [@{SomePage$:Xyz}@] will be replaced by a definition of "Xyz" in SomePage.  Page text variables can be defined using definition markup, a line beginning with the variable name and a colon, or a special directive form (that doesn't display anything on output):

-->[@
:Xyz: some value            # definition list form
Xyz: some value             # colon form
(:Xyz: some value:)         # directive form
@]
[[#ptvend]]

* The [@(:pagelist:)@] command can now filter pages based on the contents of page variables and/or page text variables.  For example, the following directive displays only those pages that have an "Xyz" page text variable with "some value":

-->[@(:pagelist $:Xyz="some value":)@]

  Wildcards also work here, thus the following pagelist command lists pages where the page's title starts with the letter "a":

-->[@(:pagelist $Title=A* :)@]

* The if= option to [@(:pagelist)@] can be used to filter pages based on conditional markup:

-->[@(:pagelist if="auth upload {=$FullName}":)@]  pages with upload permission
-->[@(:pagelist if="date today.. {=$Name}":)@] pages with names that are dates later than today

* Spaces no longer separate wildcard patterns -- use commas.  (Most people have been doing this already.)

* Because page variables are now "relative", the [@{$PageCount}, {$GroupCount}, {$GroupPageCount}@] variables used in pagelist templates are now [@{$$PageCount}, {$$GroupCount}, {$$GroupPageCount}@].

* One can now use [@{$$option}@] in a pagelist template to obtain the value of any 'option=' provided to the [@(:pagelist:)@] command.

* The [@(:pagelist:)@] directive no longer accepts parameters from urls or forms by default.  In order to have it accept such parameters (which was the default in 2.1 and earlier), add a [@request=1@] option to the [@(:pagelist:)@] directive.

* The [@count=@] option to pagelists now accepts negative values to count from the end of the list.  Thus [@count=5@] returns the the first five pages in the list, and [@count=-5@] returns the last five pages in the list.  In addition, ranges of pages may be specified, as in [@count=10..19@] or [@count=-10..-5@].

* Pagelist templates may have special [@(:template first ...:)@] and [@(:template last ...:)@] sections to specify output for the first or last page in the list or a group.  There's also a [@(:template defaults ...:)@] to allow a template to specify default options.

* PmWiki comes with an ability to cache the results of certain [@(:pagelist:)@] directives, to speed up processing on subsequent visits to the page.  To enable this feature, set $PageListCacheDir to the name of a writable directory (e.g., ''work.d/'').

* [[#elseifelse]]The [@(:if ...:)@] conditional markup now also understands [@(:elseif ...:)@] and [@(:else:)@].  In addition, markup can nest conditionals by placing digits after if/elseif/else, as in [@(:if1 ...)@], [@(:elseif1 ...:)@], [@(:else1:)@], etc.

* The [@(:if date ...:)@] conditional markup can now perform date comparisons for dates other than the current date and time.

* [[WikiTrails]] can now specify #anchor identifiers to use only sections of pages as a trail.

* A new [@(:if ontrail ...:)@] condition allows testing if a page is listed on a trail.

* The extensions .odt, .ods, and .odp (from OpenOffice.org) are now recognized as valid attachment types by default.

* A new [[blocklist]] capability has been added to the core distribution.  It allows blocking of posts based on IP address, phrase, or regular expression, and can also make use of publicly available standard blocklists.  See [[PmWiki.Blocklist]] for details.

* There is a new [[SiteAdmin.AuthList]] page that can display a summary of all password and permissions settings for pages on a site.  This page is restricted to administrators by default.

* There are new [@{$PasswdRead}@], [@{$PasswdEdit}@], etc. variables that display the current password settings for a page (assuming the browser has attr permissions or whatever permissions are set in $PasswdVarAuth).

* Forms creation via the [@(:input:)@] markup has been internally refactored somewhat (and may still undergo some changes prior to 2.2.0 release).  The new [@(:input select ...:)@] markup can be used to create select boxes, and [@(:input default ...:)@] can be used to set default control values, including for radio buttons and checkboxes.

* The [@(:input textarea:)@] markup now can take values from other sources, including page text variables from other pages.

* Specifying [@focus=1@] on an [@(:input:)@] control causes that control to receive the input focus when a page is loaded.  If a page has multiple controls requesting the focus, then the first control with the lowest value of [@focus=@] "wins".

* PmWiki now provides a ''scripts/creole.php'' module to enable Creole standard markup.  To enable this, add [@include_once('scripts/creole.php')@] to a local customization file.

* PmWiki adds a new [@{(...)}@] ''markup expression'' capability, which allows various simple string and data processing (e.g., formatting of dates and times).  This is extensible so that recipe authors and system administrators can easily add custom expression operators.

* It's now possible to configure PmWiki to automatically create Category pages whenever a page is saved with category links and the corresponding category doesn't already exist.  Pages are created only if the author has appropriate write permissions into the group.  To enable this behavior, add the following to ''local/config.php'':

-->[@$AutoCreate['/^Category\\./'] = array('ctime' => $Now);@]

* Sites with wikiwords enabled can now set $WikiWordCount['WikiWord'] to -1 to indicate that 'WikiWord' should not be spaced according to $SpaceWikiWords.

* WikiWords that follow # or & are no longer treated as WikiWords.

* Links to non-existent group home pages (e.g., [@[[Group.]]@] and [@[[Group/]]@]) will now go to the first valid entry of $PagePathFmt, instead of being hardcoded to "Group.Group".  For example, to set PmWiki to default group home pages to [@$DefaultName@], use

-->[@$PagePathFmt = array('{$Group}.$1', '$1.{$DefaultName}', '$1.$1');@]

* PmWiki now provides a $CurrentTimeISO and $TimeISOFmt variables, for specifying dates in ISO format.

* [[(Cookbook:)Cookbook]] authors can use the internal PmWiki function UpdatePage (temporarily documented at [[(Cookbook:)DebuggingForCookbookAuthors]]) to change page text while preserving history/diff information, updating page revision numbers, updating RecentChanges pages, sending email notifications, etc.

* [[Skin templates]] are now required to have <!--HTMLHeader--> and <!--HTMLFooter--> directives.  Setting $EnableSkinDiag causes PmWiki to return an error if this isn't the case for a loaded skin.  Skins that explicitly do not want HTMLHeader or HTMLFooter sections can use <!--NoHTMLHeader--> and <!--NoHTMLFooter--> to suppress the warning.

* Added a new "pre" wikistyle for preformatted text blocks.

* The xlpage-utf-8.php script now understands how to space UTF-8 wikiwords.  

* Searches on utf-8 site are now case-insensitive for utf-8 characters.

* Many Abort() calls now provide a link to pages on pmwiki.org that can explain the problem in more detail and provide troubleshooting assistance.

* PmWiki no longer reports "?cannot acquire lockfile" if the visitor is simply browsing pages or performing other read-only actions.

* The $EnableReadOnly configuration variable can be set to signal PmWiki that it is to run in "read-only" mode (e.g., for distribution on read-only media).  Attempts to perform actions that write to the disk are either ignored or raise an error via Abort().

* Including authuser.php no longer automatically calls ResolvePageName().

* Authentication using Active Directory is now simplified.  In Site.AuthUser or the $AuthUser variable, set "ldap://name.of.ad.server/" with no additional path information (see PmWiki.AuthUser for more details).

* Pages are now saved with a "charset=" attribute to identify the character set in effect when the page was saved.

* The phpdiff.php algorithm has been optimized to be smarter about finding smaller diffs.

* Removed the (deprecated) "#wikileft h1" and "#wikileft h5" styles from the pmwiki default skin.

* The mailposts.php and compat1x.php scripts have been removed from the distribution.

!! Version 2.1.27 (2006-12-11)

This version backports from 2.2.0-beta a bugfix for $TableRowIndexMax and also support for the [@{*$Variable}@] markup.

!! Version 2.1.26 (2006-09-11)

This version fixes a bug in feeds.php that would cause feed entries to be mixed up.

!! Version 2.1.25 (2006-09-08)

This release fixes a bug in authuser.php introduced by the 2.1.24 release.

The skin template code has also been extended to allow [@<!--XMLHeader-->@] and [@<!--XMLFooter-->@] as aliases for [@<!--HTMLHeader-->@] and [@<!--HTMLFooter-->@].

!! Version 2.1.24 (2006-09-06)

This release makes some improvements and fixes to the [[AuthUser]]
capability.

A bug in authuser.php that had trouble dealing with non-array values in $AuthUser has been fixed.

It is now possible to specify group memberships from ''local/config.php'' (remember that such entries must come ''before'' including the ''authuser.php'' script):

    # alice and bob's passwords
    $AuthUser['alice'] = crypt('alicepassword');
    $AuthUser['bob'] = crypt('bobpassword');

    # members of the @writers and @admins groups
    $AuthUser['@writers'] = array('alice',  'bob');
    $AuthUser['@admins'] = array('alice', 'dave');

    # carol is a member of @editors and @writers
    $AuthUser['carol'] = array('@editors', '@writers');

AuthUser can now read from Apache-formatted .htgroup files.  The location of the .htgroup file can be done either in ''local/config.php'' or [[Site.AuthUser]]

    # local/config.php:
    $AuthUser['htgroup'] = '/path/to/.htgroup';

    # Site.AuthUser
    htgroup: /path/to/.htgroup

!! Versions 2.1.21, 2.1.22, 2.1.23 (2006-09-05, 2006-09-06)

This release closes a potential security vulnerability for sites 
that are running with 'register_globals' set to on.  Details of
the vulnerability will be forthcoming on the mailing list
and site.

Sites that are running with PHP 'register_globals' and 'allow_url_fopen'
set to 'On' should upgrade to this release at the earliest
opportunity.  If upgrading isn't an option, contact Pm for
a patch to older versions.

There is now a tool available to analyze PmWiki sites for security
and other configuration settings, see [[PmWiki:SiteAnalyzer]].

Version 2.1.23 also corrects a bug that prevented PmWiki from being
able to read pagefiles created by versions of PmWiki before 0.5.6.

!! Version 2.1.20 (2006-09-04)

More minor bugfixes:
* Corrected a bug with WikiWord references appearing in the [@(:attachlist:)@] markup.
* Restore ability to remove/override PmWiki's default CSS settings.

!! Version 2.1.19 (2006-08-30)

This release provides a number of very minor bugfixes and
enhancements:

* Fixed a bug in the pageindex code that was causing it to not regenerate as quickly as it should.
* Fixed image/object/embed handling in wikistyles to better support the [[Cookbook:Flash]] recipe.
* Fixed a bug with wikistyles and input form tags.

The next release(s) may have a number of substantial code
enhancements and changes, so this release simply closes out
a few items before introducing those changes.

!! Version 2.1.18 (2006-08-28)

This release closes a potential cross-site scripting vulnerability
that could allow authors to inject Javascript code through the
various table markups.

The release also adds a new [@(:input image:)@] markup to generate
image input tags in forms.

Finally, this release corrects a problem with [@?action=print@]
failing to properly set the [@{$Action}@] page variable.

!! Version 2.1.17 (2006-08-26)

This release fixes a long-standing bug with $EnableIMSCaching
(PITS:00573), whereby login/logout operations wouldn't invalidate 
browser caches, causing some people to see versions of a page prior
to the login/logout taking place.  

The new IMS caching code maintains a "imstime" cookie in the 
visitor's browser that keeps track of the time of last login, 
logout, author name change, or site modification.  This cookie
is then used to determine the proper response to browser requests
containing If-Modified-Since headers.  (Previously only the
time of the last site modification was available.)  

Browsers which do not accept cookies will effectively act as
though IMS caching is disabled.

!! Version 2.1.16 (2006-08-26) [[#v2116]]

This release makes some improvements to skin handling -- primarily
this improves the capability of relocating skin files to other
locations, and to provide the ability for recipes to insert items
at the ''end'' of HTML output.

This release introduces a [@<!--HTMLFooter-->@] directive into
[[skin templates]], which allows recipes and local
customizations to insert output near the end of a document 
using a $HTMLFooterFmt array from PHP.

Also, the [@<!--HeaderText-->@] directive, which inserts the
contents of $HTMLHeaderFmt into the output, has now been
renamed to [@<!--HTMLHeader-->@].  PmWiki will continue to
recognize [@<!--HeaderText-->@] to preserve compatibility with
existing skins, but [@<!--HTMLHeader-->@] is preferred.

A new $SkinLibDirs array has been introduced which allows
the source locations and urls for skins to be specified from
a customization file.  By default $SkinLibDirs is set as

  $SkinLibDirs = array("./pub/skins/\$Skin"      => "$PubDirUrl/skins/\$Skin",
                  "$FarmD/pub/skins/\$Skin" => "$FarmPubDirUrl/skins/\$Skin");

The keys (on the left) indicate the places to look for a "skin .tmpl 
file" in the filesystem, while the values (on the right) indicate the
url location of the "skin css file".  Modifying the value of 
$SkinLibDirs allows a skin .tmpl file to be located anywhere on the 
filesystem.

As far as I can see, none of the changes introduced by this
release should have any sort of negative impact on existing
sites, so it should be safe to upgrade.  (If I'm wrong, please
let me know.)

!! Version 2.1.15 (2006-08-25)

This release includes a number of feature enhancements and code cleanups
as reported or requested by administrators.

First, AuthUser's LDAP authentication system now allows the use of
a [@?filter@] parameter, consistent with urls used for mod_auth_ldap
authorization in Apache.  See the newly updated LDAP section of the
[[AuthUser]] documentation for more details.

A chicken-and-egg problem with the [@@_site_*@] authorization groups
has been resolved.  It's now possible to have a page's read authorization
refer to things such as [@_site_edit@].

Also, the RetrieveAuthPage() function -- used for retrieving pages only
if the visitor is authorized to do so -- now recognizes a special
level parameter of 'ALWAYS', which means to always authorize access
regardless of the browser or visitors current permissions.  This
may be useful for allowing certain operations to take place from
within trusted scripts without having to grant full authorization
to the browser.

Hardcoded instances of the ''local/'' directory now use a
customizable $LocalDir variable.  This variable controls where
PmWiki looks for ''local/config.php'' and per-group customization 
files.  It may be useful for some [[Wiki Farm(s)]] contexts.  Note that
this does not change or affect the location of 
''$FarmD/local/farmconfig.php''.

Some minor internal changes have been made to 
''scripts/wikistyles.php'' to better accommodate the 
wikipublisher recipe.  It's probably better if we don't try
to explain them.  :-)

!! Version 2.1.13, 2.1.14 (2006-08-15, 2006-08-16)

This release fixes a bug in handling numeric passwords, and also
allows ldaps:// authentication sources.

!! Version 2.1.12 (2006-08-07)

This version introduces the ability to nest divs and tables.
The standard [@(:table:)@] and [@(:div:)@] markups are still
available, except that a [@(:div:)@] may contain a [@(:table:)@]
and vice-versa.  

As in previous versions of PmWiki, the [@(:div:)@] markup
automatically closes any previous [@(:div:)@].  However, there
are now [@(:div1:)@], [@(:div2:)@], etc. markups (and the
corresponding [@(:div1end:)@], [@(:div2end:)@], ...) which can be
used to uniquely distinguish divs for nesting purposes.

To restore PmWiki's previous "non-nested" div behavior, set
$Transition['nodivnest'] = 1; in a local customization file.

Other changes in this release:
* Add a [@(:noaction:)@] directive to suppress display of page actions.
* Allow anchor tags to contain colons, hyphens, and dots.
* Add "white-space" as an allowed wikistyle.
* Other minor bug fixes and typographical corrections.

!! Version 2.1.11 (2006-06-09)

This is a minor update that prevents [@%define=%@] wikistyles
from generating empty paragraphs in the HTML output.  Prior to
this release, markup lines containing only wikistyle definitions
would often generate empty paragraphs (<p></p>), this release
changes things so that a markup line beginning with [@%define=@]
and containing only wikistyle definitions will not initiate
a new paragraph.

!! Version 2.1.10 (2006-06-03)

Version 2.1.4 introduced an [@{$Action}@] page variable that would
contain the current [@?action=@] value.  Unfortunately, this page
variable conflicted with a pre-existing [@$Action@] global variable
that was being used by skins to display a human-friendly form of
the current action.  Since there's not really a clean way to resolve
this, I've decided to keep [@{$Action}@] as a page variable
with the current action value (as introduced in 2.1.4), and change 
the global for skins to be $ActionTitle.  This will require updating
skins to use $ActionTitle instead of $Action.  I apologize for the
conflict.

This release adds a Site.LocalTemplates page for the [@fmt=#xyz@]
option in pagelist and search results.  The list of pages to be
searched can be customized via the $FPLTemplatePageFmt variable.
The [@fmt=#xyz@] option will now also search the current page for
a matching template before searching Site.LocalTemplates
and Site.PageListTemplates.

The 'pmwiki' skin now places a <span> around the "Recent Changes"
link in the header to make it somewhat easier to style.

!! Version 2.1.9 (2006-06-02)

This release fixes a long-standing and difficult-to-find bug with
the handling of [@[[~Author]]@] links.

!! Version 2.1.8 (2006-06-01)

This release simply changes the $NotifyListFmt variable to be
$NotifyListPageFmt (more descriptive), and adds a $NotifyList
array that can be used to specify notification entries from
a configuration file.

!! Version 2.1.7 (2006-05-31)

This release introduces a variety of improvements and bugfixes.

'''Vspace paragraphs are now divs:'''
Version 2.1.7 changes the way that PmWiki handles vertical
space in output (the infamous [@<p class='vspace></p>@] sequence).
Instead of using paragraphs, PmWiki now generates 
[@<div class='vspace'></div>@] for vertical space sequences.
In addition, PmWiki is able to collapse the vspace <div> with
any subsequent paragraph tags, such that a sequence like

    <div class='vspace></div><p>...paragraph text...</p>

is automatically converted to

    <p class='vspace'>...paragraph text...</p>

This allows for better control over paragraph spacing.  It is
expected that this change in vspace handling will not have
any detrimental effects on existing sites.  Sites that have
set custom values for $HTMLVSpace will continue to use the
custom value.  A site that wants to restore PmWiki's earlier
handling of vspace can do so by adding the following to
''local/config.php'':

    $HTMLVSpace = "<p class='vspace'></p>";

'''Improved email notifications of changes:'''  Version 2.1.7
incorporates a ''notify.php'' script that provides improved
capabilities for sending email notifications in response to
page changes.  This script is intended to replace the previous
[[(PmWiki:)MailPosts]] capability, which is now deprecated (but will
continue to be supported in PmWiki 2.1.x).  Details and 
instructions for using notify.php are in the [[PmWiki.Notify]] page.

'''Added 'group home page' syntax:''' A group name followed
by only a dot or slash is automatically treated as a reference
to the group's home page, whatever it happens to be.  This simplifies
some pagelist templates as well as a number of other items. 
In particular, group links in pagelist output now points to the
correct locations (instead of being a page in the current group).

Several bugs and vulnerabilities have been fixed:
* The default width of edit forms is now more appropriate for Internet Explorer.
* Authentication failure messages from LDAP are now suppressed.
* Some cross-site scripting vulnerabilities in uploads and page links have been corrected (courtesy Moritz Naumann, http://moritz-naumann.com).
* A problem with invalid pagenames resulting in redirect loops has been corrected.

!! Version 2.1.6 (2006-05-22)

The primary improvement in this release is the addition of 
a pagename argument to the [@(:if auth:)@] conditional markup.
Thus one can display markup based on a visitor's authorization
to a page other than the current one.  For example, to test
for edit privileges to `Main.WikiSandbox, one would use
[@(:if auth edit Main.WikiSandbox:)@].  As before, if the
pagename is omitted the directive tests authorization to
the current page.

This release also restores the ability to have hyphens in
InterMap link names.

Lastly, the release closes a potential cross-site scripting
vulnerability in the WikiTrail markup, and provides some small
performance improvements.

!! Version 2.1.4, 2.1.5 (2006-03-29)

This release fixes a few more bugs:
* Pagelist-based feeds using ?action=rss work again.
* Multi-term searches with special characters is fixed.

The release also adds a couple of items:
* There is now an [@{$Action}@] page variable.
* Usernames and passwords submitted to authuser.php can contain quotes.
* The [@(:attachlist:)@] command now uses a natural case sort.

!! Version 2.1.3 (2006-03-17)

This release fixes a bug that prevents the [@lines=@] option from
working on sites running PHP 5.1.1 or later.  It also re-fixes
a bug involving empty passwords and LDAP authentication.

!! Version 2.1.2 (2006-03-16)

This release fixes a bug with handling "nopass" passwords.  It also
makes some speed improvements to large web feeds, and fixes a couple
of minor HTML tag mismatches.

!! Version 2.1.1 (2006-03-13)

This release primarily fixes a bug with passwords containing
multiple authorization groups, and in the process slightly liberalized
the formatting of "@group" and "id:name" handling.  This release also 
adds a new mechanism for managing and displaying FAQ pages.

!! Version 2.1.0 (2006-03-12)

This set of release notes is fairly lengthy, as it chronicles all of the changes since 2.0.13 (four months of development).  A lot remains the same, but some changes warrant extra care when upgrading from a 2.0.x version to 2.1.0 (thus the major revision number change).  As always, questions and issues can be mailed to the pmwiki-users mailing list.

Here's the list:

* WikiWords are now disabled by default.  To enable them, set "$LinkWikiWords = 1;" in a [[local customization(s)]] file.  As of 2.1.beta2, you can now leave WikiWords enabled but have links to non-existent pages display without decoration -- to do this, place the following lines in ''pub/css/local.css'':

    span.wikiword a.createlink { display:none; }
    span.wikiword a.createlinktext 
      { border-bottom:none; text-decoration:none; color:inherit; }

* The [@(:pagelist:)@] code has been substantially revised.  Pagelist formatting can now be specified using markup, and several defaults are available from [[Site.PageListTemplates]].  Also, several built-in pagelist formatting functions (FPLSimple, FPLByGroup, FPLGroup) are now removed in favor of the template code.  The FPLByGroup function can be restored by setting $Transition['fplbygroup']=1; . '''Remark:''' Check to see if your page [[Site.PageListTemplates]] is not passwordprotected for viewing, otherwise the resulting pagelist will not be shown. 

* [@(:pagelist:)@] now also understands wildcards in @@group=@@ and @@name=@@ arguments, as well as excluding specific names and groups.

* [@(:pagelist:)@] now has an "order=random" option.

* [@(:searchbox:)@] now accepts "group=", "link=", "list=", etc. options to be passed along to the search results.  It also accepts a "target=" option that identifies the page on which to send the search query.

* [@?action=search@] will display the contents of the current page if it contains a [@(:@][@searchresults:)@] directive, otherwise it uses the content of the page identified by $PageSearchForm (default is the search page for the current language translation).  

* PmWiki no longer maintains a ".linkindex" file -- it now has a ".pageindex" file that contains not only a table of links, but also words used in each page (to speed up term searches).  The maintenance of the .pageindex file can be disabled by setting $PageIndexFile=''; 
       
* The $EnablePageListProtect variable now defaults to true, so that read-only pages appear in pagelists only if the visitor has read authorization.  Note that this can also slow down some [@(:pagelist:)@] and search commands, so if the site doesn't have any read-only pages or if you aren't worried with cloaking read-only pages from searchlists, it might be worth setting $EnablePageListProtect=0; .

* Whitespace indentation rules now exist and are enabled by default.  Any line that begins with whitespace and aligns with a previous list item is considered to be "within" that list item.  Text folds and wraps as normal, and the [@(:linebreaks:)@] directive is honored.  To turn off whitespace indentation, use [@DisableMarkup('^ws');@].

* A single blank line after a [@!!Heading@] is silently ignored.

* The [@(:redirect:)@] directive is now a true markup, and can be embedded inside conditional markups or includes.  It also allows redirecting to an anchor in a page, such as [@(:redirect PageName#anchor:)@].  A new [@from=@] option allows the redirect to take place only from pages that match the given wildcard specification.  The [@status=@] option allows a 301, 302, 303, or 307 HTTP status code to be returned.

* The built-in authorization function has gone through some substantial internal changes, however these changes should be fully backward compatible so that it doesn't impact any existing sites.  (If it ''does'' cause a problem, please let me know so I can investigate why!)  The password prompts are now specified by an admin-customizable Site.AuthForm page.  In addition, the authorization function no longer creates PHP sessions for visitors that aren't being authenticated.

* The authuser.php has likewise been substantially updated.  The new version should have complete backwards compatibility with previous authuser.php settings, but this version also offers the ability to configure authentication resources and authorization groups through the [[Site.AuthUser]] page.  Note that by default the Site.AuthUser page can only be edited using the admin password.

* The $EnableSessionPasswords variable can be used to control whether passwords are held in PHP sessions.  (This does not affect user authentication via [[AuthUser]], however.)

* The $Author variable now defaults to $AuthId if not otherwise set by a script or cookie.

* The [[Site.SideBar]] page now defaults its edit password to the sitewide edit password (in $DefaultPasswords['edit']).

* PmWiki now supports a "draft edit" mode, enabled by $EnableDrafts = 1.  This creates a "Save as draft" button that will save a page under a "-Draft" suffix, for intermediate edits.

* There is now an ?action=login action available.

* A potential security vulnerability for sites running PHP 5 with register_globals enabled has been fixed.

* The [@[[PageName |+]]@] markup is now available by default; this creates a link to `PageName and uses that page's title as the link text.

* What used to be "markup variables" are now "[[page variables]]".  These are always specified using the @@{$''variable''}@@ syntax, and can be used in markup and in $...Fmt strings.  In addition, one can request a value for a specific page by placing the pagename in front of the variable, as in @@{''pagename''$''variable''}@@.

* The ''scripts/rss.php'' script is now ''scripts/feeds.php'', and is a complete redesign for [[web feed(s)]] generation.  The new version supports UTF-8 and other encodings, can generate Atom 1.0 ([@?action=atom@]), Dublin Core Metadata ([@?action=dc@]) output, and enclosures for podcasting.  It also allows feeds to be generated from trails, groups, categories, and backlinks, and provides options (same as pagelists) for sorting and filtering the contents of the feed.  Most sites can simply switch to using [@include_once("scripts/feeds.php");@] instead of the previous ''rss.php'' include.  The ''rss.php'' file has been removed from the distribution (but still works with PmWiki 2.1 for those sites that wish to continue using it).

* [[PmWiki/InterMap]] entries can now come from a `Site.InterMap page as well as the ''local/localmap.txt'' and ''local/farmmap.txt'' files.  The format of these files has changed slightly, in that the InterMap name should now have a colon after it (previously the colon was omitted).

* We can now provide better control of robot (webcrawler) interactions with a site to reduce server load and bandwidth.  The $RobotPattern variable is used to detect robots based on the user-agent string, and any actions not listed in the $RobotActions array will return a 403 Forbidden response to robots.  In addition, setting $EnableRobotCloakActions will eliminate any forbidden ?action= values from page links returned to robots, which will reduce bandwidth loads from robots even further (PITS:00563).

* Non-existent page handling has been improved; whenever a browser hits a non-existent page, PmWiki returns the contents of Site.PageNotFound and a 404 ("Not Found") status code.

* Page links that have "?action=" in their query arguments are now treated as "existing page" links even if the page does not exist.

* The PmWiki default skin now adds rel='nofollow' to various action links.

* Some of the CSS styles in the PmWiki default skin have been changed for better presentation.

* The gui edit buttons have transparent (instead of white) borders so they integrate better into skins.

* The $EnableIMSCaching variable is now much smarter, it can detect changes in local customization files as well as pages.

* [[PmWiki/WikiStyles]] can now make percentage specifications by using "pct" to mean "%".

* Class attributes in [[WikiStyle(s)]] shortcuts are now cumulative, so that [@%class1 class2%@] results in [@class='class1 class2'@] instead of just [@class='class2'@] in the output.

* A problem with the [@(:include PageName#from#:)@] markup not working has been fixed (PITS:00560).

* Viewing a GroupHeader or GroupFooter page no longer displays the contents twice.

* It's now easier to share pages among multiple sites (e.g., [[WikiFarms]]), see Cookbook:SharedPages (PITS:00459).

* A problem with nested apostrophe markups has been fixed (PITS:00590).

* PmWiki is now smarter about not surrounding block HTML tags with <p>...</p> tags.

* If an [@[[#anchor]]@] is used more than once in a page, only the first generates an actual anchor (to preserve XHTML validity).

* There are now [@(:if equal ...:)@] and [@(:if exists pagename:)@] [[conditional markup]]s.

* Compound conditional markup expressions are now possible -- e.g. [@(:if [ group PmWiki && ! name PmWiki ] :)@] .

* Added an $InputValues array that can supply default values for certain form controls (PITS:00566).

* The default setting of $UploadUrlFmt is now based on $PubDirUrl instead of $ScriptUrl.

* The $text global variable has been removed (use $_GET['text'], $_POST['text'], or $_REQUEST['text']).

* A possible problem with url-encoding of attachments with non-ASCII characters has been addressed (PITS:00588).

* Page actions in non-existent pages no longer display with non-existent link decorations.

* A README.txt file has been added, and several documentation files are now available through the docs/ directory.
  
* PmWiki is no longer available through CVS on sourceforge.net.  It is now available via SVN on pmwiki.org, at svn://pmwiki.org/pmwiki/tags/latest .  For more details, see PmWiki:Subversion.

* The $NewlineXXX variable (deprecated in 2.0.0) has been removed.

* There is experimental support for server-side caching of pages that take a long time to render; this is currently an unsupported feature and may be removed in future releases.

%red%Wiki administrators should note that from this release on PmWiki defaults to having WikiWords disabled.

To make sure WikiWords are enabled, use [@$LinkWikiWords = 1;@] in
the ''local/config.php'' file.

----
Bugs and other requests can be reported to the PmWiki Issue Tracking 
System at http://www.pmwiki.org/wiki/PITS/PITS.  Any help
in testing, development, and/or documentation is greatly appreciated..

[[(PmWiki:)Release Notes archive]] - notes for versions older than 2.1.0.

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Requirements</pagename>
<data><![CDATA[(:Summary:Prerequisites for running the PmWiki wiki engine:)(:Audience: administrators (basic) :)
Prerequisites for running the PmWiki wiki engine:
# [[http://php.net/ | PHP]] 4.1 or later
** [[http://gophp5.org/ | PHP 5]] or later is recommended
# Some sort of webserver that can run PHP scripts.

PmWiki has been reported to work with the following OS/webserver combinations:
* Apache 1.3 or 2.0, on roughly anything (Unix, Linux, Windows, and Mac OS/X)
** [[http://httpd.apache.org/ | Apache 2.2]] or later is recommended
* Microsoft Internet Information Server, on Windows

* I got it to work on appWeb (a very small, php-enabled webserver) executing on a Linksys NSLU2 Network Storage Link device (runs Unslung 5.5 beta which is a Linux derivate for embedded systems). Still have to work out why file-uploads does not seem to work, however. --Hans-Göran Puke

* PmWiki works very well on x86 Linux + [[http://www.litespeedtech.com/|LiteSpeedWeb Server]] Standard Edition  --Jeff Muday

PmWiki has been reported not to work on:
* Mac OS before Mac OS X because there's no PHP available

The [[(Cookbook:)Standalone]] recipe provides a special, bare-bones webserver application that can be used to run PmWiki in places where another webserver isn't available.
PmWIki can also be run from a [[Cookbook:WikiOnAStick | USB drive]].]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Search</pagename>
<data><![CDATA[(:description A page for advanced and customized search options:)
(:Summary:Targeting and customising search results:)
(:if !equal {$Action} "search":)
>>rframe width=300pcx font-size=smaller<<
-< '''This page uses [[#example|custom]] searches.'''
For regular searches, view another page.
>><<
PmWiki provides a basic search function.  While it is not powered by a "search engine", it can be tweaked to produce results that are ''targeted'' and ''customized.'' 

!!!! Targeted searches
Searches can be targeted to restrict the search to certain pages.  For example, a search can be restricted based on groups, where, for instance, "group=PmWiki" searches only the PmWiki group, and "group=-PmWiki" searches only pages that are not in the PmWiki group.  In addition to groups, searches can be restricted based on page names ("name="), [[wiki trails]] ("trail="), backlinks ("link=") and other criteria (e.g. "list=normal") and capped at a maximum number ("count=").  For documentation about each of these parameters, see [[page lists]].   

!!!! Customized display
The display of search results can be customized to control the format, content and order of the returned results.  Format and content are selected by using "fmt=" to specify a pagelist template that determines layout, such as list styles, and page elements, such as title and description.  The "order=" option allows results to be sorted according to different criteria, such as name and title.  For documentation about each of these parameters, see [[page lists]].   For examples of pagelist template formats see [[Site.Page List Templates]], (:if exists Site.LocalTemplates:)[[Site.Local Templates]],(:ifend:) and [[Cookbook:Pagelist Template Samples]].

!!!! Anyone, anywhere
'''Readers''' can create targeted and customized search results simply by typing the relevant parameters , e.g. "group=PmWiki", into search boxes together with their search string.  '''Authors''' can predefine such targeted and customized searches by incorporating the parameters into pages using the [@(:searchbox:)@] and [@(:searchresults:)@] directives (documented at [[PageLists]]).

[@(:searchresults:)@] can be customized by editing page [@Site.Search@].

See also
* $PageSearchForm 
* $SearchBoxOpt
* $SearchPatterns

[[#example]]
!!!!Try it: this page generates custom searches
Any search that is run from this page will automatically generate pre-defined sets of search results that: '''''target''''' different clusters of pages (documentation, cookbook and PITS, if available); use '''''customized''''' formats, content and ordering; and '''''reveal''''' the specific parameters used to generate each search result.  Whether you use the search box below, or the regular search box that appears at the top of this page, any search that you run from this page will provide the customized results.  
(:searchbox size=20:)

(:ifend:)
(:if equal {$Action} "search":)
[[{$Name}|back]]\

(:table border=0 width=100%:)\

(:cell width=30%:)\

!!!! [[Site/AllRecentChanges?q=PmWiki/+order%3Dname&action=search|All Documentation]]
(:searchresults group=PmWiki fmt=#onegroupdesc order=name:)
(:if expr exists Cookbook.Cookbook and equal {$Action} "search":)
(:cell width=35%:)\

!!!! [[Cookbook.Cookbook|All Cookbook Recipes]]
(:searchresults group=Cookbook fmt=#summary order=name:)
(:if expr exists PITS.PITS and equal {$Action} "search":)
(:cell width=35%:)\

!!!! [[PITS.PITS|PITS (Issue Tracking)]]
(:searchresults group=PITS fmt=#summary name=0* order=-name:)
(:if equal {$Action} "search":)
(:tableend:)

Note: The strings that were used to target and format each search result are shown above in '''italics'' and can be entered directly into a regular search box.

(:title Search:)
(:if false:)

[[#onegroupdesc]]
[[{=$Group}/{=$Name}]] %font-size=smaller font-style=italic%{=$Description}%%\\
[[#onegroupend]]

[[#summary]]
[[{=$Group}/{=$Name}]] %font-size=smaller font-style=italic%{=$:Summary}%%\\
[[#summaryend]]
(:ifend:)]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Security</pagename>
<data><![CDATA[(:Summary: Resources for securing your PmWiki installation:)
Aspects of PmWiki security are found on the following pages:

Pages distributed in a PmWiki release:
* [[PmWiki/Passwords]] {PmWiki/Passwords$:Summary}
* [[PmWiki/Passwords Admin]] {PmWiki/PasswordsAdmin$:Summary}
* [[PmWiki/Url Approvals]] {PmWiki/UrlApprovals$:Summary}
* [[(PmWiki:)Site Analyzer]] {PmWiki/SiteAnalyzer$:Summary}
* [[PmWiki/Blocklist]] {PmWiki/Blocklist$:Summary}
* [[PmWiki/Notify]] {PmWiki/Notify$:Summary}
* [[PmWiki/Security variables]] {PmWiki/SecurityVariables$:Summary}

[[Cookbook(:/)]] Pages

* [[Cookbook:Cookbook#Security | Cookbook index for Security recipes]]
* [[Cookbook:Secure attachments]] Protecting uploaded attachments
* [[Cookbook:Web server security]] Making the server more secure with .htaccess
* [[Cookbook:Farm security]] Making Farm installations secure
* [[Cookbook:EProtect]] Hide e-mail address
* [[Cookbook:Protect email]] Obfusticate email addresses
* [[Cookbook:Audit images]] Check to see what images have been uploaded to your wiki.
* [[Cookbook:Private groups]] Create and secure private groups on a public wiki
* [[Cookbook:Only one login]] Only allow 1 login at the same time for a username
* [[Cookbook:Session guard]] Protects against Session Theft

>>faq<< [[#faq]]

Q: How do I report a possible security vulnerability of PmWiki?

A: [[http://www.pmichaud.com|Pm]] wrote about this in [[http://pmichaud.com/pipermail/pmwiki-users/2006-September/031793.html | a post to pmwiki-users from September 2006]]. In a nutshell he differentiates two cases:
## The possible vulnerability isn't already known publicly: In this case please contact Pm by private mail.
## The possible vulnerability is already known publicly: In this case feel free to discuss the vulnerability in public (e.g. on [[http://www.pmichaud.com/mailman/listinfo/pmwiki-users | pmwiki-users]]).
See [[http://pmichaud.com/pipermail/pmwiki-users/2006-September/031793.html | his post mentioned above]] for details and rationals.

Q: What about the botnet security advisory at %newwin%[[http://isc.sans.org/diary.php?storyid=1672]]?

A: Sites that are running with PHP's ''register_globals'' setting set to "On" and versions of PmWiki prior to 2.1.21 may be vulnerable to a botnet exploit that is taking advantage of a bug in PHP.  The vulnerability can be closed by turning ''register_globals'' off, upgrading to PmWiki 2.1.21 or later, or upgrading to PHP versions 4.4.3 or 5.1.4.  [[<<]]In addition, there is a test at [[PmWiki:SiteAnalyzer]] that can be used to determine if your site is vulnerable.

[[#wikivandalism]]
!! Wiki Vandalism
:Assumptions: you are using a [[PmWiki/Blocklist]] and [[PmWiki/Url approvals]].
: :You don't want to resort to [[PmWiki/password(s)]] protecting the entire wiki, that's not the point after all.
: :Ideally these protections will be invoked in @@config.php@@

Q: How do I stop pages being [[PmWiki/DeletingPages|deleted]], eg password protect a page from deletion?
A: Use Cookbook:DeleteAction and password protect the page deletion [[(available) action(s)]] by adding [@$DefaultPasswords['delete'] = '*';@] to @@config.php@@ or password protect the action with @@$HandleAuth['delete'] = 'edit';@@
->or @@$HandleAuth['delete'] = 'admin';@@ to require the edit or admin password respectively.

Q: How do I stop pages being replaced with an empty (all spaces) page?
A: Add [@block: /^\s*$/@] to your [[PmWiki/blocklist]].

Q: how do I stop pages being completely replaced by an inane comment such as ''excellent site'', ''great information'', where the content cannot be blocked?
A: Try using the newer [[PmWiki/Blocklist#automaticblocklists | automatic blocklists]] that pull information and IP addresses about known wiki defacers.

A: (OR) Try using [[Cookbook:Captchas]] or [[Cookbook:Captcha]] (note these are different).

A: (OR) Set an edit password, but make it publicly available on the [[{$SiteGroup}.AuthForm]] template.

Q: How do I password protect all common pages in all groups such as recent changes, search, group header, group footer, and so on?
A: Insert the following lines into your local/config.php file. Editing these pages then requires the admin password.
->[@
## Require admin password to edit RecentChanges (etc.) pages.
if ($action=='edit'
    && preg_match('/\\.(Search|Group(Header|Footer)|(All)?RecentChanges)$/', $pagename))
  { $DefaultPasswords['edit'] = crypt('secret&nbsp;phrase'); }
@]

Note that all GroupAttributes pages are protected by the attr password.

'''Alternative:''' you can require 'admin' authentication for these pages:
->[@
## Require admin password to edit RecentChanges (etc.) pages.
if ($action=='edit' 
    && preg_match('(Search|Group(Header|Footer)|(All)?RecentChanges)', $pagename))
  { $HandleAuth['edit'] = 'admin'; }
@]

Q: How do I password protect the creation of new groups?
A: See [[Cookbook:Limit Wiki Groups]] {Cookbook.LimitWikiGroups$:Summary}

Q: How do I password protect the creation of new pages?
A: See [[Cookbook:Limit new pages in Wiki Groups]] {Cookbook.LimitNewPagesInWikiGroups$:Summary}

Q: How do I take a whitelist approach where users from known or trusted IP addresses can edit, and others require a password?
A: Put these lines to local/config.php:
[@
## Allow passwordless editing from own turf, pass for others.
if ($action=='edit'
 && !preg_match("^90.68.", $_SERVER['REMOTE_ADDR']) )    
 { $DefaultPasswords['edit'] = crypt('foobar'); }
@]
Replace 90.68. with the preferred network prefix and foobar with the default password for others.

Q: How do I password protect [[PmWiki/AvailableActions|page actions]]?
A: See [[PmWiki/Passwords]] for setting in config.php  
-> @@$HandleAuth['[==]''pageactionname''[==]'] = 'pageactionname'; # along with :@@
-> @@$DefaultPasswords['[==]''pageactionname''[==]'] = crypt('secret&nbsp;phrase');@@
A: or 
-> @@$HandleAuth['[==]''pageactionname''[==]'] = 'anotherpageactionname';@@

Q: How to make a rule that allows only authors to edit their own wiki page in [[Profiles]] group?
A: Add this to your ''local/config.php''

->@@$name = PageVar($pagename, '$Name');@@
->@@$group = PageVar($pagename, '$Group');@@
->@@if($group=='Profiles') $DefaultPasswords['edit'] = 'id:'.$name;@@

Q: How do I moderate all postings?
A: Enable [[PmWiki.Drafts]]
* Set $EnableDrafts, this relabels the "Save" button to "Publish" and a "Save draft" button appears. 
* Set $EnablePublish, this adds a new "publish" authorization level to distinguish editing from publishing.

Q: How do I make a read only wiki?
A: In config.php [[PmWiki/PasswordsAdmin | set]] an "edit" password.

Q: How do I restrict access to [[PmWiki/Uploads|uploaded attachments]]?
A: See
* [[PmWiki/UploadsAdmin#direct_download|instructions]] for denying  public access to the uploads directory
* see [[Cookbook:Secure attachments]] {Cookbook.SecureAttachments$:Summary}

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.SecurityVariables</pagename>
<data><![CDATA[(:Summary:variables crucial for site security:)

:$AuthUserFunctions: (Present only when the in-built [[AuthUser]] username/password functionality is used).  An array of different authentication mechanisms to be used for user authentication.  Array keys are a tag for the mechanism; values are a function callback that will be called with the properties $pagename, $id, $password, and $pwlist.  Oh... could someone else make this make sense, please?!

:$DefaultPasswords: Specifies default passwords for user admin or actions (edit, read, upload). See [[PmWiki/PasswordsAdmin#settingsitewidepasswords]].

:$EnablePostAttrClearSession:A switch to control whether or not changing a page's attributes causes any existing passwords to be forgotten. The default is that changing attributes forgets any passwords entered; this can be changed by setting $EnablePostAttrClearSession to zero.

:$EnableSessionPasswords: Control whether passwords are saved as part of the session.  If set to zero, then session passwords are never saved (although any [[AuthUser]] authentications are still remembered).

:$SessionEncode: Function to use to encode sensitive information in sessions.  Set this to NULL if you want to not use any encoding.  (See also $SessionDecode below.)

:$SessionDecode: Function to reverse the decoding given by $SessionEncode above.  Set this to NULL if sensitive session values are not encoded.

:$HandleAuth:This sets the required authentication Level that is necessary to perform an action. When using the following example in your @@config.php@@ you need to be authenticated as editor in order to view the page history:
        $HandleAuth['diff'] = 'edit';

:$PageAttributes:Set the string shown on the attributes page when entering a password for an action.

:$AuthLDAPBindDN:For sites using [[AuthUser]] with LDAP authentication, this specifies the distinguished name (DN) to be used to bind to the LDAP server to check identity.

:$AuthLDAPBindPassword:For [[AuthUser]] with LDAP authentication, this specifies the password used for binding (in conjunction with $AuthLDAPBindDN above).

:$EnablePublishAttr:Adds a new "publish" authorization level to distinguish editing of drafts from publishing - See $EnableDrafts.

See also:
* [[Security]]
* $EnablePageListProtect

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.SimultaneousEdits</pagename>
<data><![CDATA[(:Summary: Handling multiple attempts to edit a page nearly simultaneously:)
PmWiki has support for handling the case where multiple authors attempt to edit the same page nearly simultaneously.  Here's the basic scenario for systems where simultaneous edits are ''not'' handled:

* Alice starts to edit a page.
* Before Alice saves her edits, Bob requests an edit of the same page, and receives the page text prior to Alice's edits.
* Bob finishes with his edits and hits "save".
* Alice finishes editing her page, hits "save", and since she was working from a version of the page from before Bob had made his changes, she wipes out Bob's edits in the process.

PmWiki's simultaneous edit feature detects when this occurs, and instead of saving Alice's edits PmWiki presents Alice with a message that someone else changed the page while she was editing it.  Furthermore, Bob's changes are merged into Alice's copy of the page, with any conflicts highlighted by <<<<<<< and >>>>>>>.  Alice can then fix things as appropriate and save the updated page, or, if Alice is lazy, she can just hit "save" a second time and leave it to someone else to fix.

The simultaneous edits feature is also invoked whenever someone requests a page preview; thus if a page changes while previewing a page the author gets notification and can see the merged results.

!!!How can I test/experiment with this feature?

# Open up two browser windows and select the same page to be edited in each window (e.g., try  [[Main/WikiSandbox?action=edit]]).
# In one browser window, make some changes to the page and then save those changes.
# In the second browser window, make some different changes to the same page and hit "save".  Since the page changed after the edit form was loaded into the second window, there's a potential edit conflict and you'll receive the "edit conflict message".
# You can make any adjustments in the second window, and press "Save" again to save the changes.

!!!Notice

Some server environments such as Windows and PHP running in safe_mode are unable to use the simultaneous edits capability distributed with PmWiki.  See Cookbook:SimultaneousEdits for a solution for these environments.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.SitePageActions</pagename>
<data><![CDATA[%audience% authors (basic)

The [[Site.PageActions]] uses a large number of PmWiki features in concert. 
This page gives a brief explanation of the features commonly used on [[Site.PageActions]], and pointers to where more information can be found.

To start with, lets look at a typical Site.PageActions page.\\
Below is what is currently shipping with PmWiki version 2.2.0:
->[@
* %item rel=nofollow class=browse    accesskey='$[ak_view]'%      [[{*$FullName}               | $[View] ]]
* %item rel=nofollow class=edit      accesskey='$[ak_edit]'%      [[{*$FullName}?action=edit   | $[Edit] ]]
* %item rel=nofollow class=diff      accesskey='$[ak_history]'%   [[{*$FullName}?action=diff   | $[History] ]]
(:if auth upload:)
* %item rel=nofollow class=upload    accesskey='$[ak_attach]'%    [[{*$FullName}?action=upload | $[Attach] ]]
(:ifend:)
* %item rel=nofollow class=print     accesskey='$[ak_print]'%     [[{*$FullName}?action=print  | $[Print] ]]
(:if group Site,SiteAdmin,Cookbook:) (:comment delete if and ifend to enable backlinks:)
* %item rel=nofollow class=backlinks accesskey='$[ak_backlinks]'% [[{*$Name}?action=search&q=link={*$FullName} | $[Backlinks] ]]
(:ifend:)
(:if enabled AuthPw:)
* %item rel=nofollow class=logout    accesskey='$[ak_logout]'%''  [-[[{*$FullName}?action=logout | $[logout] ]]-]''
(:ifend:)
@]

That can seem a bit daunting, but we'll take it piece by piece. To start with, we'll look at just the first line, and take it apart. This will also give us a good handle on how most of the other lines work.

!! List
The first line, and in fact every line, begins with an unindented '@@*@@', which means its an item in an unordered list. 
You can find out more about lists on the [[Basic Editing]] page. 
PmWiki will normally display an unordered list as a set of bulleted items, but they can appear differently depending on the context they are displayed in. This difference in display is generally controlled by CSS defined in the Skin.

If you take a look at the [[Site.PageActions]] page with the default PmWiki [[PmWiki.Skins|skin]], you'll see that the list appears twice, once as a normal bulleted list in the middle of the page, and once as a row of unbulleted actions at the top right corner of the page. This is controlled by the fact that they are being rendered inside an HTML [@<div>@] with an [@id@] of 'wikicmds' and the CSS for the default PmWiki skin asks that list items inside a wikicmds element be displayed that way.

You can see the difference for yourself since PmWiki has markup that lets you ask for something to be rendered inside a div with a given [@id@]:
(:markup class=horiz:)
* test1
* test2
* test3

(:div id=wikicmds:)
* test1
* test2
* test3
(:divend:)
(:markupend:)

!! Style
Following the '[@*@]', on the line we have [@%item ... %@] which is a [[WikiStyles|WikiStyle]]. It is used to control the properties of a given output element, like its size or color. By default they apply to the text between them and the end of the line or a closing [@%%@], whichever is sooner. So, for example, one can enter [@"this %blue%text%% is blue"@] and it will appear as "this %blue%text%% is blue".

In this case the WikiStyle starts with the word [@item@], and that says to apply the given style to the entire list item as opposed to just the text that follows. In particular, it causes PmWiki to generate HTML of

->[@<li class='edit'>...</li>@]

instead of

->[@<li><span class='edit'>...</span></li>@]

Setting the class attribute of the list item allows CSS properties to be applied to the item that corresponds to the current action. For example, to have the current action display with a background color of blue, a wiki administrator can do:

->@@$HTMLStylesFmt[]@@[@ = ' .{$Action} { background-color: blue; }';@]

Then if the current action is 'edit' (as in "?action=edit"), the list item corresponding to the edit action will be drawn with a blue background.

The other property inside the [@%item ... %@] WikiStyle is the accesskey='$[ak_view]' statement. [[AccessKeys]] are keyboard shortcuts for tasks that would otherwise require a mouse. They can be attached to links or to form elements and the WikiStyle will use whichever it finds first on the line. In this case they will attach to the link [@[[{*$FullName} | $[View] ]]@].

!! Accesskey
An accesskey can be defined in a number of locations, but essentially it is a phrase translation following the model used for internationalizations. PmWiki's accesskey defaults are defined in @@scripts/prefs.php@@, but can be overridden in lots of different places, including skins, language translation pages (XLPage), and even per-browser preferences (see [[Site.Preferences]]).

The [@$[...]@] markup defines phrase translations, used for internationalizations (and access keys, as noted above). In the first line of [[Site.PageActions]] it is used in both [@$[ak_view]@] and [@$[View]@]. Essentially [@$[View]@] tells PmWiki to substitute the current translation of "View".  If no translation is defined for "View", then PmWiki just uses the phrase inside the brackets.

You can most easily see this working in the other languages sections of PmWiki. For example, at [[(http://pmwiki.org/wiki/)PmWikiDe/PmWikiDe]] you'll notice that the default "View", "Edit", "History", and "Print" actions are displayed as "Artikel", "Bearbeiten", "Historie", and "Druckansicht".
This is because the PmWikiDe group is loading in a set of translations from [[(http://pmwiki.org/wiki/)PmWikiDe.XLPage]] 

That page defines things like

->[@'View' => 'Artikel'
'Edit' => 'Bearbeiten'
'History' => 'Historie'
'Print' => 'Druckansicht'@]

which says that things like [@$[View]@] and [@$[Edit]@] should be replaced by "Artikel" and "Bearbeiten".

This makes it very easy for PmWiki to support multiple languages, since a recipe author can simply put any translatable prompts or phrases inside of [@$[...]@], and leave it to others to actually build the translation tables (either locally or on [[(http://)pmwiki.org]] for others to use). More information about [@$[...]@] is available at [[PmWiki/Internationalizations]].

!! Link
All that leaves on the first line to be explained is the [[PmWiki.Links|link]] itself: [@[[{*$FullName} | $[View] ]]@]. Links are not complex, but this one is using both the internationalization feature and a [[PageVariables|Page Variable]]. The [@$[View]@] has already been explained and it shows up in the link text section of link markup, so that, if viewed in English, the link will appear as [[[[{*$FullName} |$[View]]].

The link target section contains the [@{*$FullName}@] variable. This variable expands to the full name of the page on which it is being displayed, including the group and page names. For simple browsing, this is good enough, because viewing a page is the default action to perform on a page. Later lines use link targets like [@{*$FullName}?action=edit@] which says to go to the currently displayed page and start editing it.

!! If
This explains what all of the '[@*@]' lines are about. That only leaves the [@(:if auth upload:)@] and [@(:ifend:)@] lines, and they go together. The first starts some [[Conditional Markup]] and the second ends it. The [@(:if test :)@] markup only lets the following text be displayed if the test succeeds. The text that conditionally displayed ends at the next [@(:if...:)@] statement so an empty [@(:ifend:)@] is a convenient way to end the conditional block. The particular test being used here is [@auth upload@] which is only true if the current user is authorized to upload files to the wiki. Thus, the conditional block says to only display a link to perform an upload if the user is actually allowed to upload.

Depending on the security and permissions model on a given site, its not unusual to see many more conditional markups that test if, for example, a user has editing rights to the current page. More information on all the different conditions can be found at the [[Conditional Markup]] page, and a general index of all the PmWiki documentation can be found at [[Documentation Index]].

Hopefully this bit of documentation has answered your questions about the [[Site.PageActions]] page. 
If not, you may wish to consult the helpful people on one of the [[MailingLists|PmWiki Mailing Lists]].

----

%green%Note that any Group can have a [[Page Actions]] page, not just '''Site''' - this page should be edited to reflect that.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>HansB</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.SitePreferences</pagename>
<data><![CDATA[(:Summary: Customisable browser setting preferences: Access keys, edit form:)
The page [[{$SiteGroup}.Preferences]] contains customisable browser preference settings.
These include [[access keys]] (keyboard shortcuts to certain actions like edit, history, browse) and settings of the [[{$SiteGroup}.EditForm]] (width and height of the edit textarea) as well as the name of the edit form in use.

A different page than [[{$SiteGroup}.Preferences]] can be chosen by making a copy of that page under a new name, customising it, and setting a cookie which will point to this page for the browser being used, through 

   ?setprefs=`SomeGroup.`CustomPreferences 

`SomeGroup.`CustomPreferences being the name of the new customised preference page.

!!Notes and Comments

Note that in order to enable parsing of [[{$SiteGroup}.Preferences]] by default, a line like the following needs to be added to local/config.php:

 XLPage('prefs', "Site.Preferences");
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>OliverBetz</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.SkinTemplates</pagename>
<data><![CDATA[(:Summary:[[PmWiki/Skin(s)]] templates (.tmpl files):)
%define=box block bgcolor=#f9f9fc border='1px solid #666666' margin=10px padding=5px%
This page describes the skin template files (.tmpl) that are used to create PmWiki ''skins'', and how PmWiki uses them. As described in the [[skins]] page, a skin is a collection of files that specifies the layout for PmWiki pages. Each skin must include a template file that provides the skeleton for displaying a PmWiki page.

!! [[#findingprocessing]]Finding and Processing Templates

When you set the value of the $Skin variable in a configuration file like @@local/config.php@@, like this
-> [@
## Use the Foo Skin.
$Skin = 'foo';
@]

it tells PmWiki to search for a skin of that name, and use it. The usual result of the search is for PmWiki to load a template file from the appropriate skin directory. In this example, that would probably be the file @@pub/skins/foo/foo.tmpl@@.

The actual processing that PmWiki goes through to find a template file is important for those who are making complex skins, so its worth mentioning what those steps are:

>>rframe width=25pct margin-left:2em font-size:smaller<<
!! [[#security]]Security Note
The default value for @@[=$=]SkinLibDirs@@ has server-side and client-side files stored in the same publicly-accessible directory. That is, @@$SkinDir@@ and @@$SkinDirUrl@@ point to the same place. This is done for convenience (both for the skin user, and the skin writer), but it is not necessary.

It has the side effect that its possible to construct a URL ([[http://www.pmwiki.org/pmwiki/pub/skins/pmwiki/pmwiki.tmpl|like this one]]) that will let you look at the contents of the the @@.tmpl@@ or @@.php@@ files that a skin uses. This is usually not an issue as skin files should not contain any sensitive information.

Still, a purist might want to move their @@.tmpl@@ and @@.php@@ files out of the directories that are accessible as URLs, and modify their @@[=$=]SkinLibDirs@@ array to reflect this.
>><<

#When @@$PageTemplateFmt@@ is blank (as it should be), PmWiki gathers the names of all candidate skins. It starts with any action-specific skin that is specified in @@[[LayoutVariables#ActionSkin|$ActionSkin]][$action]@@. Thus, if the current action is 'login', and @@$ActionSkin['login']@@ is @@'Bar'@@, then PmWiki will look for a skin named 'Bar'. 

#If no skin has been found yet, it looks for the skin(s) named in the @@$Skin@@ variable (which is allowed to be an array) and uses the first skin it can find. If it gets to the end of the list without finding a skin, it issues an error.

#To attempt to find a skin, PmWiki first consults the @@[[LayoutVariables#SkinLibDirs|[=$=]SkinLibDirs]]@@ variable to know where to look. Skins consist of server-side files that are loaded by PmWiki (such as .php and .tmpl files) and client-side files (such as .css files and images) that will be requested by the user's browser when they look at a skinned PmWiki page. @@$SkinLibDirs@@ is an array of key/value pairs. The key is a directory to look in for the server-side files, while the corresponding value is a URL that points to the public client-side resources used by the skin. The default value of @@[=$=]SkinLibDirs@@ is:
 -> [@
$SkinLibDirs = array(
   "./pub/skins/\$Skin"      => "$PubDirUrl/skins/\$Skin",
   "$FarmD/pub/skins/\$Skin" => "$FarmPubDirUrl/skins/\$Skin");
@]

 So, using the above definitions, PmWiki would try to find the skin 'foo' by looking for a directory called @@./pub/skins/foo@@ and then for @@$FarmD/pub/skins/foo@@ (with the value of @@$FarmD@@ replaced by the root server directory for Farm files). The first such directory that was found would be assumed to contain the skin it was looking for. It would then set @@$SkinDir@@ to the name of this directory and @@$SkinDirUrl@@ to the corresponding URL.

#Once a valid skin directory has been found, PmWiki starts processing the files in that directory, looking for a @@.php@@ skin file to run. It first looks for one with the same name as the skin. So, if the skin is 'foo', it looks for @@foo.php@@. If no such file is found, it then checks for a file named @@skin.php@@. If one of these @@.php@@ files is found, PmWiki loads and runs it. This allows a skin to define custom markup, or custom configuration parameters. It also allows a skin to choose between which of several different @@.tmpl@@ files to load.

 To specify which @@.tmpl@@ file to load, simply call @@LoadPageTemplate()@@ inside the skin @@.php@@ file, with the name of the @@.tmpl@@ file to be loaded:

 -> @@LoadPageTemplate($pagename, "$SkinDir/xyz.tmpl");@@

 For example, a skin might specify a special template to be used if the action is 'print':

 -> [@
if ($GLOBALS['action'] == 'print')
  LoadPageTemplate($pagename, "$SkinDir/print.tmpl");
@]

 When the action is something else, PmWiki will fall back to loading the default @@.tmpl@@ file instead.

#If no appropriate @@.php@@ file is found, or if that file doesn't load a template, then PmWiki falls back to looking for a template with the same name as the skin, or, failing that, any @@.tmpl@@ file at all, so long as its the only one in the directory. If it finds one, it will load and process it. If not, it will issue an error.

!![[#fileformat]]Template file format

A template file is basically an HTML file that also contains variable substitutions (indicated by '$') and special directives embedded in HTML comments.  The following special directives are ''required'' in the template file.  
# The directive [@<!--PageText-->@] belongs to the <body> section of the HTML document, and tells PmWiki where the main content of each wiki page should be placed.  
# The directive [@<!--HTMLHeader-->@], which goes somewhere in the <head> section of the HTML document.
# The directive [@<!--HTMLFooter-->@] directive, which typically goes before the final </body> tag and is used by some recipes to insert things at the end of the HTML document. [- %green%''Prior to PmWiki 2.2.0 the [@<!--HTMLFooter-->@] directive was optional.'' -]

When PmWiki displays a page, it replaces the directives and variable substitutions with the values appropriate to the current page.  For example, the [@<!--PageText-->@] directive is replaced with the page's contents, while any instances of $PageUrl are replaced with the url (address) of the current page.

There is a long list of variables available for substitution in pages; some of the
most useful include:
-> [@
$PageUrl         the url of the current page
$ScriptUrl       the base url to the pmwiki.php script
$Title           the page's title (e.g., "`SkinTemplates")
$Titlespaced     the page's title with spaces (e.g., "Skin Templates")
$Group           the name of the current group  (e.g., "`PmWiki")
$FullName        the page's full name (e.g., "`PmWiki.SkinTemplates")
$LastModified    the page's last modification time
$PageLogoUrl     the url of a site logo
$WikiTitle       the site's title
$SkinDirUrl      the url of the skin's folder
@]

This last variable, $SkinDirUrl, is particularly useful in templates as it allows the skin designer to refer to other files (such as images or style sheets) in the skin folder without having to know the exact url.

The template is not limited to using the variables listed here; nearly any PHP global variable that begins with a capital letter can be used in a skin template.  [[Page variables]] can also be used in templates.

!![[#directives]] Skin directives

Besides the required [@<!--PageText-->@] and [@<!--HTMLHeader-->@] directives, PmWiki provides other built-in directives for generating page output.  It's not necessary to use any of these directives, but they can often add capabilities to a skin 

:[@<!--wiki:Main.SomePage-->@]:
:[@<!--page:Main.SomePage-->@]:
: :The [@<!--wiki:Main.SomePage-->@] directive outputs the contents of `Main.SomePage.  $-substitutions are allowed in directives, thus a directive like [@<!--wiki:$Group.SomePage-->@] will include "`SomePage" of the current group.  

: :If multiple pages are listed in the directive, then only the first available page is used.  Thus [@<!--wiki:$Group.SomePage Site.SomePage-->@] will display the contents of `SomePage in the current group if it exists, and `Site.SomePage if it doesn't.  To always display `Site.SomePage, even if $`Group.SomePage exists, use two consecutive [@<!--wiki:...-->@] directives.

: :The [@<!--wiki:...-->@] directive only displays pages for which the browser has read permissions.  The [@<!--page:...-->@] directive displays pages even if the browser doesn't have read permission.

:[@<!--file:somefile.txt-->@]:
: :The directive [@<!--file:somefile.txt-->@] outputs the contents of another file (on the local filesystem) at the point of the directive.  If the file to be included is a .php script, then the PHP script is executed and its output is sent to the browser.  Like the [@<!--wiki:...-->@] directive above, $-substitutions are available to be able to output files based on the current page name or group.

:[@<!--markup:...-->@]:
: :The markup directive processes any text that follows the colon as wiki markup and displays that in the output.  

:[@<!--function:SomeFunction args-->@]:
: :This directive calls a PHP function named "`SomeFunction", passing the current page's name and the text following the function name as arguments.  PHP functions called in this manner are typically defined in a local customization file. Args allows only one argument, which has to be splitted then. [@<!--function:SomeFunction arg1 arg2 arg3-->@] generates one parameter "arg1 arg2 arg3". However variables can be used (like $LastModifiedBy).

!![[#sections]] Page sections

A template file can designate "sections" that are included or excluded from the output based on [[page directives]] or other criteria.  A section always begins with [@<!--Page...Fmt-->@] and continues to the next section, the end of the template file, or [@<!--/Page...Fmt-->@].  For example, a template can specify a [@<!--PageLeftFmt-->@] section that is excluded from the output whenever the [@(:noleft:)@] directive is encountered in the page's contents.  PmWiki's predefined sections (and their corresponding page directives) are:
-> [@
<!--PageHeaderFmt-->          (:noheader:)
<!--PageFooterFmt-->          (:nofooter:)
<!--PageTitleFmt-->           (:notitle:)
<!--PageLeftFmt-->            (:noleft:)
<!--PageRightFmt-->           (:noright:)
<!--PageActionFmt-->          (:noaction:)
@]

Skin designers can define custom sections and markups, but currently all section names in the template must begin with "Page" and end with "Fmt". As mentioned you also have to define the corresponding markup (for example in your config.php) like this: 

->[@Markup('noxyz', 'directives',  '/\\(:noxyz:\\)/ei',
    "SetTmplDisplay('PageXYZFmt',0)");@] 

!![[#i18n]] Internationalization (i18n)[[#Internationalization]]

Skins can also be [[internationaliz(ations)]]ed by using [@$[...]@] substitutions.  Any string placed inside of [@$[...]@] is treated as a "translatable phrase", and the phrase is looked up in the current translation tables for a corresponding output phrase.  If a translation is available, then the translated phrase is substituted at that point, otherwise the original phrase is left intact.

For example, the substitution [@$[Edit]@] will display the current translation of "Edit" if it is known, otherwise it displays "Edit".  Thus, the same template can be used for multiple languages, displaying "Editer" when French translations are loaded, "Bearbeiten" when German translations are loaded, and "Edit" when no translation is available.

!! Understanding old config files
-< %red%This information is deprecated%%, but we're still including it in the docs so you can better understand any really old @@local/config.php@@ files you look at. 
The original method of telling PmWiki where to find a skin used to be to set @@$PageTempateFmt@@ to the path of a @@.tmpl@@ file on the server. This is still respected by PmWiki, so if, for example, you were to set @@$PageTemplateFmt@@ to @@./pub/skins/foo/foo.tmpl@@ then PmWiki would simply load and use that file, but without setting the special @@$SkinDir@@ and @@$SkinDirUrl@@ variables that are required by all modern skins.
-> %red%DO NOT USE @@$PageTemplateFmt@@%%

>>faq<< [[#faq]]

Q: How do I customize the CSS styling of my PmWiki layout?[[#customcss]]

A: See [[Skins]] for how to change the default PmWiki skin.  See also [[Cookbook:Skins]], where you will find pre-made templates you can use to customize the appearance of your site.  You can also create a file called ''local.css'' in the ''pub/css/'' directory and add CSS selectors there (this file gets automatically loaded if it exists).  Or, styles can be added directly into a local customization file by using something like:

-> [@$HTMLStylesFmt[] = '.foo { color:blue; }';@]

Q: Where can the mentioned "translation table" be found for adding translated phrases?
A: See [[Internationalizations]].

Q: Is it possible to have the edit form in full page width, with no sidebar?
A: If the sidebar is marked with [@<!--PageLeftFmt-->@], adding [@(:noleft:)@] to Site.EditForm will hide it when a page is edited.

Q: Can I easily hide the Home Page title from the homepage?
A: Yes, you can use in the wiki page either @@[=(:title Some other title:)=]@@ to change it or @@[=(:notitle:)=]@@ to hide it.]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Skins</pagename>
<data><![CDATA[(:Summary: Change the look and feel of part or all of PmWiki:)(:Audience: administrators (basic) :)
(:div class='rfloat frame' style="font-size:smaller; clear:right;" :)
!!Contents
* [[#what | What is a skin?]]
* [[#where | Where do I get skins?]]
* [[#use | How do I use a skin?]]
* [[#modify | How can I modify an existing skin?]]
* [[#make | How can I make a skin?]]
(:divend:)
!!What's a skin? [[#what]]

A skin changes the look and feel of a PmWiki page, Group of pages, or the entire wiki.
To see this try some skins out using the links below.

* [[PmWiki:Skins?skin=beeblebrox-gila2  | BeeblebroxNetGila ]]
* [[PmWiki:Skins?skin=jhskin | JHSkin ]]
* [[PmWiki:Skins?skin=gemini | GeminiSkin ]]
* [[PmWiki:Skins?skin=light | LightSkin ]]
* [[PmWiki:Skins?skin=monobook | Monobook Skin ]]
* [[PmWiki:Skins?skin=simple | Simple Skin ]]
* [[PmWiki:Skins?skin= | PmWiki (default) Skin ]]

As you see, all skins show the same page contents, but the other elements such as the sidebar, header, and footer, have changed.  
For example, different skins may display the sidebar on the left, on the right, or even not at all.  
Some skins have action links and features that others do not, especially if they were designed to take advantage of particular [[cookbook recipes -> Cookbook:Cookbook]].

So, a skin is just the set of files that determine how pages are displayed in PmWiki.  Skins are stored as subfolders of ''pub/skins/''.  For example you might create the ''example'' skin in ''pub/skins/example/''. Each skin typically has one or more of the following kinds of files:
* A template file, such as ''skin.tmpl'' or ''gemini.tmpl''.  The template is written in HTML or XHTML, and is the skeleton for the skin.  It contains special markers that tell PmWiki where to insert the page's contents.
* CSS stylesheet files, which can control the skin's appearance.
* Image files, for decorating a page with images.
* PHP files, such as ''skin.php''.  These let skins provide extra customization setting or capabilities that HTML and CSS alone cannot.
* Documentation files for the administrator, usually with names like ''readme.txt'', ''install.txt'' or ''skinname.txt''.  These usually give you information about any special installation steps or nifty features the skin has.

!!  Where do I get skins? [[#where]]

Skins are available in the [[Cookbook:Skins]] collection.  
The skins in the collection have been contributed by other PmWiki administrators for others to use, and typically have their own set of customization possibilities.  
When you find a skin you like, follow the link to download the skin package.
You can also [[{$FullName}#make|make your own]] skin.

!!How do I use or install a skin? [[#use]]

Most skin packages are .zip, .tgz, or .tar.gz files.  You should be able to unpack these with most archiving software.

# Unpack the skin to ''pub/skins/'' inside your pmwiki folder.  Most well-designed skin packages will create a subfolder in ''pub/skins/'' named after the skin.
** If the skin did not make a folder of its own, create one and move the skin files to it.

# Open up your ''local/config.php'' file, and add a line like\\
\\
[@$Skin = 'my-favourite-skin';@]\\
\\
where 'my-favourite-skin' is the name of the skin's folder.

Reload a page from your wiki in the browser, and you should be able to see the difference.

If you'd like to let your site's visitors choose one skin from a selection of skins you've installed, look at the [[Cookbook:SkinChange]] recipe.  (That's what we used for the demo above.)

!! How can I modify an existing skin? [[#modify]] [[#further]]

There are a number of ways to further customize the appearance of a skin, including 
* adding statements to /local/config.php that are compatible with your chosen skin; 
* adding css files to /pub/css/, such as local.css (for your entire wiki) and MyGroup.css (for MyGroup); and 
* directly editing the skin's files. 
If the skin is updated regularly, you probably will want to avoid editing the files in the skin's folder. 
Check the skin's page in the Cookbook for specific suggestions.

If you want to modify the default pmwiki or print skins included with the PmWiki distribution, you should copy the pub/skins/pmwiki/ and pub/skins/print/ directories to another name and then use those skins instead of the default ones.  While the name of the skin.tmpl and skin.css files don't usually matter, the optional skin.php file MUST match the name of the skin.

!!How can I make a skin? [[#make]]

The best way to make your first skin is to modify a copy of PmWiki's default skin.  

# Make a copy of the folder ''pub/skins/pmwiki'' and name it whatever your new skin should be named.
# In your ''local/config.php'' file, set $Skin to be the name of your new skin.
# Modify the template and CSS files to suit you.
# Test your new skin.
# Repeat steps 3 and 4 until you're happy with the results.

The reason we recommend starting with the default PmWiki skin is that it's quite a simple skin, much more so than many of the skins you'll find in [[Cookbook:Skins]].  The starting point is the template (.tmpl) file, which provides the overall layout of the page.  Inside of the template file are a number of special substitutions and directives that provide places for PmWiki to insert the data relevant to the current page being displayed.  [[SkinTemplates]] describes the format and directives in more detail.  There are also [[Cookbook:SkinGuidelines|skin guidelines]] available on pmwiki.org.

It's beyond the scope of this page to explain how to write HTML (hypertext markup language), XHTML (extensible HTML, which is a bit newer) or CSS (cascading style sheets), but there are many good tutorials on the web for all three of them.  One caution: if you run into an HTML tutorial that explains about how to use <font> or <blink> tags, or spacer gifs, it's at least five years out of date, so skip it and find another one.  

You should test your skin on a variety of browsers -- ideally as many as you can, on as many different platforms as you can -- but at minimum you should be testing on Internet Explorer 7 and Firefox 2 or Mozilla, since those are the most common, and have different bugs.  Don't forget to do things like resize windows and change text size during your testing.

!! Print Skins
By default your new skin will use the standard /pub/skins/print/ skin. 

To over-ride this add the following to local/config.php:

->[@$ActionSkin['print'] = 'yourprintskin';@]

This says to use 'yourprintskin' for ?action=print instead of the default.

!!!Tools that you'll need

There are good examples of all these programs available for free.  

'''HTML and CSS editor(s).''' There are two types of editors: graphical (WYSIWYG, or "what you see is what you get"), and hand-coding or programmer's editors.  Graphical editors are less intimidating to novices, but you won't learn as much, or know your code as intimately as you will by using a hand-coding editor.  Whichever you choose, get one that has syntax highlighting for the code, because it will help you spot mistakes.  Also, live preview features are not that helpful when writing a PmWiki skin, because PmWiki does stuff that the live preview won't, such as substitute values for variables and insert sidebar content.

'''Test wiki'''.  You don't want to be wreaking havoc on your skin while visitors can see your site.  It's a better idea to set up a test wiki, either on your real webserver or on your own machine.  Linux or [=MacOS=] computer owners may have webservers and PHP already running on their machines, but Windows users often don't.  If that describes you, then you might want to take a look at the Cookbook:Standalone recipe, which runs PmWiki without needing a complex webserver.  Or, you can find many local server packages which install a webserver, PHP, and other stuff (e.g. `MySQL), all configured to work together.  Try to get a package that has the same software and versions as used on your live setup, since then there will be less to go wrong when the site goes live.

'''FTP client''' to transfer files to your webserver.  You probably had one of these already.

'''Color picker'''.  Your editor might include one, or you could pick up a standalone application.  Extremely helpful for creating and saving color palettes.

!!See also

* [[PmWiki/Skin Templates]]
* [[Cookbook:Skins]]
* [[Cookbook:Skin Guidelines]]
* [[Cookbook:Standalone]]
* [[PmWiki/Installation]]

>>faq<< [[#faq]]

Q: How do I change the Wiki's default name in the upper left corner of the Main Page?

A: Put the following config.php

->[@$WikiTitle = 'My Wiki Site';@]

The ''docs/sample-config.php'' file has an example of changing the title.

Q: How can I embed PmWiki pages inside a web page?

A: Source them through a PHP page, or place them in a frame.

Q: How do I change the font or background color of the hints block on the Edit Page?

A: Add a CSS style to pub/css/local.css: [@.quickref {background:...; color:... }@]. The hints are provided by the [[Site.EditQuickReference]] page, which is in the PmWiki or Site wikigroup.  Edit that page, and change the "bgcolor" or specify the font "color" to get the contrast you need.

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.SpecialCharacters</pagename>
<data><![CDATA[When creating pages it's common to use commercial trademarks, copyright, umlaut, and other non-keyboard symbols.  therefore it's important that you have the means to input these special characters.  

!!!ISO Standard codes
PmWiki supports the HTML special character listings by the w3c. [[http://www.w3.org/MarkUp/html-spec/html-spec_13.html |  W3C Page of Special Character codes ISO standard.]]

Here are some samples: 
(:markup:)[=
&#169; | &#188; | &#189; | &#174; | &#181; | &#168; =]

(:markup:)[=
&#198; | 32&#176; | Un&#239;ted St&#228;tes | &#182; | &#165;Yen | PmWiki&#8482;=]

For a nice table of the same codes that show the codes with the output go to the [[http://www.nobledesktop.com/specialcharacters.html | Noble Desktop]] special character page. 

!!!Other ways to do it: 

!!!!Character Map
Find the "Character Map" utility in your computer's System Tools folder.  Click the symbol you're interested in, and note the keystroke information at the bottom of the box.  You execute these by ''holding "Alt"'' while keying the numbers ''on the numerical keypad'' of your keyboard (not the numbers across the top of the board).

[=&#169;=] = Alt+0169 = © | [=&#174;=] = Alt+0174 =  ® | [=&#176;=] = Alt+0176 = ° (degrees).

!!!!Paste
*Use Word or another desktop application to create your text with the special characters that you want.  Copy and paste the text to the wiki page you're editing or creating.
*Find an instance of a special character in an online document; copy and paste the character to your wiki page:  ©

There's a list of special characters at [[PmWiki:SpecialCharactersList]].
There's another illustration at [[PmWiki:Characters]]]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>TeganDowling</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.TableDirectives</pagename>
<data><![CDATA[(:Summary:Directives for table processing:)
(:Audience: authors (intermediate) :)

(:title Table directives:)
There are four directives for table processing.  All must be at the beginning of a line to have any effect.

!!![@(:table (attr...):)@]
Generates a new HTML <table> tag with the attributes provided in ''attr...''.
Closes the previous table, if any.
Valid attributes and values are:
* border ''(a positive integer)''
* bordercolor ''(a color name or hex number; doesn't display in all browsers)''
* cellspacing ''(a positive integer indicating the space between cells)''
* cellpadding ''(a positive integer indicating the interior border of a cell)''
* width ''(a positive integer or percent)''
* bgcolor ''(a color name or hex number)''
* align ''(left, center or right)''
* summary ''(does not display; used primarily to help visually disabled people navigate)''

!!![@(:cell (attr...):)@]
Generates a new cell with the attributes given by ''attr...''.  
Closes the previous table cell, if any.
In HTML, this creates a new "<td attr>" tag (and possibly <table>, <tr>, and </td> tags if they are needed to produce a valid HTML table). 

->%note% '''Note:''' Placing a space after the cell markup "(:cell:) " causes subsequent text on that line to be treated as preformatted text.

Valid attributes and values are:
* align ''(left, center or right)''
* valign ''(top, middle or bottom)'' * ''see valign attribute info below''
* colspan ''(a positive integer)''
* rowspan ''(a positive integer)''
* bgcolor ''(a color name or hex number)''
* width ''(a positive integer or percent)''

!!![@(:cellnr (attr..):)@]
Generates a new cell at the beginning of the next row.
Closes the previous table cell, if any.
In HTML, this creates a "<tr><td attr>" tag, and possibly <table>, </td>, and </tr> tags if they are needed for valid HTML.
Valid attributes and values are:
* align ''(left, center or right)''
* valign ''(top, middle or bottom)'' * ''see valign attribute info below''
* colspan ''(a positive integer)''
* rowspan ''(a positive integer)''
* bgcolor ''(a color name or hex number)''
* width ''(a positive integer or percent)''

!!![@(:tableend:)@]
Closes the previous table cell and closes off any table.  Generates </td>, </tr>, and </table> tags as needed.

!!!* valign attribute info
If not already set, PMWiki will automatically include the attribute valign='top' with all [@(:cell:)@] and [@(:cellnr:)@].  PM said "Table Directives were created for layout purposes and in that case it makes the most sense for each cell (column) to have its content at the top of the row.  The attribute is placed in each cell and not in the row because certain browsers didn't recognize valign='top' in the row tag.

!! Notes

For the table, cell, and cellnr tags the author can specify any attributes that would be valid in the HTML <table> or <td> tags.  Thus you can specify rowspan, colspan, etc. arguments to build arbitrary tables.  However, it's not possible to nest a [@(:table:)@] inside of a [@(:cell:)@] or [@(:cellnr:)@] -- the next paragraph explains why.

Many are likely to ask why we didn't just use the standard HTML table markup (<table>, <tr>, <td>, <th>) instead of creating a new markup, and allowing nested tables as a result.  There are two answers:  first, the HTML table markup is very ugly for naive authors (see [[PmWiki.Audiences]] and [[PmWikiPhilosophy]] #2), and second, it'd be very easy for authors to create tables that are incorrect HTML and that display incorrectly (or not at all) on some browsers.  Even seasoned web professionals sometimes get the table markup wrong, so it's a bit unrealistic to expect the average author to always get it right, or to be able to read arbitrary HTML table markup that someone else has created.

-> %color=green% ''Common comment:'' Surely, the average or naive author would not be writing HTML directly, but using a tool, such as [=FrontPage=], or even [=MSWord=], to generate the HTML. This would be a lot simpler than learning even the simplest PmWiki markups.
>><<

-> %color=green% ''Pm's Response:'' And once the HTML has been generated and posted, how is someone else going to edit or modify the table if they don't have the original [=FrontPage or MSWord=] file used to create it?  Remember that we're talking about ''collaborative'' authoring.  The HTML that those packages generate is among the hardest to read and edit of all!

It's difficult to write the code needed to make PmWiki understand and fix arbitrary table markup, so PmWiki uses the simplified version above.  Still, this version is able to handle most table requirements (with the possible exception of nested tables).

And, this is not to say that nested HTML tables are impossible in PmWiki --they just can't be easily created by wiki authors using the default wiki markup.  A site administrator can of course create header/footer HTML code and other [[local customizations]] that make use of nested tables.

!!!Example 1.  A table using table directive markup.

"[@&nbsp;@]" is a non-breaking space in html. Place it in a cell if a cell is to be empty or the border of the cell will not be drawn properly.

(:markup:)
(:table border=1 cellpadding=5 cellspacing=0:)
(:cell:) a1
(:cell:) b1
(:cell:) c1
(:cell:) d1
(:cellnr:) a2
(:cell:) b2
(:cell:) c2
(:cell:) &nbsp;
(:tableend:)
(:markupend:)

In HTML, this is the same as

-> [@
<table border='1' cellpadding='5' cellspacing='0'>
  <tr>
    <td>a1</td>
    <td>b1</td>
    <td>c1</td>
    <td>d1</td>
  </tr>
  <tr>
    <td>a2</td>
    <td>b2</td>
    <td>c2</td>
    <td>&nbsp;</td>
  </tr>
</table>
@]

-----
!!!Floating Table with bulleted navigation list

What if you wanted to create a nice little table like a table of contents in a page like this? In this example, the table is floating right and contains some links in a bulleted list. This is a nice demonstration of how it's possible to build a little table of contents in the page, which might navigate to other pages just within the same wiki group. Note that having a bulleted list ''won't work in a ordinary table'' - it only works inside an  table created with table directives such as the example code used here.

(:markup:)
(:table border=1 width=30% align=right bgcolor=#cccc99 cellspacing=0 :)
(:cellnr:)
'''Navigation Links'''
(:cellnr:)
*[[Tables]]
*[[Table directives]]
(:tableend:)
(:markupend:)

(:markup:)
(:table border=1 width=30% align=right bgcolor=#cccc99 cellspacing=0 :)
(:cellnr colspan=2 align=center:)
'''Navigation Links'''
(:cellnr align=center:)
[[Tables]]
(:cell align=center:)
[[Table directives]]
(:tableend:)
(:markupend:)

Looking at the markup here, notice that we have used a #cccc99 hex color for the table background. Also, the [@(:cellnr:)@] markup creates a new row, a new cell and closes the row at the end.

You could take this concept a little further: since you might want each page in the group to contain the same table of contents, you can make ONE table like the above and put it in its own page.  Then use an [[include (other pages)]] on any of your pages and bring in the table. The float (align) property will be honored in each page where it's included.

>>faq<< [[#faq]]

Q: Can I define table headers using the table directive markup?
A: No, but you can with [[Cookbook:AdvancedTableDirectives]]. See [[PITS:00535#pmanswer|Pm's reply]] to pending [[PITS:00535]]

Q: Is it possible to do nested tables?
A: Yes, if you nest simple tables inside advanced tables. See also [[Cookbook:AdvancedTableDirectives]].

Q: Is it possible to add background images to tables and table cells?
A: Yes, see [[Cookbook:BackgroundImages]].
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Tables</pagename>
<data><![CDATA[(:Audience: authors (basic) :)
(:Summary:Simple tables with double pipe markup, one row per line:)
!! Table basics

PmWiki has two types of table markup; the markup described in this page is useful for creating ''simple'' tables with lots of small cells, while [[table directive(s)]] markups help with larger scale tables.  For more possibilities with table formatting see [[Cookbook:Rowspan in simple tables]] and [[Cookbook:Formatting tables]].

Tables are created via use of double pipe characters: @@||@@. Lines beginning with this markup denote rows in a table or a formatting line. Within table row lines the double-pipe is used to delimit cells.  In the examples below a border is added for illustration (the default is no border).

The first line in the markup contains formatting commands for the table. It only has double pipe characters at the start of the line.

(:markup caption='Basic table' class=horiz:)
|| border=1
|| cell 1 || cell 2 || cell 3 ||
|| cell 1 || cell 2 ||
(:markupend:)

Header cells can be created by placing ! as the first character of a cell.  Note that these are ''table headers'', not ''headings'', so it doesn't extend to !!, !!!, etc.

(:markup caption='Table headers' class=horiz:)
|| border=1
||! cell 1 ||! cell 2 ||! cell 3 ||
|| cell 1  ||  cell 2 ||  cell 3 ||
(:markupend:)

A table can have a caption, indicated by [@||!caption!||@].  Any caption must appear prior to other rows of the table.

(:markup caption='Table caption' class=horiz:)
|| border=1
||! A special table !||
||! cell 1 ||! cell 2 ||! cell 3 ||
|| cell 1  ||  cell 2 ||  cell 3 ||
(:markupend:)

!! Formatting cell contents

Cell contents may be aligned left, centered, or aligned right. 
* To left-align contents, place the cell contents next to the leading @@||@@.
* To center contents, add a space before and after the cell contents.
* To right-align contents, place a space before the cell contents and leave the cell contents next to the trailing @@||@@.

(:markup caption='Cell alignments':)
|| border=1 width=100%
||!cell 1      ||! cell 2  ||!       cell 3||
||left-aligned || centered || right-aligned||
(:markupend:)

(:markup caption='Default cell alignments':)
|| border=1 width=100%
||!cell default||!cell left ||
||default-aligned||left-aligned ||
(:markupend:)

Note that header and detail cells have different default alignments.

To get a cell to span multiple columns, follow the cell with empty cells.
(At present there is no markup for spanning rows.)

(:markup caption='Column spanning':)
|| border=1 width=100%
|| |||| right column ||
|| || middle column ||||
|| left column ||||||
|| left column || middle column || right column ||
(:markupend:)

!! Table attributes

Any line that begins with [@||@] but doesn't have a closing [@||@] sets the ''table attributes'' for any tables that follow.  These attributes can control the size and position of the table, borders, background color, and cell spacing.  (In fact these are just standard HTML attributes that are placed in the <table> tag.)

Use the [@width=@] attribute to set a table's width, using either a percentage value, an absolute size, or '''*'''.

(:markup caption='Table width':)
|| border=1 width=100% 
|| cell 1 || cell 2 || cell 3 ||
|| c1 || cellcellcellcell2 || cell 3 ||
(:markupend:)

The [@border=@] attribute sets the size of a table's borders.

(:markup caption='Bordered table' class=horiz:)
|| border=10 width=70%
||!cell 1      ||! cell 2  ||!       cell 3||
||left-aligned || centered || right-aligned||
(:markupend:)

(:markup caption='Borderless table' class=horiz:)
|| border=0 width=70%
||!cell 1      ||! cell 2  ||!       cell 3||
||left-aligned || centered || right-aligned||
(:markupend:)

Use [@align=center@], [@align=left@], and [@align=right@] to center, left, or right align a table.  Note that [@align=left@] and [@align=right@] create a ''floating table'', such that text wraps around the table.

(:markup caption='Table alignment: center':)
|| border=1 align=center width=50%
||!cell 1      ||! cell 2  ||!       cell 3||
||left-aligned || centered || right-aligned||
Notice how text does not wrap with a table using "align=center".
(:markupend:)

(:markup caption='Table alignment: left':)
|| border=1 align=left width=50%
||!cell 1      ||! cell 2  ||!       cell 3||
||left-aligned || centered || right-aligned||
Notice how text wraps to the right of a table using "align=left".
(:markupend:)

(:markup caption='Table alignment: right':)
|| border=1 align=right width=50%
||!cell 1      ||! cell 2  ||!       cell 3||
||left-aligned || centered || right-aligned||
Notice how text wraps to the left of a table using "align=right".
(:markupend:)

Note: to get a table to align left (but not "float left") requires CSS, as in
->[@||style="margin-left:0px;"@]

The [@bgcolor=@] attribute sets the background color for a table.  At present there is no way to specify the color of individual rows or cells in this type of table (but see Cookbook:FormattingTables).

(:markup class=horiz:)
|| border=1 align=center bgcolor=yellow width=70%
||!cell 1    ||! cell 2 ||!     cell 3||
||left-align || center  || right-align||
(:markupend:)

>>faq<< [[#faq]]
Q: How do I create a basic table?  
A: Tables are created via use of the double pipe character: @@||@@. Lines beginning with this markup denote rows in a table; within such lines the double-pipe is used to delimit cells.  In the examples below a border is added for illustration (the default is no border).

(:markup caption='Basic table' class=horiz:)
|| border=1 rules=rows frame=hsides
|| cell 1 || cell 2 || cell 3 ||
|| cell 1 || cell 2 || cell 3 ||
(:markupend:)

Q: How do I create cell headers?
A: Header cells can be created by placing ! as the first character of a cell.  Note that these are ''table headers'', not ''headings'', so it doesn't extend to !!, !!!, etc.

(:markup caption='Table headers' class=horiz:)
|| border=1 rules=cols frame=vsides
||! cell 1 ||! cell 2 ||! cell 3 ||
|| cell 1  ||  cell 2 ||  cell 3 ||
(:markupend:)

Q: How do I create an advanced table?  
A: See [[PmWiki.TableDirectives | table directives]]

Q: My tables are by default centered. When I try to use '||align=left' they don't align left as expected. 
A: Use ||style="margin-left:0px;" instead. 

Q: How can I specify the width of columns?
A: You can define the widths via custom styles, see Cookbook:FormattingTables and $TableCellAttrFmt. Add in config.php :
[@$TableCellAttrFmt = 'class=col\$TableCellCount';@]
-> And add in pub/css/local.css : 
[@
table.column td.col1 { width: 120px; }
table.column td.col3 { width: 40px; }
@]

Q: How can I display a double pipe "||" in cell text using basic table markup?
A: Escape it with [@[=||=]@] to display || unchanged.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.TextFormattingRules</pagename>
<data><![CDATA[(:Summary: A list of some of the markup sequences available:) 
>>rframe font-size:smaller<<
!! Table of contents
* [[#Paragraphs|Paragraphs]]
* [[#IndentedParagraphs|Indented Paragraphs ''(Quotes)'']]
* [[#BulletedLists|Bulleted and Numbered Lists]]
* [[#DefinitionLists|Definition Lists]]
* [[#WhitespaceRules|Whitespace Rules]] 
* [[#HorizontalLine|Horizontal Line]]
* [[#Emphasis|Emphasis]]
* [[#References|References]]
* [[#Headings|Headings]]
* [[#EscapeSequence|Escape sequence]]
* [[Special Characters | Special characters]]
* [[#Tables | Tables]]
>><<
This page provides a more '''complete''' list of some of the markup sequences available in '''PmWiki'''.  
Note that it's easy to create and edit pages without using any of the markups below, but ''if'' you ever need them, they're here. 

To experiment with the rules, '''''please''''' try editing the [[Main/Wiki Sandbox]].

----

!! [[#Paragraphs]] Paragraphs

To create paragraphs, simply enter text.  Use a blank line to start a new paragraph.

Words on two lines in a row will '''wrap and fill''' as needed (the normal XHTML behavior).  To turn off the automatic filling, use the [@(:linebreaks:)@] directive above the paragraph.

* Use [@\@] (single backslash) at the end of a line to join the current line to the next one.
* Use [@\\@] (two backslashes) at the end of a line to force a line break.
* Use [@\\\@] (three backslashes) at the end of a line to force 2 line breaks.
* Use [@[[<<]]@] to force a line break that will clear floating elements.

!! [[#IndentedParagraphs]] Indented Paragraphs ''(Quotes)''

Arrows ([@->@]) at the beginning of a paragraph can be used to produce an indented paragraph.  More hyphens at the beginning ([@--->@]) produce larger indents.

(:markup:)
->Four score and seven years ago our fathers placed upon this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal.
(:markupend:)

Inverted Arrows ([@-<@]) at the beginning of a paragraph can be used to produce a paragraph with a hanging indent.  Adding hyphens at the beginning ([@---<@]) causes all the text to indent.

(:markup:)
-<Four score and seven years ago our fathers placed upon this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal. 
(:markupend:)

(:markup:)
--<Four score and seven years ago our fathers placed upon this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal.  And that food would be good too.
(:markupend:)

Blocks of text to which [@(:linebreaks:)@] has been applied can be indented by preceding the first line of the block with indention arrows ([@->@]) and aligning subsequent lines under the first. An unindented line stops the block indentation.  See [[Cookbook:Markup Tricks]] for an example.

!! [[#BulletedLists]] Bulleted and Numbered Lists

Bullet lists are made by placing asterisks at the left margin. Numbered lists are made by placing number-signs (#) at the left margin.  More asterisks/number-signs increases the level of bullet:

(:markup:) 
* First-level list item
** Second-level list item
### Order this
#### And this (optional)
### Then this
** Another second-level item
* A first-level item: cooking
## Prepare the experiment
### Unwrap the pop-tart
### Insert the pop-tart into the toaster
## Begin cooking the pop tart
## Stand back
(:markupend:)

(:markup:)
# A list is terminated
by the first line that is not a list.
# Continue a list item by lining
  up the text with leading whitespace.
# Use a forced linebreak \\
  to force a newline in your list item.
(:markupend:)

Use [[(PmWiki:)list styles]] to control numbering of ordered lists
(:markup:)
## Text between list items can cause numbering to restart
## %item value=3% this can be dealt with
(:markupend:)

Also see: [[(PmWiki:)ListStyles]], [[Cookbook:WikiStylesPlus]]

!! [[#DefinitionLists]] Definition Lists
>>rframe<<
'''Powerful new%red%*%% feature'''\\
When you define terms using this markup\\
PmWiki will recognize them as [[(PmWiki:)PageTextVariables]]\\
that you can use on any page or [[(PmWiki:)PageList(s)]].\\
[-%red%* Added%% in PmWiki version %red%2.2.0%%-]
>><<
Definition lists are made by placing colons at the left margin (and between each term and definition):

(:markup:)
:term:definition of term
::second-level item: definition of 2nd-level item
(:markupend:)

[[#WhitespaceRules]]
!!  Whitespace Rules

Whitespace indentation in lists.  Any line that begins with whitespace ''and aligns'' with a previous list item (whether bulleted, numbers or definitional) is considered to be "within" that list item.  Text folds and wraps as normal, and the [@(:linebreaks:)@] directive is honored. 

(:markup:) 
# First-level item\\
  Whitespace used to continue item on a new line
# Another first-level item
  # Whitespace combined with a single # to create a new item one level deeper
(:markupend:)

Otherwise, lines that begin with whitespace are treated as ''preformatted text'', using a monospace font and not generating linebreaks except where explicitly indicated in the markup.  Note to administrators: Starting with version 2.2.0-beta41, this feature can be modified using $EnableWSPre.  (Another way to create preformatted text blocks is by using the [=[@...@]=] markup.)

!! [[#HorizontalLine]] Horizontal Line

Four or more dashes ([=----=]) at the beginning of a line produce a horizontal line.

[[#Emphasis]]
!!  Emphasis and character formatting

* Enclose text in doubled single-quotes ([=''text''=]), i.e., ''two apostrophes'', for emphasis (usually ''italics'')
* Enclose text in tripled single-quotes ([='''text'''=]), i.e. ''three apostrophes'', for strong (usually '''bold''')
* Enclose text in five single-quotes ([='''''text'''''=]), or triples within doubles (''five apostrophes''), for strong emphasis (usually '''''bold italics''''')
* Enclose text in doubled at-signs ([=@@text@@=]) for @@monospace@@ text
* Use [=[+large+]=] for [+large+] text, [=[++larger++]=] for [++larger++], [=[-small-]=] for [-small-] text, and [=[--smaller--]=] for [--smaller--].
* Emphasis can be used multiple times within a line, but cannot span across markup line boundaries (i.e., you can't put a paragraph break in the middle of bold text).
* [='~italic~'=] and [='*bold*'=]  are available if enabled in config.php

Other styling 
(:markup:)
'+big+', '-small-', '^super^', '_sub_', 

{+insert or underscore+}, 

{-delete or strikethrough or strikeout-}
(:markupend:)
* [@`WikiWord@] `WikiWord neutralisation

See also [[Wiki Styles]] for advanced text formatting options.

[[#References]]
!!  References

* Use words and phrases in double brackets (e.g., [=[[text formatting rules]]=]) to create links to other pages on this wiki.
* On some PmWiki installations, capitalized words joined together (e.g., [[WikiWord]]s) can also be used to make references to other pages without needing the double-brackets.
* Precede [=URLs=] with "@@http:@@", "@@ftp:@@", "@@gopher:@@", "@@mailto:@@", or "@@news:@@" to create links automatically, as in http://www.pmichaud.com/toast.
* [=URLs=] ending with @@.gif@@, @@.jpg@@, or @@.png@@ are displayed as images in the page
* Links with arbitrary text can be created as either [=[[=]''target'' | ''text'']] or [=[[=]''text'' -> ''target''[=]]=].  ''Text'' can be an image URL, in which case the image becomes the link to the remote ''url'' or ''[[WikiWord]]''.
* [[#Anchors]] Anchor targets within pages (#-links) can be created using @@[=[[#target]]=]@@.
See [[Links]] for details.

[[#Headings]]
!!Headings

Headings are made by placing an exclamation mark ('''!''') at the left margin.  More exclamation marks increase the level of heading.  For example,

(:markup:)
! Level 1 Heading
!! Level 2 Heading
!!! Level 3 Heading
!!!! Level 4 Heading
!!!!! Level 5 Heading
(:markupend:)

Note that level 1 heading is already used as page title (at least in the PmWiki skin), so you should start with level 2 headings to create well formed, search enging optimized web pages.

See [[Cookbook:Numbered Headers]] for numbered headings.

[[#EscapeSequence]]
!!Escape sequence

Anything placed between [=[= and =]=] is not interpreted by PmWiki, but paragraphs are reformatted.  This makes it possible to turn off  special formatting interpretations and neutralise [=WikiWords=] that are not links (even easier is to use a tick ` in front, like [=`WikiWord=]).

For preformatted text blocks, use the [=[@...@]=] markup. It does neither reformat paragraphs nor process wiki markup:

(:markup:)
[@
Code goes here like [[PmWiki.PmWiki]]
'$CurrentTime $[by] $AuthorLink:  [=$ChangeSummary=]'; #just some code
@]
(:markupend:)

It is also useful to use [=[= =]=] within other wiki structures, as this enables the inclusion of new lines in text values.  The example below shows how to include a multi-line value in a hidden form field.

->[@(:input hidden message "[=Line1
Line2=]":)@]

[[#SpecialCharacters]]
!!  Special Characters
(:include SpecialCharacters:)

[[#Tables]]
!!  Tables

[[Tables]] are defined by enclosing cells with '||'.  
A cell with leading and trailing spaces is centered; a cell with leading spaces is right-aligned; all other cells are left-aligned.  An empty cell will cause the previous cell to span multiple columns.  (There is currently no mechanism for spanning multiple rows.)  A line beginning with '||' specifies the table attributes for subsequent tables. A '!' as the first character in a cell provides emphasis that can be used to provide headings. This is interesting stuff.

(:markup:)

||border=1 width=50%
||!Table||!Heading||!Example||
||!Left   || Center || Right||
||A       ||!  a B   ||     C||
||        || single ||      ||
||        || multi span   ||||
(:markupend:)

See [[Table Directives]] for advanced tables.

!!!Can't find it here?
See [[Markup Master Index]]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Ed W</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Troubleshooting</pagename>
<data><![CDATA[(:Summary:Advice for troubleshooting an installation:)
(:Audience: administrators :)

Pmwiki is pretty robust and can automatically adapt to a very wide variety of environments.  
However, sometimes things don't go as we expect, so we're cataloging common errors and their fixes here.

!! Troubleshooting Frequently Asked Questions

->%note% Note: This page on pmwiki.org is probably not the best place to post questions.  Consider [[PmWiki:HowToGetAssistance | seeking assistance]] from the pmwiki-users [[mailing list(s)]], or post your question on the [[PmWiki:Questions]] page.

>>faq<< [[#faq]]
Q: Why am I seeing strange errors after [[(PmWiki.)upgrad(es)]]ing?
A: Make sure all of the files were updated, in particular ''pmwiki.php''.

A: This question sometimes arises when an administrator hasn't
followed the advice, which used to be less prominent, on the
[[(PmWiki.)installation(#notes)]] and
[[(PmWiki.)initial setup tasks(#dontmodify)]] pages and has renamed
''pmwiki.php'' instead of creating an ''index.php'' wrapper script.
If you have renamed ''pmwiki.php'' to ''index.php'', then the upgrade procedure
won't have updated your ''index.php'' file.  Delete the old version and
create a wrapper script so it won't happen again.

A: Sometimes an FTP or other copy program will fail to transfer all of the
files properly.  One way to check for this is by comparing file sizes.

A: Be sure all of the files in the ''wikilib.d/'' directory
were also upgraded.  Sometimes it's a good idea to simply delete the ''wikilib.d/''
directory before upgrading.  (Local copies of pages are stored in ''wiki.d/'' and not ''wikilib.d/''.)

Q: I'm suddenly getting messages like "@@Warning: fopen(wiki.d/.flock): failed to open stream: Permission denied...@@" and @@Cannot acquire lockfile@@"... what's wrong?

A: Something (or someone) has changed the [[PmWiki/FilePermissions | permissions]] on the ''wiki.d/.flock'' file or the ''wiki.d/'' directory such that the webserver is no longer able to write the lockfile.  The normal solution is to simply delete the ''.flock'' file from the ''wiki.d/'' directory  -- PmWiki will then create a new one.  Also be sure to check the permissions on the ''wiki.d/'' directory itself. (One can easily check and modify permissions of the ''wiki.d/'' directory in %newwin%[[http://filezilla-project.org/ | FileZilla]] (open-source FTP app) by right-clicking on the file > File attributes)

Q: My links in the sidebar seem to be pointing to non-existent pages, even though I know I created the pages.  Where are the pages?

A: Links in the sidebar normally need to be qualified by a [[WikiGroup]] in order to work properly (use [=[[Group.Page]] instead of [[Page]]=]).\\
Also: Make sure you type Side'''B'''ar with a capital B.

Q: Why am I seeing "@@Warning: Cannot modify header information - headers already sent ...@@" messages at the top of my page.

A: If this is the first or only error message you're seeing, it's usually an indication that there are blank lines or spaces before the [@<?php@] or after the [@?>@] in a [[local customization(s)]] file.  Double-check the file and make sure there aren't any blank lines or spaces before the initial [@<?php@].  It's often easiest and safest to eliminate any closing [@?>@] altogether.  On Windows, it may be necessary to use a hex editor to convert LFCR line endings to LF line endings in the local\config.php file.

A: If the warning is appearing after some other warning or error message, then resolve the other error and this warning may go away.

[[#session_write_close_error]]
Q: How do I make a PHP Warning about @@function.session-write-close@@ go away?

A: If you are seeing an error similar to this

->[@
Warning: session_write_close() [function.session-write-close]:
open(/some/filesystem/path/to/a/directory/sess_[...]) failed: No such file
or directory (2) in /your/filesystem/path/to/pmwiki.php on line NNN
@]

PmWiki sometimes does session-tracking using PHP's
[[http://php.net/session | session-handling functions ]].
For session-tracking to work, some information needs to be written
in a directory on the server.  That directory needs to exist and
be writable by the webserver software.  For this example, the
webserver software is configured to write sessions in this
directory

->[@/some/filesystem/path/to/a/directory/@]

but the directory doesn't exist.  The solution is to do at least one
of these:
* Create the directory and make sure it's writable by the webserver software
* Provide a session_save_path value that points to a directory that is writable by the server, e.g.

->[@session_save_path('/home/someuser/tmp/sessions');@]

[[#multiplepwprompts]]
Q: Why is PmWiki prompting me multiple times for a password I've already entered?

A: Usually this is an indication that the browser isn't accepting cookies, or that PHP's session handling functions on the server aren't properly configured.  If the browser is accepting cookies, then try setting $EnableDiag=1; in ''local/config.php'', run PmWiki using [@?action=phpinfo@], and verify that sessions are enabled and that the session.save_path has a reasonable value.  Note that several versions of PHP under Windows require that a session_save_path be explicitly set (this can be done in the ''local/config.php'' file).  You might also try setting session.auto_start to 1 in your php.ini.

Q: I edited ''config.php'', but when I look at my wiki pages, all I see is "@@Parse error: parse error, unexpected T_VARIABLE in ''somefile'' on line ''number''.@@"

A: You've made a mistake in writing the PHP that goes into the ''config.php'' file. The most common mistake that causes the T_VARIABLE error is forgetting the semi-colon (;) at the end of a line that you added. The line number and file named are where you should look for the mistake.

Q: Searches and pagelists stopped working after I upgraded -- no errors are reported, but links to other pages do not appear (or do not appear as they should) -- what gives?

A: Be sure all of the files in the ''wikilib.d/'' directory
were also upgraded.  In particular, it sounds as if the Site.PageListTemplates page is either missing (if no links are displayed) or is an old version (if the links do not appear as they should). Allso make sure that read-permissions (attr) are set for the pages Site.PageListTemplates and Site.Search.

[[#mod_security]]
Q: Some of my posts are coming back with "403 Forbidden" errors, "Not Acceptable", or "Internal Server Error".  This happens with some posts but not others.

A: Your webserver probably has [[http://modsecurity.org | mod_security]] enabled.  The mod_security "feature" scans all incoming posts for forbidden words or phrases that might indicate someone is trying to hack the system, and if any of them are present then Apache returns the 403 Forbidden error.  Common phrases that tend to trigger mod_security include "curl ", "wget", "file(", and "system(", although there are many others.

Since mod_security intercepts the requests and sends the "forbidden"
message before PmWiki ever gets a chance to run, it's not a bug in PmWiki, and
there's little that PmWiki can do about it.  Instead, one has to alter the
webserver configuration to disable mod_security or reconfigure it to allow
whatever word it is forbidding.  Some sites may be able to disable mod_security
by placing [@SecFilterEngine off@] in a ''.htaccess'' file.

Q: I get the following message when attempting to upload an image, what do I do?
[-@@'''Warning''': move_uploaded_file(): SAFE MODE Restriction in effect. The script whose uid is 1929 is not allowed to access /home/onscolre/public_html/pmwikiuploads/Photos owned by uid 33 in '''/home/onscolre/public_html/pmwiki/scripts/upload.php''' on line '''198'''@@-]

@@'''PmWiki can't process your request'''@@

[-@@?cannot move uploaded file to /home/onscolre/public_html/pmwikiuploads/Photos/FoundationPupilsIn1958.jpeg@@-]

[-@@We are sorry for any inconvenience.@@-]

A: Your server is configured with PHP [[http://php.net/manual/en/features.safe-mode.php|Safe Mode]] enabled.  Configure your wiki to use a [[PmWiki/UploadsAdmin#sitewideprefix|site-wide uploads prefix]], then create the ''uploads/'' directory manually and set 777 permissions on it (rather than letting PmWiki create the directory).

[[#TableRowIndexMax]] [[#divisionbyzero]]
Q: I'm starting to see "Division by zero error in pmwiki.php..." on my site.  What's wrong?

A: It's a bug in PmWiki that occurs only with the [[tables]] markup and only for versions of PHP >= 4.4.6 or >= 5.2.0.  Often it seems to occur "out of nowhere" because the server administrator has upgraded PHP.  Try [[upgrad(es)]]ing to a later version of PmWiki to remove the error, or try setting the following in ''local/config.php'':

    $TableRowIndexMax = 1;

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.UTF-8</pagename>
<data><![CDATA[!!!Enabling UTF-8 Unicode language encoding in your page header. 

UTF-8 allows for support of various languages, including Asian languages and their character depth.  It is a widely supported and flexible character encoding, used for many European languages and can also represent Chinese, Japanese and Korean. 

It's fairly simple to enable UTF-8 on your wiki pages.  Currently PmWiki 2.0 versions have the UTF-8 file needed already loaded. 

!!!!Here are the steps to enable UTF-8 

*Open your config.php file
*Add this line:[[<<]]'''include_once($FarmD.'/scripts/xlpage-utf-8.php');'''
*save and upload your config.php file back to the server.

If you validate your site you should see that UTF-8 is default encoding.

See also [[Cookbook:UTF-8]] for tips.]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Anno</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Upgrades</pagename>
<data><![CDATA[(:Summary:How to upgrade an existing PmWiki installation:)
[[PmWiki]] is designed to make it easy to upgrade the PmWiki software without affecting your existing data files or installation.  For most upgrades, you simply copy the files in the new release over your existing installation.

%block bgcolor=#f7f7f7 color=black border='1px solid black' padding=5px% '''Note for PmWiki 1.0 sites:''' Upgrading from 1.0.x to 2.0 requires more than simply copying the 2.0 software over the 1.0 installation.  See [[PmWiki:Upgrading From PmWiki 1]] for more details.

!! To upgrade PmWiki: 

!!! 1. Read the release notes
If you're upgrading to a new major release (a release where the second number changes, as in going from 0.5.27 to 0.6.0), then carefully read the [[(PmWiki:)ReleaseNotes]] before performing an upgrade to see if there are any significant changes or preparation tasks that must be handled before performing the upgrade. Upgrading from a beta version of 2.0 is quite easy, but taking a look at the 2.0 [[(PmWiki:)ReleaseNotes]] doesn't hurt.

!!! 2. Backup
It's ''always'' a good idea to have a [[(PmWiki:)backup (And Restore)]] copy of your existing PmWiki installation before starting.  You can copy the entire directory containing your existing installation, or you can just make copies of the ''wiki.d/'' directory and any other local customization files you may have created (e.g., ''config.php'', ''localmap.txt'', etc.).

!!! 3. Download and extract
Download the version of PmWiki that you want from the [[(PmWiki:)download]] page.

Extract the tar image using @@tar -xvzf ''tgzfile''@@, where ''tgzfile'' is the tar file you downloaded above.  This will create a @@pmwiki-x.y.z@@ directory with the new version of the software.

!!! 4. Copy
Copy the files in @@pmwiki-x.y.z@@ over the files of your existing PmWiki installation.  For example, if your existing PmWiki installation is in a directory called ''pmwiki'', then one way to copy the new files over the existing ones is to enter the command:

->@@cp -a pmwiki-x.y.z/. pmwiki@@

Note that BSD systems will not have the -a option as a command-line argument for ''cp'', but that's okay, since it's just shorthand for ''cp -dpR'', so use that instead of ''-a''.

On (some) [=FreeBSD=] servers and Mac OS X systems you need to use 

->@@cp -Rpv pmwiki-x.y.z/. pmwiki@@

!!! 5. Update customisations and recipes
That's it! Your base PmWiki installation is complete.

Now use the [[PmWiki:Site Analyzer]] to determine which recipes could be updated to the most recent version.

Unless you have made customizations to the ''pmwiki.php'' script or to the files in ''scripts/'', your PmWiki installation should continue to run correctly! (Changes to these files are {+not+} recommended).

([[Local customizations]] should go in ''local/config.php'', ''pub/css'', and ''pub/skins/''yourskinname)

'''Note''': Additional tips can be found on the [[PmWiki:Troubleshooting]] page.

>>faq<< [[#faq]]

Q: How can I determine what version of PmWiki I'm running now?
A: See [[version]] - {Version$:Summary}.

Q: How can I test a new version of PmWiki on my wiki without changing the prior version used by visitors?
A: The easy way to do this is to install the new version in a separate
directory, and for the new version set (in local/config.php):
[@

    $WikiLibDirs = array(&$WikiDir,
      new PageStore('/path/to/existing/wiki.d/{$FullName}'),
      new PageStore('wikilib.d/{$FullName}'));

@]
This lets you test the new version using existing page content
without impacting the existing site or risking modification of
the pages.  (Of course, any recipes or local customizations have to
be installed in the new version as well.) 

Then, once you're comfortable that the new version seems to work
as well as the old, it's safe to upgrade the old version (and one
knows of any configuration or page changes that need to be made).]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.UpgradingFromPmWiki1</pagename>
<data><![CDATA[This page gives suggestions for upgrading an existing PmWiki 1.x installation to use PmWiki 2.0.  In this page we assume that a site [[(wiki) administrator]] already has a site running using PmWiki version 1.x or earlier in a somewhat standard configuration, and wants to upgrade to the 2.0 software.

->'''Important note:''' The normal PmWiki [[upgrade(s)]] procedure (i.e., copy the new software over the existing one) won't work for moving from 1.x to 2.0.  Either start over with a new installation, or use some of the conversion scenarios listed below.

As always, questions and requests for assistance can be posed to [[Mailing lists | pmwiki-users]].  Errors or problems with the methods below can be corrected here, or posted to the [[PITS:PITS |PmWiki Issue Tracking System]].

!!!Method 1: Test conversion

Because of the substantial redesign of PmWiki for 2.0, converting an existing site to 2.0 is likely to cause a [[wiki administrator]] a fair amount of apprehension.  The approach given here allows the administrator to install, configure, and test PmWiki 2.0 on an existing set of pages without risking an existing 1.x installation.

'''Step 0:'''  It's always a very good idea to back up your existing PmWiki 1.x installation before doing anything else -- especially save the files in the ''local/'' and ''wiki.d/'' directories.

'''Step 1:'''  [[Install(ation)]] PmWiki 2.0 into a new directory away from the existing 1.x installation.

'''Step 2:'''  Briefly test the PmWiki 2.0 installation and make sure it is working properly -- i.e., edit and save a couple of pages.  Then, remove the pages you created (you can just remove the files from PmWiki 2.0's ''wiki.d/'' directory, or remove the ''wiki.d/'' directory altogether).

'''Step 3:'''  Add the following lines to the ''local/config.php'' file in the 2.0 installation, replacing "[@/path/to/pmwiki1/wiki.d@]" below with the location of your PmWiki 1.x installation's ''wiki.d/'' directory on disk.
    [=
    include_once("$FarmD/scripts/compat1x.php");
    UseV1WikiD("/path/to/pmwiki1/wiki.d");
    =]
For example, my 2.0 test conversion uses:
    [=
    include_once("$FarmD/scripts/compat1x.php");
    UseV1WikiD("/home/pmichaud/pmwiki/wiki.d");
    =]
'''Step 4:'''  After making the above change, all of your existing pages should appear in the new 2.0 installation.  Furthermore, if you "edit page" on any of the existing pages, you should see that any PmWiki 1.x markups (links, etc.) have been converted to the new markup syntax.

Any pages edited/saved by the 2.0 wiki installation are kept separate from the pages in the previous installation.  Thus you can safely experiment with editing and changing pages in the new site without affecting the existing 1.x site. 

'''Step 5:'''  Once you see that your existing pages are available in the 2.0 installation, you can then begin going through the remaining [[initial setup tasks]] for the 2.0 site to enable any [[local customizations]] you may want for your site.  Many local customizations (e.g. page layout templates) remain the same between 1.x and 2.0, others such as [[custom markup]] or [[Cookbook:Cookbook |cookbook recipes]] need to be converted to 2.0 as well.  

'''Note:''' [[WikiWord]] links are disabled by default since Pmwiki version 2.1 beta2. So you may either enable WikiWord links by setting [@$LinkWikiWords = 1;@] in config.php, or convert your existing WikiWord links manually to bracketed links. To find those WikiWord links easier you can highlight them by setting in config.php

       [=$HTMLStylesFmt['wikiword'] = "
       span.wikiword { background:yellow; }
       ";=] 

'''Step 6:'''  Continue configuring the new installation just as if you were setting up a new PmWiki site.  If you find PmWiki 1.x markups that aren't converted or convert incorrectly, be sure to enter a [[PITS:NewIssue |new PITS issue]] so that we can improve the conversion script.

'''Step 7:'''  If you're comfortable with the conversion and want to go ahead and convert all of the 1.x pages into 2.0 format, change the [@UseV1WikiD(...)@] call in ''local/config.php'' above to [@ConvertV1WikiD(...)@] instead, as in:
    [=
    include_once("$FarmD/scripts/compat1x.php");
    ConvertV1WikiD("/path/to/pmwiki1/wiki.d");
    =]
Running the pmwiki.php script will then bring up some forms to allow you to bulk migrate some or all of your 1.x pages to 2.0 format.  After you've converted pages, you can then just eliminate these two lines from the configuration and your PmWiki 2.0 site will be running standalone.

If you have local customisations that require you to specify $Compat1x['/match/'] = 'replace'; entries so they are correctly converted, make sure these are defined ''before'' the call to ConvertV1WikiD.

Note that there's nothing that requires you to convert all of the pages or get rid of the 1.x ''wiki.d/'' directory -- PmWiki works just fine with it in place.  And it's good to have a backup.

'''Step 8:''' Once you're comfortable that the PmWiki 2.0 site will meet your needs, you can then discontinue the 1.x site and just start using the 2.0 site.  Or, if you decide that 2.0 isn't for you, then the 1.x site is still intact and can continue to be used.

'''Step 9:''' If your previous site had an ''uploads/'' directory, you'll probably want to copy it or move it into the new location.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.UploadVariables</pagename>
<data><![CDATA[(:Summary:variables used for uploads/attachments:)

See also: [[Uploads]], [[Uploads admin]].

:$EnableUpload:The upload.php script is automatically included from stdconfig.php if the $EnableUpload variable is true in config.php.  Note that one may still need to set an upload password before users can upload (see [[UploadsAdmin]]).

:$UploadDir:The directory where uploads are to be stored.  Defaults to ''uploads/'' in the pmwiki directory, but can be set to any location on the server.  This directory must be writable by the webserver process if uploading is to occur.

:$UploadUrlFmt:The url of the directory given by $UploadDir. By default, $UploadUrlFmt is derived from $PubDirUrl and $UploadDir.

$IMapLinkFmt['Attach:'] 
->The format of the upload link displayed when an attachment is present. No default is set. 

:$LinkUploadCreateFmt: The format of the upload link displayed when an attachment not present. Defaults to
      <a class='createlinktext' href='\$LinkUpload'>\$LinkText</a>\\
      <a class='createlink' href='\$LinkUpload'>&nbsp;&Delta;</a>");

:$UploadPrefixFmt:Sets the prefix for uploaded files to allow attachments to be organized other than by groups.  Defaults to [@'/$Group'@] (uploads are organized per-group), but can be set to other values for sitewide or per-page attachments.
    $UploadPrefixFmt = '/$Group/$Name';    # per-page attachments
    $UploadPrefixFmt = '';                 # sitewide attachments

:$EnableDirectDownload:When set to 1 (the default), links to attachments bypass PmWiki and come directly from the webserver.  Setting $EnableDirectDownload=0; causes requests for attachments to be obtained via [[PmWiki/AvailableActions#download|[@?action=download@]]].  This allows PmWiki to protect attachments using a page's read permissions, but also increases the load on the server. Don't forget to protect your directory /uploads/ with a .htaccess file (Order Deny,Allow / Deny from all).

:$EnableUploadGroupAuth:Set @@$EnableUploadGroupAuth = 1;@@ to authenticate downloads with the group password. This could be used together with @@$EnableDirectDownload = 0;@@.

:$EnableUploadVersions:When set to 1 (default is 0), uploading a file to a location where a file of the same name already exists causes the old version to be renamed to @@file.ext,timestamp@@ (instead of being overwritten). @@timestamp@@ is a Unix-style timestamp.

:$EnableUploadOverwrite:When set to 1 (the default), determines if overwriting previously uploaded files is allowed.

:$UploadNameChars:The set of characters allowed in upload names.  Defaults to [@"-\w. "@], which means alphanumerics, hyphens, underscores, dots, and spaces can be used in upload names, and everything else will be stripped.
: :$UploadNameChars = "-\\w. !=+";    # allow exclamations, equals, and plus
: :$UploadNameChars = "-\\w. \\x80-\\xff"; # allow unicode

:$UploadPrefixQuota:Overall size limit for groups, in the group configuration file (i.e., local/Group.php)

:$UploadDirQuota:Overall size limit for all uploads.

->[@
   $UploadDirQuota = 100*1024;         # limit uploads to 100KiB
   $UploadDirQuota = 1000*1024;        # limit uploads to 1000KiB
   $UploadDirQuota = 1024*1024;        # limit uploads to 1MiB
   $UploadDirQuota = 25*1024*1024;     # limit uploads to 25MiB
   $UploadDirQuota = 2*1024*1024*1024; # limit uploads to 2GiB
@]

:$UploadMaxSize:Maximum size for uploading files, 50000 octets (bytes) by default.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Uploads</pagename>
<data><![CDATA[(:Summary:Allow authors to upload files, also known as page attachments:)
(:Audience: authors (intermediate) :)
[[PmWiki]] can be configured to allow authors to upload and store files and [[images]] (known as attaching them).
These attachments may then be referenced from any page.  

-> ''Note'': ''[[PmWiki]] is distributed with uploads disabled by default.  See [[Uploads Admin]] for information about how to enable and configure the upload feature.''

-> ''Note2'': ''Uploads can be configured site-wide, by-group, or by-page; see [[Uploads Admin]] for details. This determines whether all uploads go in one directory for the site, an individual directory for each group, or an individual directory for each page. The default is to organize uploads by [[WikiGroup | group]].''

!! [@Attach:@] Syntax
To add or link to an attachment, an author edits a page to include the markup "@@Attach:@@" followed by a name of an attachment (e.g., "@@[=Attach:resume.pdf=]@@").  When the page is displayed, the @@Attach:@@ markup becomes one of the following:

* A link to the named attachment (if uploaded, ie already in the upload directory)
* A link to a form whereby the author can specify a file to be uploaded and used as the new attachment (if not yet uploaded, ie not in the upload directory)
* If the attachment is an [[image(s)]] file with an extension such as .gif, .jpeg, or .png, it is displayed as an [[image(s)]].

The behaviour of links can be modified to
* prevent an image attachment from displaying as an image, place it in double brackets (e.g., [@[[Attach:image.jpg]]@]).
* have a link to an attachment appear without the "[@Attach:@]" at the beginning of the link, use [@[[(Attach:)file.ext]]@].

!! Attachments on other pages and groups
To link  to an uploaded attachment (image or file) from another group, you simply refer the group itself (make sure "Groupname" has the dot in it).
->[@Attach:Groupname./file_name.ext@]
If PmWiki is configured with an individual directory per page use
->[@Attach:Groupname.Pagename/file_name.ext@]

!! Names with spaces
To link to a filename with spaces in it use the bracket link notation, eg
->[@[[Attach:a filename with spaces.txt]]@]
To attach an [[PmWiki/image(s)]] file with spaces in the name so that is shows as an image use one of these {+workarounds+}
->[@[[#blank | Attach:image space.jpeg]]@]
->[@[[#1 | Attach:image space.jpeg]]@]

!! Listing Uploaded Files On A Page
To list files that have been uploaded, use the markup:
[[PmWiki/PageDirectives#attachlist | [@(:attachlist:)@] ]]

This will list attachments to the current group or page, depending whether attachments are organised per group or per page; each instance includes a link to the attachment for viewing or downloading.  A list of attachments is also shown as part of the uploads page form.

!!!Upload Form / Upload Replacement
One can go directly to the upload form by appending "?action=upload" to the URI for any page that has file uploads enabled by the [[Wiki Administrator]]. Replace a file by simply uploading a new version of the file with the same name. 
* Be sure to clear your browser cache after replacing an upload. Otherwise, it may appear that the original upload is still on the server. 
If you put @@$EnableUploadVersions=1;@@ in your @@local/config.php@@, the old versions of the same files are renamed and not removed.

!!!Type and Size Restrictions
For security reasons, the upload feature is disabled when PmWiki is first installed.
When enabled uploads are restricted as to the types and sizes of files that may be uploaded to the server (see [[UploadsAdmin]]).  PmWiki's default configuration limits file sizes to 50 kilobytes and file extensions to common types such as ".gif", ".jpeg", ".doc", ".txt", and ".pdf".  

In addition, the administrator can configure the system to require an @@upload@@ password--see [[Passwords]] and [[PasswordsAdmin]].

By default the upload allows the following extensions:

[[#imagetypes]]   
->[@'gif','jpg','jpeg','png','bmp','ico','wbmp',          # images
@]
[[#imagetypesend]]
->[@'mp3', 'au','wav',                                    # audio
'mpg','mpeg','wmf','mov','qt','avi',                  # video
'zip', 'gz','tgz','tar','rpm','hqx',                  # archives
'odt','ods','odp',                                    # OpenOffice.org
'doc','ppt','xls','exe','mdb',                        # MSOffice
'pdf','psd', 'ps','ai','eps',                         # Adobe
'htm','html','fla','swf',                             # web stuff
'txt','rtf','exe','tex','dvi',''                      # misc@]

!!!Removal
At present uploaded files can only be deleted from the server by the [[wiki administrator]]. Any uploads-authorized user may over-write an existing file by uploading another of the same name and extension to the same location.

The administrator may remove an uploaded file by accessing the server via ftp (or via a control panel, if the host offers such a feature). The recipe Cookbook:Attachtable allows the deletion of the files from the wiki.

>>faq<< [[#faq]]

Q: When I upload a file, how do I make the link look like "file.doc" instead of "Attach:file.doc"?
A: Use parentheses, as in [@[[(Attach:)file.doc]]@].  There is also a configuration change that can eliminate the [@Attach:@] -- see [[Cookbook:AttachLinks]].

Q: Why can't I upload files of size more than 50kB to my newly installed PmWiki?
A: Out of the box PmWiki limits the size of files to be uploaded to 50kB. Add
->@@$UploadMaxSize = 1000000; # limit upload file size to 1 megabyte@@
->to your ''config.php'' to increase limit to 1MB (for example). See [[UploadsAdmin]] for how to further customize limits.  Note that both PHP and webservers also place their own limits on the size of uploaded files.

Q: Why does my upload exit unexpectedly with "Incomplete file received"?
A: You may be running out of space in a 'scratch' area, used either by PmWiki or by PHP.  On *nix, check that you have sufficient free space in /tmp and /var/tmp.

Q: How do I make it so that the upload link still allows one to make another upload (if someone wants to replace the old version of a file with a newer version, for example). Currently you only get the upload link when there is no file in the upload directory.
A: Use the Attach [[Site/page action(s)]], and click on the delta symbol %blue%(&Delta;)%% shown against each of files listed. If you can't see the attach action either uploads are not enabled, you are not not authorized to upload, or the attach action has been commented out or is missing. See also [[PmWiki/available actions]].

Q: How do I hide the "[=Attach:=]" for all attachments
A: See Cookbook:AttachLinks, note that this does not currently work for [@ [[Attach:my file.ext]] @].

Q: How to avoid problems with non-ASCII characters in attachment names (i.e. "Za&#380;ó&#322;&#263; ge&#347;l&#261; ja&#378;&#324;.doc")?
A: See $UploadNameChars[@ = "-\w. !=+#";@]%% # allow exclamations, equals, plus, and hash

Q: How can I link a file that have a 4-letter file extension such like 'abc.pptx'?
A: See [[Cookbook:Upload Types]]

Q: How can I prevent others from using the url's of my images on their site
A: See [[Cookbook:Prevent Hotlinking]] {Cookbook.PreventHotlinking$:Summary}

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.UploadsAdmin</pagename>
<data><![CDATA[(:title Uploads Administration:)
(:Summary:Administration of PmWiki [[uploads]]:)
[[PmWiki]] includes a script called ''upload.php'' that allows users to [[upload(s)]] files to the wiki server using a web browser.  Uploaded files (also called ''attachments'') can then be easily accessed using markup within wiki pages.  This page describes how to install and configure the upload feature.

!! Some notes about [[security]]

PmWiki takes a somewhat, but justifiable, paranoid stance
when it comes to the uploads feature.  Thus, the default settings for
uploads tend to try to restrict the feature as much as possible:

* The upload function is disabled by default
* Even if you enable it, the function is password locked by default
* Even if you remove the password, you're restricted to uploading files with certain names, extensions, and sizes
* The characters that may appear in upload filenames are (default) alphanumerics, hyphen, underscore, dot, and space ([[#restrictinguploadedfiles|see also here]]).
* The maximum upload size is small (50K by default)

This way the potential damage is limited until/unless the wiki
administrator explicitly relaxes the restrictions.

Keep in mind that letting users (anonymously!) upload files to your web server does entail some amount of risk.  The ''upload.php'' script has been designed to reduce the hazards, but [[wiki administrator]]s should be aware that the potential for vulnerabilities exist, and that misconfiguration of the upload utility could lead to unwanted consequences.

By default, authorized users are able to overwrite files that have already been uploaded, without the possibility of restoring the previous version of the file.  If you want to disallow users from being able to overwrite files that have already been uploaded, add the following line to ''config.php'':

->[@$EnableUploadOverwrite = 0;@]

Alternatively, an administrator can [[#upload_versions|keep older versions]] of uploads.

An administrator can also [[#direct_download|configure]] PmWiki so the password mechanism controls access to uploaded files.

!! Basic installation

The ''upload.php'' script is automatically included from ''stdconfig.php'' if the $EnableUpload variable is true in ''config.php''.  In addition, ''config.php'' can set the $UploadDir and $UploadUrlFmt variables to specify the local directory where uploaded files should be stored, and the URL that can be used to access that directory.  By default, $UploadDir and $UploadUrlFmt assume that uploads will be stored in a directory called ''uploads/'' within the current directory (usually the one containing ''pmwiki.php'').  In addition, ''config.php'' should also set a default upload password (see [[PasswordsAdmin]]).

Thus, a basic ''config.php'' for uploads might look like:

->[@
<?php if (!defined('PmWiki')) exit();
##  Enable uploads and set a site-wide default upload password.
$EnableUpload = 1;
$DefaultPasswords['upload'] = crypt('secret');
@]

If you have edit passwords and wish to allow all users with edit rights to upload, instead of $DefaultPasswords['upload'], you can set @@$HandleAuth['upload'] = 'edit';@@ in config.php.

'''Important''': do NOT create the uploads directory yet! See the next paragraph.

You may also need to explicitly set which filesystem directory will hold uploads and provide a URL that corresponds to that directory like:

->[@
$UploadDir = "/home/foobar/public_html/uploads";
$UploadUrlFmt = "http://example.com/~foobar/uploads";
@]

[[#uploaddirectoryconfiguration]]
!!! Upload directory configuration
Uploads can be configured site-wide, by-group, or by-page by changing $UploadPrefixFmt.  This determines whether all uploads go in one directory for the site, an individual directory for each group, or an individual directory for each page.  The default is to organize upload by group.

[[#sitewideprefix]]For site-wide uploads, use

->[@$UploadPrefixFmt = '';@]

To organize uploads by page, use:
->[@
$UploadPrefixFmt = '/$Group/$Name';
@]

!!! The upload directory

For the upload feature to work properly, the directory given by [=$UploadDir=] must be writable by the web server process, and it usually must be in a location that is accessible to the web somewhere (e.g., in a subdirectory of ''public_html'').  Executing PmWiki with uploads enabled will prompt you with the set of steps required to create the uploads directory on your server (it differs from one server to the next). ''Note that you are likely to be required to explicitly create writable group- or page-specific subdirectories as well!''

!!! Uploading a file

Once the upload feature is enabled, users can access the upload form by adding "@@?action=upload@@" to the end of a normal PmWiki URL.  The user will be prompted for an upload password similar to the way other pages ask for passwords (see [[Passwords]] and [[PasswordsAdmin]] for information about setting passwords on pages, groups, and the entire site).

Another way to access the upload form is to insert the markup "[@Attach:filename.ext@]" into an existing page, where @@filename.ext@@ is the name of a new file to be uploaded.  When the page is displayed, a '?-link' will be added to the end of the markup to take the author to the upload page. (See [[Uploads]] for syntax variations.)

By default, PmWiki will organize the uploaded files into separate subdirectories for each group.  This can be changed by modifying the $UploadPrefixFmt variable. See [[Cookbook:UploadGroups]] for details.

!! [[#upload_versions]] Versioning Uploaded Files

PmWiki does not manage versioning of uploaded files by default. However, by setting $EnableUploadVersions=1; an administrator can have older versions of uploads preserved in the uploads directory along with the most recent version.

!! Upload restrictions
!!! Restricting uploaded files for groups and pages

Uploads can be enabled only for specific groups or pages by using a [[per group customization(s)]].  Simply set @@$EnableUpload=1;@@ for those groups or pages where uploading is to be enabled; alternately, set @@$EnableUpload=1;@@ in the config.php file and then set @@$EnableUpload=0;@@ in the per-group or per-page customization files where uploads are to be disabled.

!!! Restricting total upload size for a group or the whole wiki

Uploads can be restricted to an overall size limit for groups.  In the group configuration file (i.e., local/Group.php), add the line

->$UploadPrefixQuota = 1024000;    # limit group uploads to 1000K

This will limit the total size of uploads for that group to 1000k --any upload that pushes the total over the limit will be rejected with an error message.  This value defaults to zero (unlimited).

Uploads can also be restricted to an overall size limit for all uploads.  Add the line

->$UploadDirQuota = 10240000;    # limit total uploads to 10000K

This will limit the total size of uploads for the whole wiki to 10000k --any upload that pushes the total over the limit will be rejected with an error message.  This value defaults to zero (unlimited).

[[#restrictinguploadedfiles]]
!!!Restricting uploaded files type and size

The upload script performs a number of verifications on an uploaded file before storing it in the upload directory.  The basic verifications are described below.
:'''filenames''': the name for the uploaded file can contain only letters, digits, underscores, hyphens, spaces, and periods, and the name must begin and end with a letter or digit.  
:'''file extension''': only files with approved extensions such as "@@.gif@@", "@@.jpeg@@", "@@.doc@@", etc. are allowed to be uploaded to the web server.  This is vitally important for server security, since the web server might attempt to execute or specially process files with extensions like "@@.php@@", "@@.cgi@@", etc.  
:'''file size''': By default all uploads are limited to 50K bytes, as specified by the $UploadMaxSize variable.  Thus, to limit all uploads to 100K, simply specify a new value for $UploadMaxSize in ''config.php'':

->[@$UploadMaxSize = 102400;@]

However, maximum file sizes can also be specified for each type of file uploaded.  Thus, an administrator can restrict "@@.gif@@" and "@@.jpeg@@" files to 20K, "@@.doc@@" files to 200K, and all others to the size given by $UploadMaxSize.  The $UploadExtSize array is used to determine which file extensions are valid and the maximum upload size (in bytes) for each file type.  For example:

->[@$UploadExtSize['gif'] = 20000; # limit .gif files to 20K@]

Setting an entry to zero disables file uploads of that type altogether:

->[@$UploadExtSize['zip'] = 0;     # disallow .zip files@]

You can limit which types of files are uploadable by disabling all defaults and specifying only desired types
Setting the variable $UploadMax to zero will disable all default file types. Individual file types may then be enabled by setting their maximum size with the variable $UploadExtSize.

-> [@# turns off all upload extensions
$UploadMaxSize = 0;

# enable only these file types for uploading
$aSize=102400; // 100 K file size limitation
$UploadExtSize['jpg' ] = $aSize;
$UploadExtSize['gif' ] = $aSize;
$UploadExtSize['png' ] = $aSize;
@]

[[#newuploadfiletypes]]
!! Adding new file types to permitted uploads

To add a new extension to the list of allowed upload types, add a line like the following to a [[local customization(s)]] file:

->[@$UploadExts['ext'] = 'content-type';@]

where ''ext'' is the extension to be added, and ''content-type'' is the "MIME type", or content-type (which you may find %newwin%[[http://www.iana.org/assignments/media-types/ | here]] or on the lower part of %newwin%[[http://www.w3schools.com/media/media_mimeref.asp | this page]]) to be used for files with that extension.  For example, to add the '[@dxf@]' extension with a Content-Type of '[@image/x-dxf@]', place the line

->[@$UploadExts['dxf'] = 'image/x-dxf';@]

Each entry in $UploadExts needs to be the extension and the
mime-type associated with that extension, thus:

->[@
$UploadExts = array(
  'gif' => 'image/gif',
  'jpeg' => 'image/jpeg',
  'jpg' => 'image/jpeg',
  'png' => 'image/png',
  'xxx' => 'yyyy/zzz'
);
@]

For the types that PmWiki already knows about it's not necessary to repeat them here (the ''upload.php'' script adds PmWiki's defaults to whatever the administrator supplies).
[[#newuploadfiletypesend]]
See also Cookbook:UploadTypes for additional types.

[[#otherfilesizelimits]]
!!Other file size limits

There are other factors involved that affect upload file sizes.  In Apache 2.0, there is a `LimitRequestBody directive that controls the maximum size of anything that is posted (including file uploads).  Apache has this defaulted to unlimited size.  However, some Linux distributions (e.g., Red Hat Linux) limit postings to 512K so this may need to be changed or increased.  (Normally these settings are in an ''httpd.conf'' configuration file or in a file in ''/etc/httpd/conf.d''.)

Problem noted on Red Hat 8.0/9.0 with Apache 2.0.x, the error "Requested content-length of 670955 is larger than the configured limit of 524288" was occurring under Apache and a "Page not found" would appear in the browser. Trying the above settings made no change with PHP, but on Red Hat 8.0/9.0 there is an additional PHP config file, /etc/httpd/conf.d/php.conf, and increasing the number on the line "`LimitRequestBody 524288" solves the issue.

PHP itself has two limits on file uploads (usually located in /etc/php.ini).  The first is the @@upload_max_filesize@@ parameter, which is set to 2M by default.  The second is @@post_max_size@@, which is set to 6M by default.

With the variables in place--PmWiki's maximum file size, Apache's request-size limits, and the PHP file size parameters, the maximum uploaded file size will be the smallest of the three variables.

!!! [[#direct_download]] Password protecting uploaded files
Setting a  read password for pages (and groups) will prevent an attached file from being seen or accessed through the page, but to prevent direct access to the file location (the uploads/ directory) one can do the following:
 
* In local/config.php set $EnableDirectDownload=0;
* If you use per-group upload directories (PmWiki default, see $UploadPrefixFmt), add to config.php @@$EnableUploadGroupAuth = 1;@@
* Deny public access to the uploads/ directory through moving it out of the html/ or public_html/ directory tree, or through a .htaccess file.

See [[Cookbook:Secure attachments]] {Cookbook.SecureAttachments$:Summary}

!! Other notes

* If uploads doesn't seem to work, make sure that your PHP installation allows uploads.  The ''php.ini'' file (usually ''/etc/php.ini'' or ''/usr/local/lib/php.ini'') should have  

->[@file_uploads = On@]

Note that if you change this value, httpd must generally be restarted.  Another way to check if uploads are allowed by the server is to set $EnableDiag to 1 in ''config.php'', and set ?action=phpinfo on a URL. The "@@file_uploads@@" variable must have a value of 1 (if it says "@@no value@@", that means it's off).

>>faq<< [[#faq]]

Q: How do I disable uploading of a certain type of file?
A: Here's an example of what to add to your ''local/config.php'' file to disable uploading of .zip files:

->[@$UploadExtSize['zip'] = 0;  # Disallow uploading .zip files.@]

Q: How do I attach uploads to individual pages or the entire site, instead of organizing them by [[wiki group]]?
A: Use the $UploadPrefixFmt variable (see also the Cookbook:UploadGroups recipe).

->[@$UploadPrefixFmt = '/$FullName';  # per-page@]
->[@$UploadPrefixFmt = '';   # site-wide@]

Q:For $UploadDirQuota - can you provide some units and numbers?  Is the specification in bytes or bits? What is the number for 100K? 1 Meg? 1 Gig? 1 Terabyte?
A: Units are in bytes. 

   $UploadDirQuota = 100*1024;         # limit uploads to 100KiB
   $UploadDirQuota = 1000*1024;        # limit uploads to 1000KiB
   $UploadDirQuota = 1024*1024;        # limit uploads to 1MiB
   $UploadDirQuota = 25*1024*1024;     # limit uploads to 25MiB
   $UploadDirQuota = 2*1024*1024*1024; # limit uploads to 2GiB

Q: Is there a way to allow file names with Unicode or addtiional characters? 
A: Yes, see $UploadNameChars

Q:Where is the list of attachments stored?
A: It is generated on the fly by the [[PageDirectives#attachlist|(:attachlist:)]] markup.

Q: How can I find orphaned or missing attachments
A: See [[Cookbook:Attachlist enhanced]] {Cookbook.AttachlistEnhanced$:Summary}

Q: How can I prevent hotlinking of my uploaded images
A: See [[Cookbook:Prevent Hotlinking]] {Cookbook.PreventHotlinking$:Summary}

Q: I have limited the max upload size to 8 Mb in config.php, however only files smaller than 2M can be uploaded.
A: Check your php.ini for ''upload_max_filesize''
->[@
upload_max_filesize = 8M
@]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.UrlApprovals</pagename>
<data><![CDATA[(:Summary:Require approval of Url links:)

This page explains how to discourage "link spamming" on your wiki site using PmWiki's ''urlapprove.php'' script. This script is already included in PmWiki files, but not activated by default.

!! Using ''urlapprove.php''
Occasionally spammers may try to add large number of (sometimes hidden) `URLs to pages because they think it will improve their search engine rankings -- which it [[#nofollow |probably won't]].  The ''urlapprove.php'' script works against these spammers' purpose by

* requiring approval of links to Internet sites before a link to them are created in the wiki, and
* allowing you to limit the number of unapproved links that may be added to a page.

To enable ''urlapprove.php'', add the following line to a configuration file:

->[@include_once("$FarmD/scripts/urlapprove.php");@]

By default, unapproved links display what ever should be displayed normally (the URL or a text), but not linked and next to it a link [-%blue%(approve links)%%-].
A click on the link will approve all unapproved `URLs on the page, %green%but ''only'' if you are authorized to edit the ''SiteAdmin.ApprovedUrls'' page%%.  You may also pre-approve sites by by adding them directly to the [[SiteAdmin.ApprovedUrls]] page.

!!! Limiting unapproved urls per page
You can limit the number of unapproved links per page. If the limit is exceeded, the page cannot be saved.  This is useful because spammers like to write long link lists, which is rare for normal authors.

Example: To set the limit to 5 unapproved links, add the following line to a configuration file:

->[@$UnapprovedLinkCountMax = 5;@]
->[@include_once('scripts/urlapprove.php');@]

Note that $UnapprovedLinkCountMax must be set ''before'' including the ''urlapprove.php'' script.

!!! Handling of Unapproved Links
You can also change the disapproval message defined in the $UnapprovedLinkFmt variable, for example:

-> [@
include_once('scripts/urlapprove.php');
$UnapprovedLinkFmt =
 "[$[Link requires approval]]<a class='apprlink'
  href='\$PageUrl?action=approvesites'>$[(approve)]</a>";
@]

"Link requires approval" is whatever you want to see in place of the unapproved link and "(approve)" is the blue text. Using this feature may prove usefull if you want to always hide the unapproved link.

If you wish to totally forbid unapproved links you can use

->[@$UnapprovedLinkFmt = "<b>external link not allowed</b>";@]

!!! `SideBar caveat [[#sidebar]]
Please note that in general you need to go to the sidebar page in order to approve links in the sidebar. The reason for this is that the approve mechanism only approves links on the ''current'' page.

!!! Initial setup
After initial setup all existing links become unapproved. You need to visit your pages and approve all links, where needed. See [[Site/AllRecentChanges]] for a list of all pages that were created on your wiki.

!! Technical tips
[[#whiteurls]]
!!! URL Whitelist
Urls can also be approved by adding them to a "white list", 
defined in the variable @@$WhiteUrlPatterns@@, 
which is set in the ''local/config.php'' file.\\
To add multiples urls, use the separator @@|@@ (vertical bar).  For example:

-> [@
$WhiteUrlPatterns =
  "http://example.com/|http://example.net/|http://example.org/";
@]

To add all urls from, say New Zealand and Australia, use:

-> [@
$WhiteUrlPatterns[] = 'http://[^/] \\.nz';
$WhiteUrlPatterns[] = 'http://[^/] \\.au';
@]

!!! Change Approved URLs page name
If you want to change the default name of ''SiteAdmin.ApprovedUrls'', set the following in ''local/config.php'':

->[@$ApprovedUrlPagesFmt = array('OtherGroup.OtherName');@]

!!! Previewing the unapproved URL
To see what link is to be approved without editing the page a tool tip can be displayed when the cursor hovers over the [-%blue%(approve links)%%-] link that displays the URL. e.g. [[http://uuu.example.com|Example]].

Add the following setting in your ''local/config.php'':

-> [@
$UnapprovedLinkFmt =
  "\$LinkText<a class='apprlink' href='\$PageUrl?action=approvesites'
   title='\$LinkUrl'>$[(approve links)]</a>";
@]

->Some browsers show only the link and not the tooltip title. In this case, you can use the following code to see the unapproved link at the end of the tooltip :
-> [@$UnapprovedLinkFmt =
  "\$LinkText<a class='apprlink' href='\$PageUrl?action=approvesites&XES_url=\$LinkUrl'
   title='\$LinkUrl'>$[(approve sites)]</a>";
@]

!! About rel='nofollow' [[#nofollow]]
By default, PmWiki creates external links that are not followed by search engines.  
Here are release notes from pmwiki-2.0.beta20 (30-Jan-2005):

->''First, the $UrlLinkFmt variable has been modified so that links to external urls automatically have a rel='nofollow' attribute added to them, to help combat wiki spam as described in [[http://googleblog.blogspot.com/2005/01/preventing-comment-spam.html]]. Site administrators can customize $UrlLinkFmt and $UnapprovedLinkFmt to supply or omit rel='nofollow' as appropriate.''

!! See Also

* [[PmWiki/Blocklist]] - Blocking postings based on content or IP address
* [[PmWiki/Security]] - Securing your PmWIki
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>DaveG</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Variables</pagename>
<data><![CDATA[(:Summary:Variables available for local customisation:)
(:Audience: administrators (basic) :)
 
This page documents the variables available in PmWiki for [[local customizations]].  Much of this documentation is still incomplete but people are working on it now.  Feel free to add placeholders for variables you want to have documented if you don't know what the variable does.

The variables documentation is divided into several pages

!!!PHP Variables

* [[Basic Variables]]    - {BasicVariables$:Summary}
* [[Debug Variables]]    - {DebugVariables$:Summary}
* [[Edit Variables]]     - {EditVariables$:Summary}
* [[I18n Variables]]     - {I18nVariables$:Summary}
* [[Layout Variables]]   - {LayoutVariables$:Summary}
* [[Link Variables]]     - {LinkVariables$:Summary}
* [[Other Variables]]    - {OtherVariables$:Summary}
* [[Pagelist Variables]] - {PagelistVariables$:Summary}
* [[Path Variables]]     - {PathVariables$:Summary}
* [[Security Variables]] - {SecurityVariables$:Summary}
* [[Upload Variables]]   - {UploadVariables$:Summary}

!!! PmWiki Page Variables - set and used only in PmWiki pages

* [[Page Variables]]     - {PageVariables$:Summary}
* [[Page TextVariables]] - {PageTextVariables$:Summary}
* [[Markup Expressions]] - {MarkupExpressions$:Summary}

A complete index of documented variables is given below.

In general, variables with names ending in 'Fmt' (such as $PageLayoutFmt) have their values processed for $-variable substitutions prior to being output.  Thus strings such as [@{$Name}@] and [@{$PageUrl}@] are replaced with the name and URL of the page when the string is printed.

!!See Also

* [[Blocklist(#variables)]] - {Blocklist$:Summary}
* [[Notify(#variables)]]    - {Notify$:Summary}

* %% [[PmWiki/Functions]]   - {Functions$:Summary}

* [[Basic Variables]] %item comment% to provide circular trail
----
[[#index]]
(:varindex:)
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.Version</pagename>
<data><![CDATA[(:Summary: Determining and displaying the current version of PmWiki ({$Version}):)
!! Obtaining the PmWiki version
Use the [@{$Version}@] [[page variable(s)]] to display the current version of PmWiki.

See the [[SiteAdmin.Status]] page for the current version and version number.

For example
(:markup:)
This wiki installation is running PmWiki {$Version}, version number {$VersionNum}.
-<The default group is {$DefaultGroup}.
-<The default name is {$DefaultName}.
-<The site group is {$SiteGroup}
(:markupend:)

See also [[basic variables]].

The script @@version.php@@  contains the declaration of the version number.

!! Obtaining recipe versions
The [[(PmWiki:)Site Analyzer]] can be used to display the current version of 
[[Cookbook(:/)]] recipes.

See also [[Cookbook:RecipeCheck]]

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WebFeeds</pagename>
<data><![CDATA[(:Summary:Web feed notification of changes:)
(:Audience: visitors (intermediate) :)
Web feeds are a convenient mechanism to let visitors be notified of changes to a site.  Instead of repeatedly checking [=RecentChanges=] every day to see what is new, a visitor can use a [[news aggregator -> Wikipedia:Aggregator]] to quickly see what pages of interest have changed on a site.  Web feeds are commonly recognized by terms such as [[(Wikipedia:)RSS]], [[(Wikipedia:)Atom(_%28standard%29)]], and ''[[Wikipedia:web_syndication | web syndication]]''.  They are also the foundation for podcasting.

In its simplest form, web feeds in PmWiki are built on [[WikiTrails]].  Using a feed action such as [@?action=rss@] or [@?action=atom@] on a trail generates a web feed (often called a "channel") where each page on the trail is an item in the feed.  Since the RecentChanges and [[{$SiteGroup}.AllRecentChanges]] pages are effectively trails, one can easily get an RSS feed for a group or site by simply adding [@?action=rss@] to the url for a RecentChanges page.  For example, to get the site feed for pmwiki.org, one would use

->http://pmwiki.org/wiki/Site/AllRecentChanges?action=rss

Authors can also create custom feeds by simply creating a wiki trail of the pages they want included in the feed.  Feeds can also be generated from [[groups -> WikiGroup]], [[categories]], and %newwin%[[Cookbook:Backlinks|backlinks]], and the order and number of items in the feed can be changed using options in the feed url.  Thus, one can obtain a feed for the ''Skins'' category (sorted with most recent items first) by using

->http://pmwiki.org/wiki/Category/Skins?action=rss&order=-time

PmWiki is able to generate feeds in many formats, including RSS 2.0 ([@?action=rss@]), Atom 1.0 ([@?action=atom@]), and RSS 1.0 ([@?action=rdf@]).  In addition, although it is not normally considered a web feed, PmWiki can generate metadata information using the Dublin Core Metadata extensions ([@?action=dc@]).

!!How to read a PmWiki syndicated feed

# You'll need a [[news aggregator -> Wikipedia:List_of_feed_aggregators]], which is a piece of software designed to read news feeds.  Many different news aggregators are available.  Some run on your own computer, either on their own or as plugins for email clients, web browsers, or newsreaders.  Others are web applications that you can use from any Internet-connected computer.  Some are in between (technically web applications, but ones designed to run on your computer, not some remote server).  Get one that you like.
# Subscribe to the [[WikiTrail(s)]] you desire by supplying the feed url to the aggregator.  The feed url will be the name of a trail page with [@?action=rss@] or [@?action=atom@] added to the end of the url.

!!Feed options

Add any of the following options to the end of a PmWiki web feed url to change its output (basically any [[pagelist->PageLists]] option is available for web feeds):

:?count=''n'': Limit feed to ''n'' items
:?order=-time : Display most recently changed items first
:?trail=''page'': Obtain items from trail on ''page''
:?group=''group'': Limit feed to pages in ''group''
:?name=''name'': Limit feed to pages with specific ''name''
:?link=''page'': Create feed from pages linked to ''page''
:?list=normal: Exclude things like RecentChanges, AllRecentChanges, etc.

%audience% authors (intermediate)
!!Configure PmWiki for feeds

This section describes how to syndicate portions of a wiki to appear in a web feed.  It does not describe how to display a web feed within a wiki page -- for that, see Cookbook:RssFeedDisplay.

To enable web feed generation for a site, add one or more of the following to a [[local customization(s)]] file:

->[@
if ($action == 'rss') include_once("$FarmD/scripts/feeds.php");
if ($action == 'atom') include_once("$FarmD/scripts/feeds.php");
if ($action == 'rdf') include_once("$FarmD/scripts/feeds.php");
if ($action == 'dc') include_once("$FarmD/scripts/feeds.php");
@]

or you can combine multiple feeds into a single expression using "||" to separate each feed type.  For example, if you want to enable RSS and Atom feeds you would use

->[@
if ($action == 'rss'  ||
    $action == 'atom' ||
    $action == 'rdf'  ||
    $action == 'dc') include_once("$FarmD/scripts/feeds.php");
@]

!!Configure feed content
Web feeds are highly configurable, new elements can be easily added to feeds via the $FeedFmt array. Elements in $FeedFmt look like

[@$FeedFmt['atom']['feed']['rights'] = 'All Rights Reserved';@]

where the first index corresponds to the action (?action=atom), the second index indicates a per-feed or per-item element, and
the third index is the name of the element being generated. The above setting would therefore generate a "<rights>All Rights Reserved</rights>" in the feed for ?action=atom.

[[#pitfall1]]
If the value of an entry begins with a '<', then feeds.php doesn't automatically add the tag around it. Elements can also be callable functions which are called to generate the appropriate output. See [[http://blogs.law.harvard.edu/tech/rss | RSS specification]] or other feed specifications for what feed content you can use.

You can also change an existing element rather than add a new one.  You can use the following lines to ensure that changes made to the wiki will be picked up by  some RSS readers that wouldn't otherwise "notice" a page has been changed:

->[@
# Change the link URL when an item is edited.
$FeedFmt['rss']['item']['link'] = '{$PageUrl}?when=$ItemISOTime';
$FeedFmt['atom']['item']['link'] =
   "<link rel=\"alternate\" href=\"{\$PageUrl}?when=\$ItemISOTime\" />\n";
@]

!!See Also

* [[Cookbook:FeedLinks]] - Add HTML <head> links for auto-discovery of your feeds.
* [[WikiTrails]]
* Wikipedia:Web_feed, Wikipedia:Web_syndication, Wikipedia:RSS_%28file_format%29, Wikipedia:Atom_%28standard%29

>>faq<< [[#faq]]

Q: How do I include text from the page (whole page, or first X characters) in the feed body?  (note: markup NOT digested)

    function MarkupExcerpt($pagename) {
      $page = RetrieveAuthPage($pagename, 'read', false);
      return substr(@$page['text'], 0, 200);
    }

    $FmtPV['$MarkupExcerpt'] = 'MarkupExcerpt($pn)';
    $FeedFmt['rss']['item']['description'] = '$MarkupExcerpt';

%green% Q:Does this mean if I want to include the time in the rss title and "summary" to rss body I call [@$FeedFmt@] twice like so:
->[@$FeedFmt['rss']['item']['description'] = '$LastSummary'; 
$FeedFmt['rss']['item']['title'] = '{$Group} / {$Title} @ $ItemISOTime';@] %%

---> From mailing list Feb 13,2007, a response by Pm: Yes

Q: How can I use the RSS <enclosure> tag for podcasting?

A: For podcasting of mp3 files, simply attach an mp3 file to the page
with the same name as the page (i.e., for a page named Podcast.Episode4,
one would attach to that page a file named "Episode4.mp3").  The
file is automatically picked up by ?action=rss and used as an
enclosure.

The set of potential enclosures is given by the $RSSEnclosureFmt
array, thus

->[@$RSSEnclosureFmt = array('{$Name}.mp3', '{$Name}.wma', '{$Name}.ogg');@]

allows podcasting in mp3, wma, and ogg formats.

Q: [[#AddSummary]] How to add "summary" to the title in a rss feed (ie. with [@?action=rss@])?

A: Add this line in you [@local/config.php@]

->[@$FeedFmt['rss']['item']['title'] = '{$Group} / {$Title} : $LastModifiedSummary';@]

Q: [[#AddDescriptionSummary]] How to add "description" to the title in an rss feed, and summary to the body?

A: Add these lines to your [@local/config.php@]

->[@$FeedFmt['rss']['item']['title'] = '{$Group} / {$Title} : {$Description}';@]
->[@$FeedFmt['rss']['item']['description'] = '$LastModifiedSummary';@]

'''NOTES:'''
* you need to replicate these lines for each type (atom, rdf, dc) of feed you provide.
* the RSS '''[@description@]'''-tag is not equivalent to the pmWiki ''[@$Description@]'' variable, despite the confusing similarity.

Q: Some of my password-protected pages aren't appearing in the feed... how do I work around this?

A: From a similar question on the newsgroup, Pm's reply:

The last time I checked, RSS and other syndication protocols didn't
really have a well-established interface or mechanism for performing
access control (i.e., authentication).  As far as I know this is
still the case.

PmWiki's WebFeeds capability is built on top of pagelists, so it
could simply be that the $EnablePageListProtect option is preventing
the updated pages from appearing in the feed.  You might try
setting $EnablePageListProtect=0; and see if the password-protected
pages start appearing in the RSS feed.

The "downside" to setting $EnablePageListProtect to zero is that
anyone doing a search on your site will see the existence of the
pages in the locked section.  They won't be able to read any of
them, but they'll know they are there!

You could also set $EnablePageListProtect to zero only if ?action=rss:

    if ($action == 'rss') $EnablePageListProtect = 0;

This limits the ability to see the protected pages to RSS feeds;
normal pagelists and searches wouldn't see them.

Lastly, it's also possible to configure the webfeeds to obtain
the authentication information from the url directly, as in:

    .../Site/AllRecentChanges?action=rss&authpw=secret

The big downside to this is that the cleartext password will
end up traveling across the net with every RSS request, and
may end up being recorded in Apache's access logs.

Q: How to add feed image?

A: Add the following to ''local/config.php'' (this example is for [@?action=rss@]):

->[@
$FeedFmt['rss']['feed']['image'] =
" <title>Logo title</title>
 <link>http://example.com/</link>
 <url>http://example.com/images/logo.gif</url>
 <width>120</width>
 <height>60</height>";
@]

-> %red%Do not forget NOT to start with a '<' as there would be no <image> tag around this...   See [[#pitfall1|here]].

Q: How do I insert RSS news feeds into PmWiki pages?

A: See [[Cookbook:RssFeedDisplay]].

Q: How can I specify default feed options in a configuration file instead of always placing them in the url?
A: For example, if you want [@?action=rss@] to default to [@?action=rss&group=News&order=-time&count=10@], try the following in a [[local customization(s)]] file:

->[@
   if ($action == 'rss')
     SDVA($_REQUEST, array(
       'group' => 'News',
       'order' => '-time',
       'count' => 10));
@]

Q: Are there ways to let people easily subscribe to a feed?

A: On some browsers (Mozilla Firefox), the visitor can see an orange RSS icon in the address bar, and subscribe to the feed by clicking on it. To enable the RSS icon, add this to config.php :[@
$HTMLHeaderFmt['feedlinks'] = '<link rel="alternate" type="application/rss+xml" 
  title="$WikiTitle" href="$ScriptUrl?n=Site.AllRecentChanges&amp;action=rss" />
<link rel="alternate" type="application/atom+xml" title="$WikiTitle"
  href="$ScriptUrl?n=Site.AllRecentChanges&amp;action=atom" />';@]

You can also add such a link, for example in your SideBar, @@[=[[Site.AllRecentChanges?action=atom | Subscribe to feed]]=]@@. 

Q: Can I create an RSS feed for individual page histories?
A: See Cookbook:PageFeed.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiAdministrator</pagename>
<data><![CDATA[A Wiki Administrator is a person (or persons) who installs, configures, and administers a PmWiki system for authors and site visitors.  PmWiki has been designed to make the [[installation]] and [[initial setup tasks]] as easy as possible for people who do not have a lot of knowledge about HTML, PHP, or even web server software.  At the same time, PmWiki is designed to be flexible enough so that someone with just a little bit of knowledge about HTML and PHP can customize PmWiki to their specific needs. 

See the [[PmWiki.documentation index]] for pages about administering PmWiki, [[PmWiki:AdminTask|administration tasks]], 
[[PmWiki/security]],
and [[PmWiki.audiences]] for more details of PmWiki's target audiences.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiFarmTerminology</pagename>
<data><![CDATA[%audience% administrators (intermediate)
There are many ways to configure [[PmWiki:WikiFarms]], and some of the documentation uses different terminology to describe the same things. This page attempts to explain the terminology.

For terms not related to farms, see [[Glossary]].

!!Why is this page needed?
* to provide a place to find the preferred terminology with definitions
* to explain where the term "farm" came from
* to list various terms that have been deprecated but still exist in the docs
* to suggest alternate terms for the deprecated ones

!!The origins of WikiFarms
The term WikiFarm is based on the computing term "server farm", which is a collection of servers that use a common infrastructure.  A wiki farm is nothing more than multiple wikis that share the same installation of the PmWiki software.

Some recipe and documentation authors, however,  began writing about WikiFarms using agricultural terms such as "field", "farmer", "barn", "crop", and "tractor".  In some cases these terms made the documentation more confusing.  It is suggested that documentation authors avoid the  agricultural terms, as tempting as they may be, and keep in mind that a wiki in a wiki farm is like a server in a server farm.

!!Wikis and components in a WikiFarm
All of the wikis in a farm are more or less the same, except the "home wiki" is a wiki that is located in the same directory as the PmWiki software.  The home wiki needs special consideration because it holds the components that are shared by or affect the operation of all the wikis in the farm. In particular:
*the ''scripts/'' directory
*the ''cookbook/'' directory
*the ''pub/'' directory
*the ''wikilib.d/'' directory

It is possible to move the PmWiki software outside of the web document tree, but the ''pub/'' directory needs to be in a web-servable directory (one that can be accessed by a URL).

Authors writing about complex farm setups often have difficulty describing the components and their locations. However, it is probably not necessary or desirable to coin new terms for the components and their locations.

!! [[#suggested_terms]] Suggested terms

:WikiFarm: An installation where one copy of PmWiki is configured to run multiple wikis.  Analogous to the computing phrase "server farm".  The wikis in a farm can be configured farm-wide (using the farm's ''local/farmconfig.php'') or individually (using the wiki's ''local/config.php'').
:Wiki: A site with it's own URL and ''wiki.d/'' directory. All of the wikis in a wiki farm are simply called wikis.
:Home wiki:A wiki in a farm that's located in the same directory as the PmWiki software and therefore shares the farm's ''cookbook/'' and ''pub/'' directories. If you start with a stand-alone installation and add a wiki, the original wiki becomes a home wiki.
:Farm-wide: Something available to or affecting all wikis in the farm.  Typically this means modifying the ''farmconfig.php'' file or the contents of the farm's cookbook/ or pub/ directories.
:Local: Something available to or affecting a specific wiki.  Typically this means modifying the wiki's ''local/config.php'' file or the contents of the wiki's ''cookbook/'' or ''pub/'' directories.

:PmWiki {-engine-} : The software that makes PmWiki work, as opposed to the content of the wiki that readers see.
:PmWiki {-installation-} directory: The directory PmWiki is installed to. It contains pmwiki.php and its subdirectory scripts/, which is used by all the wikis in the WikiFarm. {-If you do a standard, single install of PmWiki, it goes into this directory.-}

!!Ambiguous terms

:Installation directory: Installation of what? Some authors have used this to mean the directory that contains most of the shared components on a wiki farm. Others use it to mean a directory that has a complete standalone installation of PmWiki that is not part of a farm. Use PmWiki directory instead.
:PmWiki installation: This is sometimes used to indicate a process, sometimes used to mean a single wiki in a farm, and sometimes refers only to the shared components of a farm.

!!Deprecated terms that should not be used

These terms still exist in the documentation (pending revisions), and will live forever in the PmWiki-Users list archive.

:farm directory: The directory in which the home wiki lives or a directory where the shared components are stored. Use PmWiki directory instead.
:field: Any wiki in a farm which is '''not''' the home wiki.
:farm administrator: An administrator who has access to all of the wikis in a farm, particularly the home wiki. Use administrator instead.
:field administrator: An administrator who has access to one or more wikis in a farm, but '''not''' the home wiki. Use administrator instead.
:barn: The place where common components are stored. Use PmWiki directory instead.
:crop: Packaged content and customizations that can be added to a wiki. See [[Cookbook:ListOfBundles]] for similar ideas. Use component bundles instead.
:tractor: The PmWiki engine or ''pmwiki.php'' itself. Use PmWiki instead.

----
Categories: [[!WikiFarms]]
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Susan</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiFarms</pagename>
<data><![CDATA[(:Audience: administrators (intermediate) :)
(:Summary:Running multiple wikis from a single installation:)
Also see: [[Cookbook:Farm Setup By Example]], [[Cookbook:Wiki Farm Alternative]]

A [[WikiFarm(s)]] is a collection of two or more wikis running on the same web server and sharing a set of common components. The term is based on the computing phrase "server farm".

This page provides some background information about WikiFarms and describes how to turn a "normal" configuration into a farm by adding a wiki.  There are many ways to configure wiki farms; this page describes only one, in an effort to make it as simple as possible for the administrator who is creating a farm for the first time.

!! Why use a farm?
The primary motivation for using a wiki farm is to reduce the amount of administrative work involved in managing several wikis. In a farm, most of the PmWiki code is stored in one place and is shared by all the wikis. An administrator can (for example) upgrade to a new version of PmWiki on every wiki in the farm by simply updating the shared components in a single location.

From a reader's point of view, each wiki in a farm is completely independent, and appears as a separate web site. Each wiki in a farm:
* has its own URL, and the URLs can be in different domains
* can have its own look and feel by using different skins
* can have its own add-ons or "recipes" from the [[(Cookbook:)Cookbook(Basics)]]
* can have its own administrator responsible for local configuration

!! Why not to use a farm
Because the wikis in a farm are all independent, it is difficult (but not impossible) to provide services that require access to more than one wiki. For example, the PmWiki search function can only search within one wiki. Using a farm as a way of subdividing related content is generally a bad idea. A much better way to subdivide content is to use [[(PmWiki:)WikiGroup | WikiGroups]].

!! I still can't decide if I need a farm ...
The good news is that you don't have to decide in advance. In fact, the recommended procedure is to first do a "normal" or single [[installation]] of PmWiki. Use it for a while. Create pages and edit them. Get to know how to add recipes. Be sure to try out [[WikiGroup | WikiGroups]] (they may be all you need).

Once you have decided that you need another wiki, you have two basic choices:
# Do a complete [[installation]] of PmWiki in a new directory. This gives you two totally independent wikis that are completely self-contained. This is '''not''' a wiki farm.
# Create a wiki farm using your existing wiki as the "home wiki" where most of the shared PmWiki components will live.

Choice number 1 can be a good choice for several reasons:
* it is not a wiki farm, and requires no additional administrative knowledge - it's just two installations
* if you decide to move one of the wikis to another server, you can simply copy the wiki directory structure to the second server, and it will work (assuming there is a web server and PHP in place).
* you can run different versions of PmWiki on each wiki (good for testing new versions)
* no matter how badly you mess up one installation, it doesn't affect the other

If you choose to create a wiki farm, then read on ...

!! Prerequisites
Before you create a farm, make sure that:
* you have a working installation of PmWiki ready to become the home wiki for your farm
* all of the wikis in your farm will be on the same web server
* each wiki will have a unique URL, such as http://www.example.com/wiki1/, http://www.example.com/wiki2/, http://another.example.com/wiki1/ and so on.

!! Creating the home wiki
You do have a working installation of PmWiki at this point, don't you? That's good, because your existing wiki is about to become the home wiki of your farm.

In the directory that contains your existing wiki, create the file ''local/farmconfig.php''. This file is used to hold any [[local customizations]] that apply across the whole farm. For example, you could assign an admin password in ''farmconfig.php'' that will be used by all of the wikis in your farm.

If the URL used to access your existing wiki is http://www.example.com/pmwiki/ then a minimal ''farmconfig.php'' file would look like this:

-> [@<?php if (!defined('PmWiki')) exit();
$FarmPubDirUrl = 'http://www.example.com/pmwiki/pub';@]

This loads the variable $FarmPubDirUrl with the URL location of your home wiki's ''pub/'' directory. All of the wikis in your farm share this ''pub/'' directory. The ''pub/'' directory holds skin definitions and GUI-edit buttons to be shared by all the wikis in the farm.

Amazing as it may sound, this completes all of the changes you need to make in order to turn your existing wiki into the home wiki of your farm.

!! Creating an additional wiki in your farm
-< 1. Create a directory to hold the new wiki. This directory must be web-accessible, just like the directory that holds your home wiki.

-< 2. Create a file called ''index.php'' in the directory with the following contents:

--> [@    <?php include('path/to/pmwiki.php'); @]

-> This allows your new wiki to share the PmWiki code stored in your home wiki. The ''[@path/to/pmwiki.php@]'' is the file path to ''pmwiki.php'' in your home wiki. Use an absolute file path ([@/home/username/pmwiki/pmwiki.php@]) or a relative file path ([@../pmwiki/pmwiki.php@]). Do not use a url path - there should not be an '[@http://@]' in it anywhere. For a web server running under Windows, you need to use a complete file path as in [@C:/Apache Group/Apache2 /www/mynewwiki/@].

-< 3. Open a web browser and browse the URL of the new wiki.  This will be a web address starting with '[@http://@]'.  PmWiki will attempt to automatically create a writable ''wiki.d/'' directory where the wiki's pages will be stored.  If you see an error message, follow the instructions.  If you choose the option for a "slightly more secure installation" be sure to execute both commands.

Your new wiki is now set up, and your farm now contains 2 wikis. To add more wikis, just repeat these 3 steps.

!! Customization
Each wiki in a farm inherits the settings stored in ''farmconfig.php''. Do any customization that you want to apply farm-wide (to all the wikis) in ''farmconfig.php''.

Create a ''local/'' directory within each wiki's directory to hold [[local customizations]] that apply only to that wiki. You should at least create the local/config.php file with a new title, like so : 

->[@
<?php if (!defined('PmWiki')) exit();
  ## Title of your farmed wiki
  $WikiTitle = 'New Wiki';
?>
@]

Farm-wide customizations are processed before the individual wiki local customizations.

The PmWiki variable ''$FarmD'' points to the directory in which pmwiki.php is installed, and your home wiki, and it is used as a prefix to allow the other wikis to share PmWiki components. For example:
* ''$FarmD/scripts/'' points to the shared ''scripts/'' directory
* ''$FarmD/pub/'' points to the shared ''pub/'' directory
* ''$FarmD/cookbook/'' points to the shared ''cookbook/'' directory

Any [[Cookbook(:.)]] scripts you include in farmconfig.php must be included with a line such as:
-> @@include_once("$FarmD/cookbook/scriptfile.php");@@\\
Note the double quotes - single quotes may work for per farm inclusions, but they will not work for $FarmD.

!! Notes
* The terminology used to describe wiki farms is not used consistently. See [[WikiFarmTerminology]] for more info.
* It is important to remember that not all of the recipes in the Cookbook have been written for or tested with farms. Be sure to look for instructions on how to use a recipe on a farm.
* There are many, many more things you can do with farms. Some are described on [[PmWiki:WikiFarmsAdvanced]] which also contains links to step-by-step examples of setting up a farm.

!! Password use/authorization on farm wikis:

''' How come when I switch to another wiki within a farm, I keep my same authorization?'''

PmWiki uses PHP sessions to keep track of authentication/authorization information, and by default PHP sets things up such that all interactions with the same server are considered part of the same session.

An easy way to fix this is to make sure each wiki is using a different cookie name for its session identifier.  Near the top of one of the wiki's local/config.php files, before calling authuser or any other recipes, add a line like:

-> @@    session_name('XYZSESSID'); @@

You can pick any alphanumeric name for XYZSESSID; for example, for the cs559-1 wiki you might choose

-> @@    session_name('CS559SESSID'); @@

This will keep the two wikis' sessions independent of each other.

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiGroup</pagename>
<data><![CDATA[(:Audience: authors (basic) :)
(:Summary: Organising pages into related groups:)
(:keywords trailing dot, trailing slash, default group:)
PmWiki pages are organized into groups of related pages.  This feature was added to PmWiki to allow authors to create their own ''wiki spaces'' of specialized content on their own, without having to become, or rely on, wiki administrators.  See [[http://pmichaud.com/|Pm]]'s [[http://pmichaud.com/pipermail/pmwiki-users/2006-March/024838.html|post]] to the pmwiki-users [[mailing list(s)]].

By default, page [[links]] are between pages of the same group; to create a link to a page in another group, add the name of the other group and a dot or slash to the page name.  For example, links to [=Main/WikiSandbox=] could be written as:

(:markup class=horiz:)
* [[Main.WikiSandbox]]
* [[Main/WikiSandbox]]
* [[(Main.Wiki)Sandbox]]
* [[Main.WikiSandbox | link text]]
* [[Main.WikiSandbox | +]]
(:markupend:)

To link to the [[#groupdefaultpage | default home page]] of a group, the name of the page can be omitted, like this:

(:markup class=horiz:)
* [[Main.]]
* [[Main/]]
(:markupend:)

!! Creating groups
Creating a new group is as easy as [[creating new pages]]; simply edit an existing page to include a [[link(s)]] to the new group's default home page  (or any page in the new group) then click on the '?' to edit the page. As a rule, group names must start with a letter (but this can be changed by the wiki administrator by adding 
-> @@[@$GroupPattern = '[[:upper:]\\d][\\w]*(?:-\\w+)*';@]@@
in config.php).

For example, to make a default page in the group Foo, create a link to [=[[Foo/]]=] (or [=[[Foo.]]=]).  
To make a page called Bar in the group Foo, create a link to [=[[Foo/Bar]]=] and follow the link to edit that page.

!! Groups in a standard PmWiki distribution
* [[Main]]: The default group. On many wikis, it contains most of the author-contributed content. Main.HomePage and Main.WikiSandbox come pre-installed.
* [[PmWiki]]: An edit-protected group that contains PmWiki documentation and help pages.
* [[Site]]: Holds a variety of utility and configuration pages used by PmWiki, including [[<<]][=SideBar=], Search, Preferences, Templates, and [=AllRecentChanges=].
* [[SiteAdmin/]]: Holds a number of password protected administration and configuration pages used by PmWiki, including [[<<]] [=ApprovedUrls=], and Blocklist

* To list all the groups in a site, try [[PmWiki/Search | searching]] for "[[{$FullName}?action=search&q=fmt%3Dgroup|fmt=group]]".
* To list all the pages in a group, try [[PmWiki/Search | searching]] for "[[{$FullName}?action=search&q={$Group}%2F|GroupName/]]".

[[#specialpages]]
!! [[(PmWiki:)Special Pages]] in a Group
By default, the ''[[Recent Changes]]'' page of each group shows only the pages that have changed within that group; the ''[[Site.All Recent Changes]]'' page shows all pages that have changed in all groups.

Each group can also have ''[[Group Header(s)]]'' or ''Group Footer'' pages that contain text to be automatically prepended or appended to every page in the group.  A group can also have a ''Group Attributes ''page that defines attributes (read and edit passwords) shared by all pages within the group.  

Each page can also have its own individual read/edit password that overrides the group passwords (see [[Passwords]]).

Finally, [[wiki administrator]]s can set [[local customizations]] on a per-group basis--see [[Per Group Customizations]].

[[#groupdefaultpage]]
!! Group's default page

The default "start page" for a group is a page whose name is: 
# the same as the group (Foo/Foo)
# HomePage (Foo/HomePage)
# a name that the administrator has assigned to the [={$DefaultName}=] variable in the configuration.php file.  

Note, on this site, the value of [={$DefaultName}=] is ''{$DefaultName}'' and, thus, the default home page would be Foo/{$DefaultName}.   

You can usefully change the default ''search'' order for an entered page name by setting the variable @@$PagePathFmt @@ in @@config.php@@, eg
-> @@ $PagePathFmt = array('$Group.$1', '$1.$DefaultName', '$1.$1', '$DefaultGroup.$1', 'Profiles.$1'); @@
where "$1" is the name of the page entered. 

As noted above, when linking to the default home page, authors can omit the page name and simply identify the group followed by a  forward slash ([=[[Foo/]]=]).

Note the forward slash is required to ensure that the link unambiguously points to the identified group.  
If the slash is omitted, the link can end up being interpreted as pointing to an existing (or new) page in the current group (if the group, or its default home page, do not exist).  

!! Subgroups? Subpages?
No, PmWiki does not have subpages.  Pm's reasons for not having subgroups are described at [[PmWiki:Hierarchical Groups]], but it comes down to not having a good page linking syntax.  If you create a link or pagename like [@[[A.B.C]]@] PmWiki doesn't think of "B.C" as being in group "A", it instead thinks of "C" as being in group "AB", which is a separate group from "A".  Wiki administrators can look at [[Cookbook:Subgroup Markup]] and [[Cookbook:Include With Edit]] for recipes that may be of some help with developing subgroups or subpages.

!! Restricting the creation of new groups
You can set PmWiki's $GroupPattern variable to only accept the group names you want to define. For example, to limit pages to the "PmWiki", "Main", "Profiles", and "Example" groups, add the following to local/config.php:

-> $GroupPattern = '(?:Site|SiteAdmin|PmWiki|Main|Profiles|Example)';

With this setting, only the listed groups will be considered valid WikiGroups. You can add more groups to the list by placing additional group names separated by pipes (|).

See other solutions to this at [[Cookbook:Limit Wiki Groups]] and [[Cookbook:New Group Warning]].

>>faq<< [[#faq]]
Q: How can I get rid of the 'Main' group in urls for pages pointing to Main?

A: See [[Cookbook:Get Rid Of Main]].

Q: How can I limit the creation of new groups?

A: See [[Cookbook:Limit Wiki Groups]].

Q: Why doesn't [=[[St. Giles and St. James]]=] work as a link?  (It doesn't display anything.)

A: Because it contains periods, and destroys PmWiki's file structure, which saves pages as [=Group.PageName=]. Adding those periods disrupts this format. Links may only contain words. If you need a link precisely as shown, the page must be named eg StGilesAndStJames then you can use the [=(:title:)=] directive to have the page's title appear with periods [=(:title St. Giles and St. James:)=]. (Although modern US and UK grammar now tend to drop the period to simplify style).

Q: How can I delete a wiki group?

A: Normally you can't, as this requires an admin with server-side access to delete the file that makes up the group's RecentChanges page.  But there is an option method of making it possible to delete RecentChanges pages from within the wiki if the admin enables the code found on [[Cookbook:RecentChanges Deletion]].

Q: How can I delete a wiki group's Group.RecentChanges page?

A: Normally you can't, as this requires an admin with server-side access to delete a file.  But there is an optional method of making it possible to delete RecentChanges pages from within the wiki if the admin enables the code found on [[Cookbook:RecentChanges Deletion]].
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiGroups</pagename>
<data><![CDATA[(:Summary: Redirects to [[PmWiki/Wiki Group]]:)
(:redirect PmWiki/WikiGroup:)]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiPage</pagename>
<data><![CDATA[(:Summary: Wiki page information:)
A WikiPage is simply the basic building block of a WikiWikiWeb that contains text and images. See [[WikiStructure]]s and [[WikiWikiWeb]] for more information.

Wiki pages can have an edit template to predefine initial content, see [[Cookbook:Edit Templates]] [-{Cookbook/EditTemplates$:Summary}-]

Wiki pages are stored in individual flat files, see [[PmWiki/Page File Format]] and [[(PmWiki:)Flat File Advantages]].

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiStructure</pagename>
<data><![CDATA[(:Summary: PmWiki structural support for page organization:)
Authors have a range of options to choose from when organizing a collection of [[wiki page]]s. 
Used in combination, these give a lot of flexibility.
An effective wiki will use all of these to optimize
* content
* navigation
These are the two most important aspects of a website.

:[[Wiki Word]]: The most powerful organizing principle is the author's choice of page names. When a search returns a list of pages, their names need to be clear enough to guide a visitor to the right place.
: : Providing a network of [[PmWiki/links]] to other points in the wiki, with or without wiki words, is the primary means of navigating a wiki.

:[[Wiki Page]]: A page with text (and images), where the text can contain for instance [[WikiWord]]s that automatically becomes a link to another WikiPage.

:[[Wiki Group]]: PmWiki requires every page to be a member of a group. A group is like a wiki within a wiki; it can have its own presentation look, security controls and navigation aids. With default configuration, [[WikiWord]]s are only searched inside the current group, and you use either [@OtherGroup/MyWikiWord@] or [@OtherGroup.MyWikiWord@] to refer to pages in other groups (see [[Links]]).

:[[Wiki Trails]]: A collection of pages, either in the same group or across multiple groups, can be designated as a trail. A visitor can move from stop to stop by clicking on ''next'' and ''previous'' links.

:[[Categories]]: Individual wiki pages can also be grouped by having tags and links to a common "category" page; we say that any pages that link to a common page are in a "category" defined by that page.  PmWiki uses the [@[[!category]]@] markup as a shorthand to place a page into a category with other pages containing the same markup.
: : The shortcoming of categories is that categories do not distinguish between the declaration of a category ([=[[!structure]]=]) and the link to a category ([=[[Category/Structure]]=]).

:[[Page text variables]]: A newer and more powerful concept than [[Categories]], pages can use one of more [[page text variables]] to store page attributes. These can the be used in [[page lists]].

:[[Page lists]]: Page lists provide a powerful means of presenting lists of relevant pages, or selection of data from within a page. Lists are [[Site/PageListTemplates|template]] based and are highly customizable.

:[[Include other pages]]: The capability to include parts of other pages also provides a flexible means of sharing content between pages.

:[[Search]]: Being able to search is a fundamental requirement of a website. In PmWiki search, like pagelists is both powerful and  highly customizable.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiStyleExamples</pagename>
<data><![CDATA[(:Summary: Styling text for colour and other attributes:)
See also [[Cookbook:WikiStylesPlus | Wiki Styles Plus]] and [[(PmWiki:)Wiki style colors]].

PmWiki uses [[WikiStyles]] for styling text with color and other attributes.  PmWiki 2.0 introduced the ability to control the styling further and to even place styles on blocks.

A  style is specified within a pair of %-signs and styles the text that follows, as in:

(:markup class=horiz:)
This text is %color=red% red, %color=blue% blue, %% and normal (black).
(:markupend:)

There are a wide number of available style properties, borrowed primarily from HTML and CSS.  In addition, an author can define a style "shortcut" by using the [@define=@] property.  For example, to define a style of [@%red%@], one can use:

(:markup class=horiz:)
%define=mystyle color=red%
Here is some %mystyle% red text created using a style shortcut.
(:markupend:)

Shortcuts can be combined with other styles, including other shortcuts:

(:markup class=horiz:)
%define=lovelyred color=red%
%define=likegrapefruit bgcolor=yellow%

%red% This text is red, %red bgcolor=#ccc% red on a grey background, and %lovelyred likegrapefruit% red on a yellow background.  
(:markupend:)

So far, this is all basically the same as what was available in PmWiki 1.0.  PmWiki 2.0 includes the capability to style blocks, by using the [@apply=@] style property.  Specifying [@apply=block@] in a `WikiStyle will cause that style to be applied to the entire block, instead of just the text that follows:

(:markup:)
This entire block %apply=block bgcolor=yellow% has a yellow background, even though the `WikiStyle appears in the middle of the line.  %bgcolor=pink% Other inline (non-block) WikiStyles can appear in the middle of the line,%% as before.
(:markupend:)

This means it's now possible to do right-aligned and centered text:

(:markup:)
%block text-align=right% The text of this paragraph is right-aligned. 

%block text-align=center% The text of this paragraph is centered.  
(:markupend:)

In fact, PmWiki predefines [@%right%@] and [@%center%@] style shortcuts so that you can do this more simply:

(:markup class=horiz:)
%right% This is right-aligned.

%center% This is centered.
(:markupend:)

Authors can define their own custom styles:

(:markup:)
%define=Pm block bgcolor=#fdf%
%define=goofy center bgcolor=#dfd border='3px dotted green'%
%define=rediguana right bgcolor=#ffffcc border='1px dotted red' padding=5px%
%define=strike text-decoration=line-through%

%Pm% Any text that is on a light purple background is a comment from "Pm".

%goofy% Here's some text from Goofy.

%rediguana% bla bla by rediguana!

%goofy%Hello, I am %strike%upset%% %strike%disheartened%% happy to meet you.
(:markupend:)

Styles can be applied to almost any kind of block:

(:markup class=horiz:)
* %block bgcolor=yellow% Here is a list item
* Here's another list item

* Here's more of a list

# A new list
(:markupend:)

In particular, this means that outlines are now possible using the predefined [@%ROMAN%@], [@%roman%@], [@%ALPHA%@], and [@%alpha%@] list-block styles.  The style has to be specified on the first item in the list (and we may develop an alternate syntax for this sort of ordered list):

(:markup class=horiz:)
# %ROMAN% Top level
## %ALPHA% second-level
## second-level
## second-level
### third-level
### third-level
## second-level
### third-level
#### %alpha% fourth-level
##### %roman% fifth-level
##### fifth-level
#### fourth-level
# top-level
# top-level
(:markupend:)

[[Wiki styles]] can be combined with CSS stylesheets to do this automatically -- see [[Cookbook:OutlineLists]].

!! Q & A

!!! How do I get a block of preformatted text?

Use something similar to this (assuming you want markup within the block to be interpreted as wiki markup and URIs to be recognized).

(:markup:)
>>white-space=pre<<
This block of text is ''preformatted'', see all   the   white-space
and   linebreaks
are preserved. Links such as [[wiki styles]] etc still work.
>><<
(:markupend:)

!!! How do I get a block of preformatted text with a colored background and a border?

Use something similar to this (note that wiki markup etc is not recognized within the block):

(:markup:)
%block bgcolor=#f0f9ff border='1px solid gray' padding=5px%[@
ip access-list extended example-acl
remark ** This is an example acl **
deny ip any host 10.0.0.1
permit ip any any
@]
(:markupend:)

!!! How do I get a block of text (including wiki markup) with a colored background and a border?
(:markup class=horiz:)
>>teal background-color:silver border:'medium dotted green'<<
Hello world
* bullet
# number
>><<
(:markupend:)

!!! How do I get a block of text (including wiki markup) with a border that is indented on the left and does NOT extend all the way to right?  I'm not interested in having later text to the right as would occur with lfloat...

You can use the @@indent lframe@@ class and follow the block by a forced line break [=[[<<]]=].

(:markup class=horiz:)
Before indention...
>>indent lframe<<
Hello world
* bullet
# number
>><<
[[<<]]
... after indention!
(:markupend:)]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiStyles</pagename>
<data><![CDATA[(:Summary: Modifying the style of page contents:)
(:div class='rfloat frame' style='clear:right; font-size:small;':)
'''Contents'''
*[[#Basics|Basics]]
*[[#Scopes|Scopes]]
*[[#Attributes|Attributes]]
*[[#Styles|Enabling Styles]]
*[[#Shortcuts|Custom style shortcuts]]
*[[#predefined|Predefined Style Shortcuts]]
*[[#Examples|Examples]]
*[[#KnownIssues|Known Issues]]
*[[#SeeAlso|See Also]]
(:divend:)
(:Audience: authors (basic) :)

[[#Basics]]
!! Wiki style basics

[[Wiki styles]] allow authors to modify the color and other styling attributes of a page's contents.  
A wikistyle is written using percent-signs, as in %red%[@%red%@]%% or %bgcolor=lightblue%[@%bgcolor=lightblue%@]%%.

!!! Text color and font
The most basic use of wiki styles is to change text attributes such as color, background color, and font.  
PmWiki defines several wikistyles for changing the text color to [=%black%, %white%, %red%, %yellow%, %blue%, %gray%, %silver%, %maroon%, %green%, %navy%, and %purple%=].

(:markup class=horiz:)
The basket contains %red% apples, %blue% blueberries, %purple% eggplant, %green% limes, %% and more.
(:markupend:)

For colors other than the predefined colors, use the [@%color=...%@] wikistyle.  (Note: RGB colors (#rrggbb) should always be specified with lowercase letters to avoid [[WikiWord]] conflicts.)

(:markup class=horiz:)
I'd like to have some %color=#ff7f00% tangerines%%,  too!
(:markupend:)

To change the background color, use [@%bgcolor=...%@] as a wikistyle:

(:markup class=horiz:)
This sentence contains %bgcolor=green yellow% yellow text on a green background.
(:markupend:)

See [[(PmWiki:)Wiki Style Colors]] for more color help.

!!!Text justification
Styles are used to control the text justification

(:markup class=horiz:)
%center% This text is centered. 

%right% Right justified.
(:markupend:)

and to create floating text:

(:markup class=horiz:)
%rfloat% This text floats to the right

%rframe% floats to the right with a frame

Lorem ipsum dolor sit amet, consectetuer sadipscing elitr
(:markupend:)

[[#Scopes]]
!! Scopes

Wikistyles can also specify a ''scope''; with no scope, the style is applied to any text that follows up to the next wikistyle specification or the end of the paragraph, whichever comes first. The '''apply=''' attribute and its shortcuts allow to change the scope as follows:

||border=1 cellpadding=3 cellspacing=0
||apply attribute ||shortcut ||style applies to... ||
||[@%apply=img ...%@] ||- ||any image that ''follows''||
||[@%apply=p ...%@] ||[@%p ...%@] ||the current paragraph||
||[@%apply=pre ...%@] ||- ||the current preformatted text||
||[@%apply=list ...%@] ||[@%list ...%@] ||the current list||
||[@%apply=item ...%@] ||[@%item ...%@] ||the current list item||
||[@%apply=div ...%@] ||- ||the current div||
||[@%apply=block ...%@] ||[@%block ...%@] ||to the current block, whether it's a paragraph, list, list item, heading, or division.||

thus '''[@%p color=blue%@]''' is the same as '''[@%apply=p color=blue%@]''', and '''[@%list ROMAN%@]''' is the same as '''[@%apply=list list-style=upper-roman%@]'''.

Some [[#predefined|predefined style shortcuts]] also make use of apply, thus '''[@%right%@]''' is a shortcut for '''[@%text-align=right apply=block%@]'''.

Example: Apply a style to a paragraph:
(:markup:)
%p bgcolor=#ffeeee% The wikistyle specification at the beginning of this line applies to the entire paragraph, even if there are %blue% other wikistyle specifications %% in the middle of the paragraph.
(:markupend:)

Wiki styles can also be applied to [[PmWiki/tables]] and [[PmWiki/table directives]]:
(:markup class=horiz:)
||class="green" style="font-style:italic; border:1px solid blue; background-color:#ffffcc"
||Everything after the above line is styled with green italic text, ||
|| ||
||This includes ||
||    preformatted text ||
||* lists ||
||-> indented items ||
(:markupend:)

(:markup class=horiz:)
(:table class="green" style="font-style:italic; border:1px solid blue; background-color:#ffffcc":)
(:cellnr:)
Everything after the above line is styled with green italic text,

This includes
    preformatted text
* lists
-> indented items
(:tableend:)
(:markupend:)

The '''[@>>style<<@]''' block can be used to apply a wikistyle to a large block of items.  
The style is applied until the next [@>><<@] is encountered.

(:markup class=horiz:)
>>blue font-style:italic bgcolor=#ffffcc<<
Everything after the above line is styled with blue italic text,

This includes
    preformatted text
* lists
-> indented items
>><<
(:markupend:)

The '''[@(:div style:)@]''' works in ''almost'' the same way as [@>>style<<@],
but the style information is encapsulated in a @@style=""@@ attribute and nested div blocks are possible.
(:markup class=horiz:)
(:div class="green" style="font-style:italic; border:1px solid blue; background-color:#ffffcc":)
Everything after the above line is styled with green italic text,

This includes
    preformatted text
* lists
-> indented items
(:divend:)
(:markupend:)

(:markup class=horiz:)
(:div1 style="font-style:italic; background-color:#ffffcc":)
outer style
(:div2 style="color:red; background-color:lightblue":)
nested style
(:div2end:)
again outer style
(:div1end:)
(:markupend:)

'''Caveat''': An applied wikistyle will only take effect if it's on the
line that starts the thing it's supposed to modify.  In other
words, a wikistyle in the third markup line of a paragraph
can't change the attributes of the paragraph:

(:markup class=horiz:) 
after the first line of the paragraph,
we try to %apply=p color=blue% change color.
This does't work because the style comes
(:markupend:)

(:markup class=horiz:)
However, this %p color=red% paragraph
''will'' be in red because its block style does
occur in the first line of its text.
(:markupend:)

(:markup class=horiz:) 
* Here's a list item
* %list red% Oops, too late to affect the list!
(:markupend:)

[[#Attributes]]
!! Wikistyle attributes

The style attributes recognized within a wikistyle specification are:

    ------------ CSS -------------          --HTML--
    color               bgcolor             class 
    background-color    margin              id
    text-align          padding             hspace
    text-decoration     border              vspace
    font-size           float               target
    font-family         list-style          rel
    font-weight         width*              accesskey
    font-style          height*             value
    display

    Special: define, apply

The attributes in the first two columns correspond to the ''[[cascading style sheet -> http://blooberry.com/indexdot/css/propindex/all.htm]]'' (CSS) properties of the same name.  The attributes in the last column apply only to specific items:

* '''[@class=@]''' and '''[@id=@]''' assign a CSS class or identifier to an HTML element
* '''[@target=name@]''' opens links that follow in a browser window called "name"
* '''[@rel=name@]''' in a link identifies the relationship of a target page
* '''[@accesskey=x@]''' uses 'x' as a shortcut key for the link that follows
* '''[@value=9@]''' sets the number of the current ordered list item

[=*=] The width and height attributes have asterisks because they are handled specially for <img .../> tags.  If used by themselves (i.e., without anything providing an "apply=" parameter to the wikistyle), then they set the 'width=' and 'height=' attributes of any <img ... /> tags that follow. Otherwise, they set the 'width:' and 'height:' properties of the element being styled.

[[#Styles]]
!! Enabling Styles
Styles not listed above can be enabled by a PmWiki Administrator by modifying the local/config.php file.  
For instance to enable the "line-height" style attribute add the line 

->$WikiStyleCSS[] = 'line-height';

to the local/config.php file.

[[#Shortcuts]]
!! Custom style shortcuts

The '''[@define=@]''' attribute can be used to assign a shorthand name to any wikistyle specification.\\  
This shorthand name can then be reused in later wikistyle specifications.

(:markup class=horiz:)
%define=box block bgcolor=#ddddff border="2px dotted blue"%

%box% [@some sort of text@]

%box font-weight=bold color=green% [@some sort of text@]
(:markupend:)

-< '''Tip:'''  It's often a good idea to put common style definitions into [[Group Header(s)]] pages so that they can be shared among multiple pages in a group.  Or, the [[wiki administrator]] can predefine styles site-wide as a [[local customization(s)]] (see [[Custom Wiki Styles]]).

-< '''Tip:''' Use custom style definitions to associate meanings with text instead of just colors.  For example, if warnings are to be displayed as green text, set [@%define=warn green%@] and then use [@%warn%@] instead of [@%green%@] in the document.  Then, if you later decide that warnings should be styled differently, it's much easier to change the (one) definition than many occurrences of [@%green%@] in the text.

-< '''Tip:''' Any undefined WikiStyle is automatically treated as a request for a class, thus [@%pre%@] is the same as saying [@%class=pre%@].

!![[#predefined]] Predefined style shortcuts

PmWiki defines a number of style shortcuts.

* Text colors: %black%black%%, %white bgcolor=black%white%%, %red%red%%, %yellow%yellow%%, %blue%blue%%, %gray%gray%%, %silver%silver%%, %maroon%maroon%%, %green%green%%, %navy%navy%%, %purple%purple%%  (shortcut for [@%color=...%@])
* Justification: [@%center%@] and [@%right%@]
* Images and boxes
** Floating left or right: [@%rfloat%@] and [@%lfloat%@]
** Framed items: [@%frame%@], [@%rframe%@], and [@%lframe%@]
** Thumbnail sizing: [@%thumb%@]
* Open link in new window: [@%newwin%@]  (shortcut for [@%target=_blank%@])
* Comments: [@%comment%@] (shortcut for [@%display=none%@])
* Ordered lists: [@%decimal%@], [@%roman%@], [@%ROMAN%@], [@%alpha%@], [@%ALPHA%@] (see also Cookbook:OutlineLists)

[[#Examples]]
!! Examples

[[Wiki Style Examples]] contains a number of examples of ways to use wikistyles in pages.

[[#KnownIssues]]
!! Known Issues
* Percents in style definitions (like: [@%block width=50% %@]) require the use of "pct" instead of "%".
* If you specify multiple values for an attribute, like @@border="2px solid blue"@@ make sure you place the values in quotes.
* Be sure to use lowercase letters for red-green-blue hex colors, [@%color=#aa3333%@] will work, [@%color=#AA3333%@] may not.

[[#SeeAlso]]
!!See Also
* [[PmWiki/Custom Wiki Styles]] {PmWiki/CustomWikiStyles$:Summary}
* [[PmWiki:List Styles]]        {PmWiki/ListStyles$:Summary}

>>faq<< [[#faq]]
Q: 
A:
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiTrails</pagename>
<data><![CDATA[(:Summary: Trails from lists items from a single page:)
(:div class="rfloat frame" style="font-size:smaller; clear:right;" :)
!! Table of contents
* [[#creating | Creating a trail]]
* [[#types | Types of trail]]
* [[#linksyntax | Trail link syntax]]
* [[#using | Using a trail]]
** [[#pathtrail | Path trail]]
** [[#circular-trails | Circular trail]]
* [[#crossgroup | Cross group trails]]
* [[#trailstyle | Trail style]]
* [[#trailpagelists | Trail page lists]]
(:divend:)
(:Audience: authors (basic) :)
The WikiTrails feature allows wiki authors to create "trails" through sequences of pages in the wiki. You simply specify pages and their order on a "trail index", and then place the navigation markup on the pages that you will be navigating. 

(Don't confuse the [[PmWiki/PageLists|pagelist]] directive with WikiTrails - they are different animals as explained in the [[#faq|Q and A]] below.)

[[#creating]]
!! Creating a trail

Before you can use a trail through a group of pages, you have to create a "trail index" on a separate page, which we will call the "trail index page". 
On that trail index page, you simply create a numbered or bulleted list of links. (So every numbered or bulleted list of links implicitly creates a trail.) 
It is important that each page name ([[Links|link]]) be the first item following each bullet; any text or formatting in front of the page name will exclude it from the trail.

An example trail index page might contain the list:
[[#trailstart]]
* [[Installation]] how to install
* [[The customisation page->LocalCustomizations]]
* [[PmWiki]] some other text [[PmWiki Philosophy]] [-(The latter won't be in the trail because it is preceded by text)-]
* Yet some other text. [[PmWiki.WikiStyles]] [-(This won't be in the trail because it follows text)-]
* %center%[[PmWiki/Uploads]] [-(This won't be in the trail because it is preceded by the [=%center%=] style.)-]

* Some text [-(This won't be in the trail because it is not a link)-]
* [[PmWiki/PageLists]] {PmWiki/PageLists$:Summary}
* [[http://pmwiki.org]] [-(This won't be in the trail because it is not a page link)-]
** [[PmWiki:InterMap]]  [-(This won't be in the trail because it is an [[InterMap]] link)-]
* [[Cookbook:Cookbook]] [-(This won't be in the trail because it is an [[InterMap]] link)-] 
: [[PmWiki philosophy]] :  [[Design notes]] [-(The first link will, and the second link won't, be in the trail defined by ([[TextFormattingRules#DefinitionLists | definition list]]))-]
* [[#security]][[Security]] [-(This won't be in the trail because its preceded by a (hidden) [[Links#anchors | anchor]])-]
* %newwin%[[Links]] [-(This won't be in the trail because its preceded by a (hidden) [=%newwin%=] style)-]
* ''[[PmWiki/Troubleshooting]]''  [-(This won't be in the trail because its preceded by (hidden) ''italic'' style markup)-]
[[#trailend]]

The list above creates the following "wikitrail", displayed using a [[PageLists|pagelist]]:
(:markup:)
(:pagelist trail={$FullName}#trailstart#trailend fmt={$FullName}#traillist:)
(:markupend:)

!!! Observations

# In general, indentation levels in the page list don't matter -- trails are a linear sequence of pages.
# A page is part of the trail only if the page link immediately follows the list markup.
#The list itself can be [[#linksyntax|delineated]] by the use of [[#list#anchors|anchors]], allowing for multiple lists on a page, or for some list items to be excluded.

[[#types]]
!! Trail types
PmWiki defines 2 trail markups:

* '''[@<<|[[Trail Index Page]]|>>@]''' displays as "[=<< PreviousPage | Trail Index Page | NextPage >>=]".

* '''[@<|[[Trail Index Page]]|>@]''' displays as "[=< PreviousPage | Trail Index Page | NextPage >=]", except the appropriate arrow is omitted at the beginning and end of the trail.

[[#linksyntax]]
!! Trail link syntax
The trail link has the same syntax as a standard [[link(s)]], 
this means for example you can specify 
* [@<|[[TrailIndexPage | +]]|>@]

Trail links can be restricted by [[links#anchors|anchors]] (links to a specific location within a page),
this means you can have more than one trail on a page, or start a trail from a specific location in a page.
* [@<|[[Trail Index Page#trailstart#trailend]]|>@]

[[#using]]
!! Using the trail

What makes a trail "work" is adding ''trail markup'' on the pages in the trail (i.e. the pages that are listed in the bullet/numbered list on the trail index page).

To build a trail, add  ''trail markup'' like [@<<|[[TrailIndexPage]]|>>@] to a page, where `TrailIndexPage is the page, described above, containing the bulleted list of pages in the trail.  PmWiki will display the trail markup with links to any previous and next pages in the trail. 

The trail markup can be placed anywhere in a page, and a page can contain multiple trail markups.  If you are adding a trail to every page in a group, consider setting the trail markup in the [[Group Headers | GroupHeader]] or GroupFooter pages instead of on every individual page in your group.

[[#pathtrail]]
!!! Path trail[[#path-trail]]

[@^|[[TrailIndexPage]]|^@] treats the list levels as a hierarchy and displays the "path" to reach the current page (i.e., a "breadcrumb" trail).  In the example trail above, the markup [@^|TrailIndexPage|^@] on [@TrailPage4@] would display as "[=TrailIndexPage | TrailPage2 | TrailPage4=]".

Wiki administrators can change the trail separator of the "path" trail ( [@^|[[TrailIndexPage]]|^@] ) from the default | by setting the variable $TrailPathSep in the ''config.php'' file. For instance $TrailPathSep = ' > '; will output "[=TrailIndexPage > TrailPage2 > TrailPage4=]".

[[#circular-trails]]
!! Circular trails

Typically, a trail is a linear list with a first and a last page. However, the trail can be made "circular" by repeating the first page as the last item in the trail index:

->[@
 * [[TrailPage1]]
 * [[TrailPage2]]
 ...
 * [[TrailPageN]]
 * [[TrailPage1]]
@]

If the trail index page is intended to be read by others, the last item can be made invisible inside an [@(:if false:)@] block:

->[@
 * [[TrailPage1]]
 * [[TrailPage2]]
 ...
 * [[TrailPageN]]
 (:if false:)
 * [[TrailPage1]]
 (:ifend:)
@]

[[#crossgroup]]
!! Cross Group Trails
Before version 2.2.1, if your trail contains pages in different groups, it should use full [=[[Group.Name]]=] links instead of just [=[[Name]]=].

!! Other notes
* There is no space between @@<|@@ and @@[=[[link]]=]@@ and @@|>@@; same for the other trail markups.
* Note that non-existing pages will appear in the WikiTrail as links.

[[#trailstyle]]
!!! Trail style
PmWiki encapsulates the trail with a ''wikitrail'' css class. 
This allows the wiki trail to be [[LocalCustomizations | customised]] by defining CSS for the ''wikitrail'' in the ''local.css'' file.

[[#trailpagelists]]
!!! Trail in [[page lists]]
Trails from a single page can only be displayed using the pagelist [[PmWiki/PageLists#pagelisttrail|trail]] parameter. For example
(:markup class="horiz":)
(:pagelist trail=PmWiki/WikiTrails fmt=PmWiki.WikiTrails#traillist order=random count=3:)
(:markupend:)

!!!A simple example of a WikiTrail

1) On the TrailIndexPage:

[@
* [[MyTrailPage1]]
* [[MyTrailPage2]]
* [[MyTrailPage3]]
@]

2) On the pages MyTrailPage1, 2, and 3:

[@
<<|[[TrailIndexPage]]|>>
@]

>>comment<<
[[#traillist]]
%font-size:small green%> [[{=$FullName}|{=$Groupspaced}.{=$Namespaced}]] <
[[#traillistend]]
>><<

!! Questions
[[#faq]]
>>faq<<
Q: What's the difference between a [[[[PmWiki/PageLists|PageList]] and a WikiTrail?
A: The pagelist directive dynamically generates a list of pages. There are many ways to generate the list, including using a WikiTrail as the source. The pagelist directive then displays the pages that match the criteria using an optional template - for example displaying each page name on a separate line as a link or including the entire content. The pagelist directive currently does not have built-in navigation markup that you can put on the pages in the list. By contrast, WikiTrails are simply specified via links on an "index" page and you ''can'' put previous-next navigation markup on each page. The two serve very different purposes. WikiTrails are useful for specifying the pages in [[PmWiki/WebFeeds|web feeds]], for creating a "tour" through a predefined set of pages, and many other things.
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiWikiWeb</pagename>
<data><![CDATA[(:Summary: An introduction to the Wiki Wiki Web (www):)
'''WikiWikiWeb''' is an "open-editing" system where the emphasis is on the ''authoring'' and ''collaboration'' of documents rather than the simple browsing or viewing of them. 
The name "wiki" is based on the Hawaiian term "wiki wiki", meaning "quick" or "super-fast". 
The basic concept of a WikiWikiWeb (or "wiki") is that (almost) anyone can edit any page. While at first this sounds like a recipe for complete anarchy, the truth is that sites using this system have developed surprisingly complex and rich communities for online collaboration and communication.  Yes, it's possible for someone to go and destroy everything on a page, but it doesn't seem to happen often.  And, many systems (including this one) have built-in mechanisms to restore content that has been defaced or destroyed.

''The point of the system is to simply make it as ''quick'', ''easy'' and ''rewarding'' as possible to create or edit online content.''

Using any standard Web browser, a person can edit (almost) any page on the system using relatively simple [[text formatting rules]].  [[Links | Creating a link]] to a new or existing page simply involves putting the word or phrase that will be your link text inside of [=[[double square brackets]]=] to reference and serve as a title for the target page. In the process of creating the link you're ''creating the new page'', if it doesn't already exist.  On some sites (depending on the configuration of PmWiki), a link can also be created by entering a WikiWord--a word consisting of two or more capitalized words joined together.

It's not even necessary to learn all of the formatting rules; others will often come in and reformat things for you.  After all, anyone can edit!  '''You''' can see some of the [[({$SiteGroup}.All) recent changes]] that others have posted to this site.

To learn more about adding pages to this Wiki site, see [[basic editing]], then try editing pages in the [[Main/WikiSandbox]].

If you want to learn more about the WikiWikiWeb concept, try some of these Web sites:

* %newwin%Wiki:WikiWikiWeb -- The original WikiWikiWeb
* %newwin%Meatball:WhyWikiWorks -- how and why Wiki works
* %newwin%Meatball:SoftSecurity -- how open editing can result in good Web sites
* %newwin%[[http://emacswiki.org/cgi-bin/community/CategoryWiki|Wiki]] on [[http://emacswiki.org/cgi-bin/community/SiteMap|CommunityWiki]]
* %newwin%[[Wikipedia:Wiki#Key_characteristics|WikiFeatures]] -- for info on features in wikis and how to use them
* %newwin%Wikipedia:Why_Wikipedia_is_so_great -- how and why the biggest wiki in the world made a comprehensive free-content encyclopedia
* %newwin%[[http://wikitravel.org/en/article/Wikitravel:Wiki | Wikitravel:WikiWiki]] -- another introduction to wikis, on another exemplary site

Or, send email to Patrick Michaud at mailto:pmichaud@pobox.com.]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Terry Phelps</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiWord</pagename>
<data><![CDATA[!!Definition and use as Page Titles
A WikiWord is a set of two or more words run together, where the first letter of each word is capitalized. This syntax is also sometimes referred to as "mixed case" or "camel case". WikiWords are used as '''page titles''' in a [[WikiWikiWeb]].  

!!Use as links
In some wikis, you can string any sequence of words together, capitalizing the first letter of each word, to make a valid WikiWord '''link'''. In such PmWiki installations, WikiWords surrounded by [=[=...=]=] or preceded by a backquote (`) are not turned into links: 

(:linkwikiwords:)
(:markup:)[@LikeThis compared to `LikeThis or even [=LikeThis=]@]
(:nolinkwikiwords:)

See [[Links]] for information about `PmWiki's rules for forming links and forming page titles.

!!!!Enabling WikiWord links
WikiWord links are disabled by default since Pmwiki version 2.1 beta2. To enable WikiWord links you need to  set in ''config.php'' 

->     [@$LinkWikiWords = 1;@]  

If you want to display links to non-existent pages without decoration, place the following lines in ''pub/css/local.css'': 

->    [@span.wikiword a.createlink { display:none; }
span.wikiword a.createlinktext { border-bottom:none; text-decoration:none; color:inherit; }@]
 
!!!!Finding WikiWord links
If you upgraded from an earlier version and want to convert WikiWord links to standard [[links]], the following will help to find those WikiWord links easier by highlighting them. Set in ''config.php'':

->       [@$HTMLStylesFmt['wikiword'] = "span.wikiword { background:yellow; }";@] 

!!!!Disabling certain WikiWords
The variable $WikiWordCount controls WikiWord conversion on a per word basis.

Other descriptions of WikiWords are available from [[Wiki:WikiWord]] and [[Wikipedia:WikiWord]].

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>PmWiki.WikiWords</pagename>
<data><![CDATA[(:Summary:Redirects to [[PmWiki.WikiWord]]:)
(:redirect WikiWord:)]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.AuthUser</pagename>
<data><![CDATA[(:redirect SiteAdmin.AuthUser:)
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author></author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.EditForm</pagename>
<data><![CDATA[(:Summary:contains the edit page layout form:)
!! $[Editing {*$FullName}] %block class=wikiaction%
(:messages:)
(:div id='wikiedit':)
(:input e_form:)[[#top]](:e_guibuttons:)\\
(:input e_textarea:)\\
$[Summary]: (:input e_changesummary:)\\
$[Author]: (:input e_author:) (:input e_minorcheckbox:) $[This is a minor edit]\\
(:input e_savebutton:) (:input e_savedraftbutton:) (:input e_saveeditbutton:) (:input e_previewbutton:) (:input e_cancelbutton:)
(:input end:)
(:divend:)
(:include $[{$SiteGroup}/EditQuickReference]:)
(:if e_preview:)
!! $[Preview {*$FullName}]
'''$[Page is unsaved]'''
(:e_preview:)
----
'''$[End of preview -- remember to save]'''\\
[[#top | $[Top] ]]
(:ifend:)
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.EditQuickReference</pagename>
<data><![CDATA[(:Summary:quick reference for [[PmWiki/BasicEditing|editing]] pages:)
%define=em font-weight=bold%
(:table width='100%' cellspacing='0' cellpadding='0' style='font-size:80%; font-family:Arial; padding:2px; border:1px solid #cccccc;' class='quickref' :) (:comment Use 'quickref' class to override formatting :)
(:cellnr:)
%target=_blank% [[PmWiki/Basic editing]] - [[PmWiki/Text formatting rules]] - [[PmWiki/Documentation index]]
(:cell align=right:)
%em%Tables%%: %target=_blank%[[PmWiki/Tables | simple ]] - [[PmWiki/TableDirectives | advanced ]]
(:cellnr:)
%em%Paragraphs%%: for a new paragraph, use a blank line;
(:cell align=right:)
%em%Line break%%: 
%em%[=\\=]%%, 
%em%[=[[<<]]=]%%, or 
%em%[=(:nl:)=]%%
(:cellnr:)
%em%[=->=]%% to indent text, 
%em%[=-<=]%% hanging text 
(:cell align=right:)
%em%Join line%%: %em%\%%
(:cellnr colspan='2':)
%em%Lists%%: 
%em%*%% for bulleted, 
%em%#%% for numbered, 
%em%:%%term%em%:%%definition for definition lists
(:cellnr colspan='2':)
%em%Emphasis%%: 
%em%[=''=]%%''italics''%em%[=''=]%% &nbsp;
%em%[='''=]%%'''bold'''%em%[='''=]%% &nbsp;
%em%[='''''=]%%'''''bold italics'''''%em%[='''''=]%% &nbsp;
%em%[=@@=]%%@@monospaced@@%em%[=@@=]%%
(:cellnr colspan='2':)
%em%References%%: 
%em%[=[[=]%%another page%em%[=]]=]%%, 
%em%[=[[=]%%[=http://example.com/=]%em%[=]]=]%%, 
%em%[=[[=]%%another page %em%[=|=]%% link text%em%[=]]=]%%, 
%em%[=[[#=]%%anchor%em%[=]]=]%%,
%em%[=[[#=]%%anchor %em%[=|=]%% link text%em%[=]]=]%%
(:cellnr colspan='2':)
%em%Groups%%: 
%em%[=[[=]%%Group%em%[=/=]%%Page%em%[=]]=]%% [-displays Page,-] 
%em%[=[[=]%%Group%em%[=.=]%%Page%em%[=]]=]%% [-displays [=Group.Page=],-] 
%em%[=[[=]%%Group%em%[=(.=]%%Page%em%[=)]]=]%% [-displays Group,-]
%em%[=[[=]%%Group%em%[=/]]=]%% [-links Group homepage-]
(:cellnr:)
%em%Separators%%: 
%em%!!%%, 
%em%!!!%% for headings, 
%em%[=----=]%% for horizontal line
(:cell align=right:)
%em%Prevent formatting%%: 
%em%[=[==]%%...%em%[==]=]%%
(:cellnr:)
%em%Other%%: 
%em%[=[+=]%%[+big+]%em%[=+]=]%% &nbsp;
%em%[=[++=]%%[++bigger++]%em%[=++]=]%% &nbsp;
%em%[=[-=]%%[-small-]%em%[=-]=]%% &nbsp;
%em%[=[--=]%%[--smaller--]%em%[=--]=]%% &nbsp;
%em%[='^=]%%'^superscript^'%em%[=^'=]%% &nbsp;
%em%[='_=]%%'_subscript_'%em%[=_'=]%% &nbsp;
%em%[={+=]%%{+inserted+}%em%[=+}=]%% &nbsp;
%em%[={-=]%%{-deleted-}%em%[=-}=]%%
(:cell align=right:)
%em%Preformatted%%: 
%em%[=[@=]%%...%em%[=@]=]%%  or 
%em%[=>>=]pre<<%%...%em%[=>>=]<<%%
(:tableend:)]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.PageActions</pagename>
<data><![CDATA[(:Summary:Contains the '[[PmWiki/AvailableActions|action]]' links (like Browse, Edit, History, etc.), placed at the top of the page, see [[PmWiki/site page actions]]:)
(:comment This page can be somewhat complex to figure out the first time you see it. Its contents are documented at PmWiki.SitePageActions if you need help. :)
* %item rel=nofollow class=browse    accesskey='$[ak_view]'%      [[{*$FullName}               | $[View] ]]
* %item rel=nofollow class=edit      accesskey='$[ak_edit]'%      [[{*$FullName}?action=edit   | $[Edit] ]]
* %item rel=nofollow class=diff      accesskey='$[ak_history]'%   [[{*$FullName}?action=diff   | $[History] ]]
(:if auth upload:)
* %item rel=nofollow class=upload    accesskey='$[ak_attach]'%    [[{*$FullName}?action=upload | $[Attach] ]]
(:ifend:)
* %item rel=nofollow class=print     accesskey='$[ak_print]'%     [[{*$FullName}?action=print  | $[Print] ]]
(:if group Site,SiteAdmin,Cookbook,Profiles,PmWiki*:) (:comment delete if and ifend to enable backlinks:)
* %item rel=nofollow class=backlinks accesskey='$[ak_backlinks]'% [[{*$Name}?action=search&q=link={*$FullName} | $[Backlinks] ]]
(:ifend:)
(:if enabled AuthPw:)
* %item rel=nofollow class=logout    accesskey='$[ak_logout]'%''  [-[[{*$FullName}?action=logout | $[Logout] ]]-]''
(:ifend:)]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.PageListTemplates</pagename>
<data><![CDATA[(:Summary:[[(PmWiki/PageList)Templates]] for PmWiki's [[PmWiki/Page lists]] directive:)
This page contains "templates" for PmWiki's [@(:pagelist:)@] directive.  The [[Site.LocalTemplates]] page can be created and used to store pagelist templates that are local to a site.

!!Page list template documentation
* [[PmWiki.Page Lists]] - {PmWiki/PageLists$:Summary}
* [[PmWiki.Page List Templates]] - {PmWiki/PageListTemplates$:Summary}
* [[PmWiki.Page Variables]] - {PmWiki/PageVariables$:Summary}
* [[PmWiki.PageTextVariables|Page Text Variables]] - {PmWiki/PageTextVariables$:Summary}
* [[PmWiki.Conditional Markup]] - {PmWiki/PageLists$:Summary}
* [[Cookbook:Pagelist Template Samples]] - {Cookbook/PagelistTemplateSamples$:Summary}

!!fmt=#default

The default template for pagelists when [@fmt=@] isn't specified (and note that on the PmWiki.org wiki, this template is over-ridden by the one on the [[Site.LocalTemplates]] page).

(:markup class="horiz":)
(:if false:)
[[#default]]
(:template first {=$Group}:)

:[[{=$Group}/]] /:
(:template each:)
: :[[{=$Group}/{=$Name}]]
[[#defaultend]]
(:ifend:)

(:pagelist group={$Group} fmt=#default count=6:)
(:markupend:)

!!fmt=#bygroup

Display pages by group/name.

(:markup class="horiz":)
(:if false:)
[[#bygroup]]
(:template first {=$Group}:)

:[[{=$Group}/]] /:
(:template each:)
: :[[{=$Group}/{=$Name}]]
[[#bygroupend]]
(:ifend:)

(:pagelist group={$Group} fmt=#bygroup count=6:)
(:markupend:)

!!fmt=#simple

A simple bullet list of page names.

(:markup class="horiz":)
(:if false:)
[[#simple]]
* [[{=$FullName}]]
[[#simpleend]]
(:ifend:)

(:pagelist group={$Group} fmt=#simple count=5:)
(:markupend:)

!!fmt=#title

A simple bullet list of page titles. 

(:markup class="horiz":)
(:if false:)
[[#title]]
(:template defaults order=title:)
* [[{=$FullName}|+]]
[[#titleend]]
(:ifend:)

(:pagelist group={$Group} fmt=#title count=5:)
(:markupend:)

!!fmt=#titlespaced

Outputs wiki page titles with spaces between the words in the title.

(:markup class="horiz":)
(:if false:)
[[#titlespaced]]
(:template defaults order=title:)
* [[{=$FullName}|{=$Titlespaced}]]
[[#titlespacedend]]
(:ifend:)

(:pagelist group={$Group} fmt=#titlespaced count=5:)
(:markupend:)

!!fmt=#group

A bullet list of groups.

[@
[[#group]]
(:template first {=$Group}:)
* [[{=$Group}/]]
[[#groupend]]
@]

!!fmt=#include

Concatenate the text of pages in the list.  (Note, this can be an expensive operation!)

[@
[[#include]]
(:include {=$FullName} self=0:)
[[#includeend]]
@]

!!fmt=#includefaq

Include just the #faq sections from pages in the list.  (This can also be expensive,
especially if the list includes pages that don't have the [@[[#faq]]@] anchor!)

[@
[[#includefaq]]
!![[{=$FullName}|+]]
>>faq<<
(:include {=$FullName}#faq#faqend self=0:)
>><<
[[#includefaqend]]
@]

!!fmt=#description

List pages and append the page's description if it exists. Creates dash by all names, but adding a nested loop to get rid of it causes markup problems (nested loops are not allowed).

(:markup class="horiz":)
(:if false:)
[[#description]]
* [[{=$FullName}|+]]
  - {=$Description}
[[#descriptionend]]
(:ifend:)

(:pagelist group={$Group} fmt=#description count=7:)
(:markupend:)

!!fmt=#simplename

Simple bullet list of page names, without the Group name. 

(:markup class="horiz":)
(:if false:)
[[#simplename]]
* [[({=$Group}/){=$Name}]]
[[#simplenameend]]
(:ifend:)

(:pagelist group={$Group} fmt=#simplename count=5:)
(:markupend:)

!!fmt=#simplenamespaced

Simple bullet list of spaced page names, without the Group name. 

(:markup class="horiz":)
(:if false:)
[[#simplenamespaced]]
* [[({=$Group}/){=$Namespaced}]]
[[#simplenamespacedend]]
(:ifend:)

(:pagelist group={$Group} fmt=#simplenamespaced count=5:)
(:markupend:)

!! fmt=#titlesummary

A simple bullet list of page title and summary. 

(:markup class=horiz:)
>>comment<<
[[#titlesummary]]
* [[{=$FullName} | {=$Titlespaced}]] &nbsp; [-{=$:Summary}-]
[[#titlesummaryend]]
>>font-size:smaller<<

(:pagelist group=Site fmt=#titlesummary list=normal count=8:)
(:markupend:)

!!fmt=#count

Number of pages in pagelist 

(:markup class="horiz":)
(:if false:)
[[#count]]
(:template defaults wrap=inline list=normal :)
(:template last:)
{$$PageCount}
[[#countend]]
(:ifend:)

Number of pages in the {$Group} group: (:pagelist group={$Group} fmt=#count :).

Number of pages in the {$Group} group: (:pagelist group={$Group} fmt=count :).

There are (:pagelist group=PmWiki fmt=#count wrap=html :) pages in the PmWiki group.
(:markupend:)
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.Preferences</pagename>
<data><![CDATA[(:Summary: Preferences for access keys and edit form:)
Preferences for [[PmWiki/access keys]] and edit form

This page can be used as template for (personal) preferences, or set as default site preference (see below).

->[@
  # Access keys - hold Alt (Windows IE), Shift + Alt (Firefox)
  # or Control (Mac) and tap the indicated key on your keyboard
  # to trigger the corresponding action.
#  'ak_view'          => '' ,         # view page
  'ak_edit'          => 'e',         # edit page
  'ak_history'       => 'h',         # page history
#  'ak_print'         => '',          # print view of page
  'ak_recentchanges' => 'c',         # Recent Changes
  'ak_save'          => 's',         # save page
  'ak_saveedit'      => 'u',         # save and keep editing
  'ak_savedraft'     => 'd',         # save as draft
  'ak_preview'       => 'p',         # preview page
  'ak_em'            => 'i',         # emphasized text (italic)
  'ak_strong'        => 'b',         # strong text (bold)

#  'ak_attach'        => '',          # attach a file
#  'ak_backlinks'     => '',          # show backlinks
#  'ak_logout'        => '',          # log out

  # Editing components
  'e_rows' => '20',                  # rows in edit textarea
  'e_cols' => '70',                  # columns in edit textarea
  'Site.EditForm' => 'Site.EditForm' # location of EditForm
  @]

To create personal user (browser) preferences,
* make a copy of [[{$FullName}?action=source | this page]] somewhere, preferably as @@Profiles.''%green%insert_your_name_here%%''-Preferences@@
* edit that page with your new preferred settings,
* select [[{$FullName}?setprefs={$FullName} | Set Preferences of this Page]] on the page containing your newly created settings. 
-> This sets a preference cookie on your browser which tells PmWiki where to find your personal preference settings.

To revert to the PmWiki default preferences
* select [[{$Name}?setprefs=| Revert to PmWiki Default Preferences]] to unset the preference cookie

See also [[Cookbook:UserConfigurations]] about how to customise the edit form for personal use.

Note that by default, parsing of {$FullName} is disabled. To make it the default site preference, add
 XLPage('prefs', "Site.Preferences");
to a config file (e.g. local/config.php).
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>OliverBetz</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.SideBar</pagename>
<data><![CDATA[* [[Main/HomePage]]
* [[Main/WikiSandbox]]

%sidehead% [[PmWiki/PmWiki]]
* [[PmWiki/Initial Setup Tasks]]  
* [[PmWiki/Basic Editing]]
* [[PmWiki/Documentation Index]]
* [[PmWiki/FAQ | PmWiki FAQ ]]
* [[PmWiki/PmWikiPhilosophy]]
* [[PmWiki/Release Notes]]
* [[PmWiki/ChangeLog]]

%sidehead% [[http://www.pmwiki.org | pmwiki.org ]]
* [[Cookbook:CookbookBasics | Cookbook (addons) ]]
* [[Cookbook:Skins | Skins (themes) ]]
* [[PITS:PITS | PITS (issue tracking) ]]
* [[PmWiki/Mailing Lists]]

%right% [-[[Site.SideBar?action=edit | edit SideBar]]-]]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author></author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.Site</pagename>
<data><![CDATA[(:title Site Configuration:)(:Summary: Site Configuration:)
Here you find some links to Site configuration and administration pages. Add links to other pages you may need for your site's configuration here, as necessary. 
Some links may only apply to certain configurations or [[PmWiki/skins]].

The [[{$SiteGroup}/]] group contains configuration pages, and the [[SiteAdmin/]] group contains administrative pages.

'''Note to new administrators''':
* All pages in the 'Site' group (except [[Site.Side Bar]]) are locked for editing as the default. [[{$SiteGroup}.SideBar]] is locked with the site-wide edit password, if one is set.  
* All pages in the 'SiteAdmin' group are locked for reading and editing as the default.
* In order to edit any locked page you need to create in @@local/config.php@@ a site wide '''admin''' password (see [[PmWiki/Passwords Admin]]).  Then you can edit pages and change the access protection of individual pages by changing the page attributes with [@?action=attr@].
(:table border=0 width=100%:)
(:cellnr:)
!! Configuration and Menu Pages
(:pagelist group={$SiteGroup} name=AuthUserPageActions,InterMap,Search,Preferences,PageNotFound fmt=#titlesummary:)

* [[{$SiteGroup}/All recent changes]] - changes made to all pages in all groups

!! SideBar, header, and footer pages
Sidebar, [[PmWiki/GroupHeaders | headers]] and footers are used to display common content across a group or entire website.
(:pagelist group={$SiteGroup} name=*bar*,*head*,*foot* fmt=#titlesummary:)

!! Form pages
[[PmWiki/Forms]] are used for display and entry of information.
(:pagelist group={$SiteGroup} name=*form* fmt=#titlesummary:)

!! Quick reference pages
Quick reference pages are included in other pages to assist in the use of those pages.
(:pagelist group={$SiteGroup} name=*quick* fmt=#titlesummary:)

!! Template pages
Templates are used by page and form directives to control the output displayed.
(:pagelist group={$SiteGroup} name=*template* fmt=#titlesummary:)
(:cell:)
!! Site Administration
Here is the list of the pages in the [[SiteAdmin/]] group. Some links may only apply to certain configurations.
(:pagelist group=SiteAdmin list=all fmt=#titlesummary:)
(:tableend:)

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>Site.UploadQuickReference</pagename>
<data><![CDATA[(:Summary:quick reference for [[PmWiki/uploads|uploading]] pages:)
[[#quickreference]]
>>color:#000000 bgcolor:#f9f9f9 font-family:'Arial,sans-serif' font-size:12px padding:2px border:'1px solid #cccccc' class='quickref'<<
'''%newwin%[[PmWiki/Uploads]]'''

# Use the "Browse" button above to find the "File to upload" on your local computer.

# For the "Name attachment as:" field, enter the name you prefer the file to have once it has been uploaded to the site. [[<<]]This can be the same as its filename on your source disk ''or it can be different'', but %bgcolor:yellow%'''make sure it has the correct file extension'''%%.

# Press "$[Upload]" to upload the file.

# To refer to an attachment within a wiki page in this {$Group} `WikiGroup, simply enter @@[=Attach:=]''filename.ext''@@ in the page text.

# After uploading, you can 
** %item rel=nofollow class=browse    accesskey=$[ak_view]% [[{*$FullName}?action=browse | $[View] the {*$Name} page]] or
** %item rel=nofollow class=edit      accesskey=$[ak_edit]% [[{*$FullName}?action=edit   | $[Edit] the {*$Name} page]] or
** Scroll down to view the list of files that have been uploaded to the {*$Group} wiki group.
>><<
[[#quickreferenceend]]

----

!! Existing uploads
>>font-size:smaller<<
(:attachlist:)
>><<]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>SiteAdmin.AuthList</pagename>
<data><![CDATA[This page displays the permissions settings for pages that have permissions set.  Fields that say "(protected)" mean that you may need to [[{*$FullName}?action=login | log in]] (e.g., with an administrative password) in order to view them.

(:pagelist fmt=#authlist request=1:)

(:if false:)
[@
[[#authlist]]
(:template defaults passwd=?* list=all:)
(:template first:)
|| class='indent authlist' cellspacing=0 cellpadding=0
(:template first {=$Group}:)

'''{=$Group}:'''

(:if exists {=$Group}.GroupAttributes:)
{=$Group}.GroupAttributes 
[- [[{=$Group}.GroupAttributes | (view)]] -]
[- [[{=$Group}.GroupAttributes?action=attr | (attr)]] -] :
||read    ||{{=$Group}.GroupAttributes$PasswdRead}   ||
||edit    ||{{=$Group}.GroupAttributes$PasswdEdit}   ||
||attr    ||{{=$Group}.GroupAttributes$PasswdAttr}   ||
||upload&nbsp;&nbsp;&nbsp; ||{{=$Group}.GroupAttributes$PasswdUpload} ||
(:if:)
(:template each:)

(:if ! equal {=$Name} GroupAttributes :)
{=$FullName}
[- [[{=$FullName} | (view) ]] -]
[- [[{=$FullName}?action=attr | (attr) ]] -] :
||read    ||{=$PasswdRead} ||
||edit    ||{=$PasswdEdit} ||
||attr    ||{=$PasswdAttr} ||
||upload&nbsp;&nbsp;&nbsp; ||{=$PasswdUpload} ||
(:if:)
(:template last:)

Displayed {$$PageCount} pages.
[[#authlistend]]

@]]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Pm</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>SiteAdmin.AuthUser</pagename>
<data><![CDATA[(:Summary: Configuration of identity based authorisations:)
(:nolinkwikiwords:)
This is the default configuration page for PmWiki's identity-based authorizations (aka "authuser.php").  See [[PmWiki.AuthUser]] for instructions.

(:if enabled EnableAuthUser:)
This site appears to have the authuser extensions enabled.
(:if !enabled EnableAuthUser:)
At present this site doesn't appear to have the authuser extensions enabled.  To enable them, add the line [@include_once("$FarmD/scripts/authuser.php");@] to your ''local/config.php'' file.  (See [[PmWiki.LocalCustomizations]].)
(:ifend:)

!! Login accounts

Specify login accounts in the form "@@[=username: (:=]encrypt ''password'':)@@":

-> # Examples:
-> # alice: [=(:=]encrypt wonderland:)
-> # bob: [=(:=]encrypt builder:)

Note that the passwords will be encrypted when the page is saved, so that the result will look something like:

-> # alice: $1$0gcdAN1a$HTdEAXyYYo8Hc9/Xv30Yz1
-> # bob: $1$wSP2R80i$sJ593ERCmTtjm3Fk26HCV1

To authorize specific login accounts for pages and groups, use "[@id:username@]" as a password in [@?action=attr@] or $DefaultPasswords (see [[PmWiki.Passwords]]).  Use "[@id:*@]" to mean "any logged-in user".

!! Authorization groups

Authorization groups are specified with a leading "@" sign.  Define either the login accounts belonging to a group or the groups for a login account:

-> # @writers: alice, bob  
-> # carol: @editors, @writers
-> # @admins: alice, dave

Then use "[@@group@]" as a password in [@?action=attr@] or $DefaultPasswords.

!! Login accounts from external sources

Obtaining login accounts from external sources (uncomment out appropriate line(s)):

-> # htpasswd: /filesystem/path/to/.htpasswd
-> # ldap: ldap://ldap.example.com/ou=People,o=example?uid?sub
-> # mysql: mysql://[username:password]@localhost/db/table?user,passwd

]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>SiteAdmin.SiteAdmin</pagename>
<data><![CDATA[(:include Site.Site:)
(:title Site Administration:)(:Summary: Site Administration:)
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>Petko</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
<asset>
<pagename>SiteAdmin.Status</pagename>
<data><![CDATA[(:Summary: PmWiki version {$Version} (VersionNum={$VersionNum}):)
(:comment Any local edits to this page may be lost!:)

This site is running {$Version} (VersionNum={$VersionNum}).
]]></data>
<template>pmwiki.tpl</template>
<activated>1</activated>
<staticcache>1</staticcache>
<rss_include>1</rss_include>
<author>simon</author>
<rread_users>|anonymous|</rread_users>
<rwrite_users>|anonymous|</rwrite_users>
</asset>
</simple_cms>