## FAQ

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 Questions page or search for documentation using the search facility. More documentation can be found on the documentation index page.

## Introduction

What is PmWiki?

PmWiki is a wiki-based system for collaborative creation and maintenance of websites. See PmWiki.

What can I do with it?

PmWiki pages look and act like normal web pages, except they have an "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 Text Formatting Rules in the "Wiki sandbox". The website you're currently viewing is built and maintained with PmWiki.

What are the requirements?

See the PmWiki requirements page.

Where can I find documentation?

See the documentation index page.

How do I install PmWiki?

Instructions for installation are on the installation page.

How do I get help with PmWiki?

How do you pronounce "Michaud"?

"Michaud" is french pronounced "mee show", the trailing D is silent.

## Basic PmWiki editing rules

I'm new to PmWiki, where can I find some basic help for getting started?

The Basic Editing page is a good start. From there, you can just follow the navigational links at the top or 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.

How do I include special characters such as Copyright (©) and Trademark (® or ™) on my wiki pages?

See special characters on how to insert special characters that don't appear on your keyboard.

How can I preserve line-breaks from the source text?

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 the following lines of markup text in the page to be kept as separate lines in the output. Or a wiki administrator can set in config.php $HTMLPNewline = '<br/>'; to force literal new lines for the whole site. Can I just enter HTML directly? 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 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. Where can I find more documentation? See the documentation index and the markup master index pages. ## CreatingNewPages How do I create a new page? Typing [[my new page]] will create a link to the new page. There's a lot you can do with double bracket links. 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"? 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:) directive. 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. ## Links How do I create a link that will open as a new window? Use the %newwin% wikistyle, as in:  %newwin% https://example.com/ %% How do I create a link that will open a new window, and configure that new window? This requires javascript. See Cookbook:PopupWindow. How do I place a mailing address in a page? Use the mailto: markup, as in one of the following:  * mailto:myaddress@example.com * [[mailto:myaddress@example.com]] * [[mailto:myaddress@example.com | email me]] * [[mailto:myaddress@example.com?subject=Some subject | email me]]  The markup [[mailto:me@example.com?cc=someoneelse@example.com&bcc=else@example.com&subject=Pre-set Subject&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:DeObMail for information on protecting email addresses from spammers. How can I enable links to other protocols, such as nntp:, ssh:, xmpp:, etc? How do I make a WikiWord link to an external page instead of a WikiPage? Use link markup. There are two formats: [[https://example.com/ | WikiWord]] [[WikiWord -> https://example.com/]] How do I find all of the pages that link to another page (i.e., backlinks)? In the wiki search form, use link=Group.Page to find all pages linking to Group.Page. Use the link= option of the (:pagelist:) directive, as in (:pagelist link=SomePage list=all:) -- show all links to SomePage (:pagelist link={$FullName} list=all:)  -- show all links to the current page

Note that (with a few exceptions) includes, conditionals, pagelists, searchresults, wikitrails, and redirects are not evaluated for Wikilinks, and so any links they put on the page will not be found as backlinks. All other directives and markup, for example links brought to the page by (:pmform:), will be found.

What link schemes does PmWiki support?

How do I open external links in a new window or mark them with an icon?

How can I use an image as a link?

Use [[Page| Attach:image.jpg ]] or [[ https://site | https://site/image.jpg ]] See Images#links

For security reasons, most browsers will only enable file:// links if the page containing the link is itself on the local drive. In other words, most browsers do not allow links to file:// from pages that were fetched using https:// such as in a PmWiki site. See also Cookbook:DirList for a workaround.

How links to the first existed page ? for example  [[Group1.Page Group2.Page|Page]]

(:if exists Group1.Page:)
[[Group1.Page|Page]]
(:elseif exists Group2.Page:)
[[Group2.Page|Page]]
(:ifend:)

How do I make Reference links also show up on the bottom of the page like Wikipedia? Or, how do I list all links on a page?

## Images

Why are some external images correctly embedded, and others aren't?

If the current page is on a secure URL with the "https://" protocol, some browsers will refuse to load pictures from insecure URLs (the other way around is allowed). Also, some webmasters configure their servers to disallow hotlinking.

Is it possible to link an image on PmWiki without using a fully qualified URL?

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 where "Path:" replaces the server name like "https://www.example.com".

Can I attach a client image file on PmWiki?

How can I include a page from another group that contains an attached image?

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. 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? 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. 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. Yes, add to config.php: DisableMarkup('img');$ImgExtPattern = "$^";  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)? 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: [==] https://www.pmwiki.org/pub/pmwiki/pmwiki-32.gif Having [==] at the beginning of a line forces whatever follows to be part of a paragraph. Is there any way to use relative paths for images? Is there a way to attach a BMP and have it display rather than link? Add to config.php the following line: $ImgExtPattern = "(?:$ImgExtPattern|\\.bmp|\\.BMP)"; Note that BMP images are uncompressed and quite heavy. You may wish to convert them to PNG (lossless) or JPG (lossy) format, and thus reduce 5-20 times their filesizes. How do I add an image type to $ImgExtPattern and yet have it include any future default image types added in PmWiki?

You can append the extensions to the $ImgExtPattern variable this way: $ImgExtPattern = "(?:$ImgExtPattern|\\.webp|\\.WEBP)"; Is there a way to have a table to the left or right of an image? Yes, see TableAndImage. ## Uploads When I upload a file, how do I make the link look like "file.doc" instead of "Attach:file.doc Δ"? Use parentheses, as in [[(Attach:)file.doc]]. There is also a configuration change that can eliminate the Attach: -- see Cookbook:AttachLinks. Why can't I upload files of size more than 50kB to my newly installed PmWiki? 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.

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.

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.

Use the Attach page action, and click on the delta symbol (Δ) shown against each of files listed. If you can't see the attach action either uploads are not enabled, you are not authorized to upload, or the attach action has been commented out or is missing. See also available actions.

How do I hide the "Attach:" for all attachments

See Cookbook:AttachLinks, note that this does not currently work for  [[Attach:my file.ext]] .

How can I link a file that have a 4-letter file extension such like 'abc.pptx'?

How can I prevent others from using the url's of my images on their site

How can I display a file that lacks a correct extension? (e.g. you are using Cookbook:LinkIcons)

A file can be displayed by addition of a "false" extension to the URL. For example, if the url is https://example.com/dox/mydoc, add a fake query string on the end with the desired extension (e.g., https://example.com/dox/mydoc?format=.docx). If query strings are unsuitable, a fragment identifier should work, e.g. https://example.com/dox/mydoc#.docx.

## Tables

How do I create a basic table?

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).

Basic table
|| border=1 rules=rows frame=hsides
|| cell 1 || cell 2 || cell 3 ||
|| cell 1 || cell 2 || cell 3 ||

 cell 1 cell 2 cell 3 cell 1 cell 2 cell 3

How do I create cell headers?

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.

|| border=1 rules=cols frame=vsides
||! cell 1 ||! cell 2 ||! cell 3 ||
|| cell 1  ||  cell 2 ||  cell 3 ||

cell 1cell 2cell 3
cell 1cell 2cell 3

How do I obtain a table with thin lines and more distance to the content?

"Thin lines" is tricky and browser dependent, but the following works for Firefox and IE (Nov. 2009):

||border="1" style="border-collapse:collapse" cellpadding="5" width=66%
||        ||         ||             ||


How do I create an advanced table?

My tables are by default centered. When I try to use '||align=left' they don't align left as expected.

How can I specify the width of columns?

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; }  How can I display a double pipe "||" in cell text using basic table markup? Escape it with [=||=] to display || unchanged. How do I apply styles to the elements of the table, like an ID to the table row, or a class/style to the TD? See$WikiStyleApply.

Alternately, use table directives, which allow specifying styling either directly (style="...") or by a class="..." attribute for CSS.

Is there a simple way to change the table defaults? I prefer a border and I'm tired of adding it to every table.

You can set $SimpleTableDefaultClassName = 'simpletable'; and/or define your own styles in your stylesheet. The "simpletable" class is available in the core skins, and can be redefined or overridden in pub/css/local.css. ## Table directives Can I define table headers using the table directive markup? Yes, use (:head:) or (:headnr:) with PmWiki version 2.2.11 or newer. See also Cookbook:AdvancedTableDirectives. Is it possible to do nested tables? Yes, if you nest simple tables inside advanced tables. See also Cookbook:AdvancedTableDirectives. Is it possible to add background images to tables and table cells? Yes, see Cookbook:BackgroundImages. Is it possible to apply styles to the elements of the table, like an ID to the table row, or a class/style to the TD? Yes, see$WikiStyleApply.

Is it possible to automatically generate columns or rows in tables, i.e. without having to do a lot of counting?

Yes, this is possible with the Cookbook:CreateColumns recipe - it allows you to specify a certain number of columns, and/or to specify a certain number of items per column. Plus, someone has provided some similar markup on the TableDirectives-Talk page.

Is it possible to use table captions in table directives similar to simple tables? Tried  ! Captiontext !  and  (:caption:) . Didn#t work. How to do?

Yes, this is possible with the Cookbook:AdvancedTableDirectives recipe - There you will find a (:caption:) directive.

## AccessKeys

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

## PageDirectives

Can I get (:redirect:) to return a "moved permanently" (HTTP 301) status code?

Use (:redirect PageName status=301:).

Is there any way to prevent the "redirected from" message from showing at the top of the target page when I use (:redirect:)?

From version 2.2.1 on, set in config.php $EnableRedirectQuiet=1; and in the page (:redirect OtherPage quiet=1:) for a quiet redirect. 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}:)? (: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. How can a wiki enable linebreaks by default, i.e. without having the directive (:linebreaks:) in a page or in a GroupHeader? Add to config.php such a line: $HTMLPNewline = '<br/>';

## IncludeOtherPages

What's the maximum number of includes that can exist in a page?

My site seems to stop including after 48 includes. ($MaxIncludes) 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.

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-* ?

This can be achieved using page lists.

There appears to be a viewing issue when the included page contains the (:title:) directive.

In a default installation, the last title in the page overrides previous ones so you can place your (:title :) directive at the bottom of the page, after any includes. See also $EnablePageTitlePriority. How to test to see if the page is part of another page?  (:if ! name {PmWiki.IncludeOtherPages$FullName}:) %comment% name of this page is not the same as the page this text was sourced from ->[[{PmWiki.IncludeOtherPages$FullName}#anchor | more ...]] (:ifend:)  name of this page is not the same as the page this text was sourced from Is there any way to include (chapters of) pages which are protected (authuser.php)? You can achieve this the other way around: have the public sections in a public page (passwdread=@nopass or @_site_read) and include those into both the protected page, and the public page. Note that it is strongly recommended to NOT hide sensitive content inside a conditional in an unprotected page. ## InterMap Are InterMap names case sensitive? Yes, thus eAdmin: is a different InterMap link than EAdmin:. How can I achieve a localmap.txt mapping with the effect of Pics: Path:/somepathto/pics/? Use the following: Pics: /somepathto/pics/ How can I define an InterMap in PHP? Use the following: $LinkFunctions['PmWikiHome:'] = 'LinkIMap';
$IMap['PmWikiHome:'] = 'https://pmwiki.org/wiki/$1';


How can I define an InterMap link that lets me refer to files at the server "root"?

From the page https://example.org/index.php/Main/HomePage I want to create a relative link to a directory at the "root" level of the site. The fully qualified URL is https://example.org/commoninfo/infoaboutu.php. I want to do this because the domain name will change, which would break an absolute link.

Create an InterMap link like so:
 Root    /

 Root:commoninfo/infoaboutu.php


Or, you can use the predefined "Path:" prefix, as in Path:/commoninfo/infoaboutu.php.

## Page specific variables

Is there a variable like $LastModified, but which shows me the creation time? No, but you can create one in config.php. For instance: # add page variable [={$PageCreationDate}=] in format yyyy-mm-dd
$FmtPV['$PageCreationDate'] = '[[PmWiki/Functions#PSFT|PSFT]]("[=%Y-%m-%d=]", $page["ctime"])'; If you like the same format that you define in config.php with $TimeFmt use
$FmtPV['$Created'] = "[[PmWiki/Functions#PSFT|PSFT]](\$GLOBALS['TimeFmt'], \$page['ctime'])";

How can I test if a variable is set and/or not empty?

Use [=(:if ! equal "{$Variable}" "":)$Variable is not empty. (:ifend:)=]. Note that undefined/inexistent variables appear as empty ones.

Categories:

## FAQ

How can I get rid of the 'Main' group in urls for pages pointing to Main?

How can I limit the creation of new groups?

Why doesn't [[St. Giles and St. James]] work as a link? (It doesn't display anything.)

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 in US grammar the period is often omitted and in UK grammar the period must be omitted for contractions like St).

How can I delete a wiki group?

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.

How can I delete a wiki group's Group.RecentChanges page?

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.

Can I delete a wiki group inside wiki.d folder on the server to eliminate the group?

Yes, if you delete all files named YourGroup.*, the pages from that group will be removed from the wiki. Note that the documentation (group PmWiki) and the site configuration (groups Site and SiteAdmin) that exist in the default installation, are located in wikilib.d and not in wiki.d, and some recipes provide files located in a wikilib.d subdirectory in the cookbook directory. (You shouldn't delete the groups Site and SiteAdmin, they are required for normal function.)

How can I list all pages in a WikiGroup?

In a wiki page use (:pagelist group=GroupName list=all:) or in a search box type GroupName/ list=all.

How do I set the same header or footer for all pages/groups?

The header and footer for each page are controlled by the variables $GroupHeaderFmt and $GroupFooterFmt. If your site-wide header and footer pages are Site.SiteHeader and Site.SiteFooter, you can add this in config.php:

### If you use Site.SiteHeader and Group.GroupHeader
$GroupHeaderFmt = '(:include {$SiteGroup}.SiteHeader'
. ' basepage={*$FullName}:)(:nl:)' .$GroupHeaderFmt;

$GroupHeaderFmt = '(:include {$SiteGroup}.SiteHeader'
. ' basepage={*$FullName}:)(:nl:)'; ### If you use Site.SiteFooter and Group.GroupFooter$GroupFooterFmt .= '(:nl:)(:include {$SiteGroup}.SiteFooter' . ' basepage={*$FullName}:)';

### If you use Site.SiteFooter instead of Group.GroupFooter
$GroupFooterFmt = '(:nl:)(:include {$SiteGroup}.SiteFooter'
. ' basepage={*$FullName}:)';  Note that single quotes must be used in the lines above. See also the Cookbook:AllGroupHeader recipe. Instead of using an additional page, you could set any wiki text in $GroupHeaderFmt, for example:

$GroupHeaderFmt .= "Global message here."; ## WikiTrails What's the difference between a PageList and a WikiTrail? 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 web feeds, for creating a "tour" through a predefined set of pages, and many other things. ## PageHistory Is there a way to remove page history from page files? 1. Administrators can clean page histories using the Cookbook:ExpireDiff recipe. 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 PageFileFormat#creating. 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. How can I restrict viewing the page history (?action=diff) to people with edit permission? 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'; ## Passwords 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? 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'] = pmcrypt('edit_password');

I get http error 500 "Internal Server Error" when I try to log in. What's wrong?

This can happen if the encrypted passwords are not created on the web server that hosts the PmWiki.
The PHP 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.

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?

Modify the edit attribute for each group to id:username, e.g. set the edit attribute in JaneDoe.GroupAttributes to id:JaneDoe.

There is a more automatic solution, but it's probably not a good idea for most wikis. Administrators can use the 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. Unfortunately it also gives edit rights to such a user who is visiting a same-named group not just for pages in that group, but for any page on the wiki that relies on the site's default edit password. This can create security holes.

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.
For security considerations about shared session pools, see the "Session injection" chapter in Cookbook:SessionSecurityAdvice.
To fix the browser-side convenience issue, one easy way is to make sure each wiki uses 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' session cookies independent of each other.

Is it possible to test the password level for display and/or if condition? Example: * (:if WriterPassword:) (display Edit link) (:ifend:)

You can use (:if auth edit:). See ConditionalMarkup.

Can I use (:if …:) to hide secrets in a wiki page?

You can, but usually that's not secure. The recommended strategy is to put secrets in a separate page and restrict all read-related¹ access permissions to those users who are allowed to read the secrets. To display the secrets in another page, you can include (parts of) the secrets page: Users with read access to the secrets will readily see them, whereas other users see nothing or (at your choosing) some other text, e.g. a login link.

¹ Currently (version 2.2.99), these are: read (would allow include), edit (would show the source), attr (would allow to obtain read/edit), diff (would allow viewing any change), source (allows raw source display)

The reason why Conditional Markup isn't suitable for access control is that it only applies for rendering wikitext as a web page, and that's just one of many ways to access a page's text. In order to rely on Conditional Markup for protection of secrets, you'd have to restrict all access methods that can circumvent it. To do so, you'd need to keep track of all methods available. In a default installation of PmWiki, some of the easy methods include: Editing a page, viewing its edit history, its source, or including fragments of it into the edit preview of another page. (Preview: To avoid traces in RecentChanges.) However, this list is far from exhaustive, and could easily grow with Recipes? or future versions of PmWiki.

## PageLists

• 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!)
• 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).
• fmt=#simplename - Simple bullet list of page names, without the Group name.
• fmt=#simplenamespaced - Simple bullet list of spaced page names, without the Group name.
• fmt=#titlesummary - A simple bullet list of page title and summary, defined in page by (:title ttttt:) and (:Summary:sssss:) markup.

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 "#"). In a trail, fmt=count counts existing and non-existing pages ; to limit count to existing pages, use : if="exists {=$FullName}" fmt=count . ### link= and category= The "link=" and "category=" arguments implement "backlinks" -- i.e., it returns a list of pages with a link to the target, or declared in the category. It's especially useful for category pages and finding related pages. The category=Name argument differs from link=Category.Name as it only lists pages declared in the category with the markup [[!Name]], and does not include pages simply linking to [[Category/Name]] (unless they also contain [[!Name]]). • 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 category=Skins:)

Since PmWiki 2.3.0, link= and category= accept multiple and negative targets and wildcard lists, see the section Wildcards.

Note, link= and category= will ignore the directives (:if...:), (:include...:), (:redirect...:), (:pagelist...:), and page text variable directives, while searching for links in a page. That means links in included pages will not be found, and links inside non-displayed conditional markup will be found. See PageTextVariables for ways to hide a link on a page while still allowing link= to find it.

Note: The new category= argument requires all pages containing [[!Category]] links to be reindexed. See the recipe Cookbook:ReindexCategories which can automate this.

### 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
 A simple bullet list of ten most recently modified pages (:pagelist trail=Site.AllRecentChanges count=10 fmt=#simple:) Display the first ten pages of a list count=10 # display the first ten pages of list Negative numbers specify pages to be displayed from the end of the list: count=-10 # display last ten pages of list Ranges may be specified using '..', thus: count=1..10 # first ten pages of list count=5..10 # 5th through 10th pages of list Negative numbers in ranges count from the end of the list: count=-10..-5 # 10th from end, 9th from end, ..., 5th from end Omitting the start or end of the range uses the start or end of the list: 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 Ranges can be reversed, indicating that the order of pages in the output should likewise be reversed: 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 "Reverse sequence" here refers to the sequence after any sorting has taken place. Therefore the three directives to the right are equivalent: (:pagelist order=-name count=10:) (:pagelist order=-name count=1..10:) (:pagelist order=name count=-1..-10:) 

### 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>...

### request=

With (:pagelist [other parameters] request=1:)  you can override most pagelist parameters, by providing request parameters in the URL. For example,  (:pagelist order=name request=1:)  will normally sort the list by name. But if the page's URL contains ?order=time, the list will be sorted by time. If the URL contains ?order=, the list will be unordered. Note: In the URL, encode any "#"s that are in your parameters as "%23". Since this parameter gives users who don't have edit rights the ability to run a pagelist of their choosing, consider its security implications for your website before using it.

Since version 2.2.71, it is possible to explicitly allow only certain parameters that can be overridden, or to disallow some parameters to be overridden. If you need this, instead of 1, enter the parameter names.

Allow all parameters to be overridden:
(:pagelist request=1:)

Allow only 'order' and 'count' parameters to be overridden:
(:pagelist request=order,count:)

Allow all parameters to be overridden, except 'fmt' and 'trail', note the "minus" sign before each forbidden parameter:
(:pagelist request=-fmt,-trail:)


### req=1

The req=1 parameter requires that search terms be posted (that is, that the user presses "search" on a search form, or follows a link with additional parameters like [[Page?q=terms&order=-name]]) before the pagelist is executed. Note that (:pagelist request=1 req=1:) works mostly like (:searchresults:) without the lines "Results of search for ..." and "X pages found out of Y pages searched". Both "request=1" and "req=1" are needed.

When a search is performed, either via a searchbox directive, or via the search form of the skin, if the page contains a "searchresults" directive, that page will be used to display the results of the search; if the page doesn't have a "searchresults" directive, the page Site.Search will be used to display the results.

### passwd=

The "passwd" option returns only those pages that have some sort of password attribute on them.

### if=

The "if" option allows a condition to be specified as part of the pagelist processing, rather than from within the page list template. Only those pages for which the condition is true are retrieved. Anything that could 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.

If any arguments within the quotes could contain a space they must be quoted:

  (:pagelist if="date 2009-01-01..2009-12-31 '{=$:Mydate}'" :)  ### 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 custom pagelist sort order: • order=name - alphabetically by name (default order) • order=$Name - alphabetically by name across groups
• order=title - alphabetically by title rather than names
• order=time - most recently changed pages last
• order=ctime - time of page creation (see note)
• 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 page text variable value (note no braces) • order=$pagevarname - alphabetically by page variable value (note no braces)

Also, the order= option allows custom ordering functions to be written.

• Note: trail= preserves the order of the pages as they appear on the trail (unless you've specified order= explicitly or there is a default order in the page list template). So PmWiki's alphabetical default order does not apply when trail= is specified.
• 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.

### cache=0

Pagelist has the capability to cache lists which greatly speeds up processing (when $PageListCacheDir is set). Every once in a while this caching can result in undesired results. Specifying cache=0 disables caching. #### 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 format: (:pagelist fmt=#pagelist variable1="value" variable2="value2":) This assumes that a site has $EnableRelativePageVars enabled (default since 2.2.9).

For example, in the template:

 >>comment<< [[#tvars]] (:template default count=1 ParamName=Simon:) Hi, , how are you today? [[#tvarsend]] >><<  (:template default count=1 ParamName=Simon:) Hi, , how are you today?

This gives:

 (:pagelist fmt=#tvars ParamName="Sam":) (:pagelist fmt=#tvars ParamName="Sally":) (:pagelist fmt=#tvars:) 

See also $EnableUndefinedTemplateVars. ## 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:) ## The Searchbox Directive The (:searchbox:) directive generally accepts the same parameters as (:pagelist:) and (:input search:) 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 default placeholder value is "Search" (localized in other languages), and can be modified in the form placeholder="Type search terms..." or removed with placeholder="". In recent browsers, this value appears gray in the search field when it is empty. • Optionally, you can add aria-label and other aria-* accessibility attributes that will be attached to the input text field. • 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.

The additional parameter label="Label" can be used to change the label of the associated submit button:

 (:searchbox label="Search this wiki":)


Use label="" to remove the submit button (users need to press "Enter" to search).

By default, the input field has the "text" type for compatibility with HTML/XHTML. Alternatively, you can set it to the "search" input type for HTML5, see $SearchBoxInputType (some HTML5 skins already set this). ## The Searchresults directive The (:searchresults:) directive generally accepts the same parameters as (:pagelist:) and (:input search:) directives. ### Customizing "Results of search for..." and "3 pages found out of..." To change the text surrounding the search results, customize the following and add it to local/config.php or $FarmD/local/farmconfig.php. Note that 'en' should be changed to the localized language.

XLSDV('en', array(
'SearchFor' => 'Results of search for <em>$Needle</em>:', 'SearchFound' => '$MatchCount pages found out of $MatchSearched pages searched.' )); Alternatively, adjust the 'SearchFor' and 'SearchFound' phrases in your translation pages. The $SearchResultsFmt variable can also be set in local/config.php or $FarmD/local/farmconfig.php. SDV($SearchResultsFmt, "<div class='wikisearch'>\$[SearchFor] <div class='vspace'></div>\$MatchList
<div class='vspace'></div>\$[SearchFound]</div>"); You can remove the lines above and below the generated list by adding this in config.php: $SearchResultsFmt = '$MatchList'; ## See Also ## FAQ How PmWiki opens pages with PageStore? When PmWiki needs to open a file for reading, it will ask the PageStore, objects one after another, in the order you have defined them in config.php, if they have MyGroup.MyPage. The first PageStore object that finds this page will return it and if there are more PageStores they will be not bothered. When you define a PageStore object with paths like wiki.d/{$Group}/{$FullName} and then ask "is there a page MyGroup.MyPage", the PageStore only checks "is there a file wiki.d/MyGroup/MyGroup.MyPage" so it will only look in the wiki.d/MyGroup sub-directory, not in other subdirectories. When you write a page, only the first PageStore object is used, that is usually $WikiDir. This way we can have documentation in wikilib.d but if you modify a page from the PmWiki or Site groups on your wiki, it will be saved in wiki.d and from now on only the file in wiki.d will be read and written.

What is the behavior of pagelist and searchresults when only name or word is provided?

Both pagelist and searchresults are searching for all groups unless either (there is a group=ThisGroup argument in the markup or in the search field), or (you have (:template default group=SomeGroup,{*$Group}:) in the pagelist template), or (there is a request=1 argument in the markup and there is somehow a $_REQUEST['group'] variable, eg from a search form or from the url), or (you set some $SearchPatterns['xy'] and list=xy), or (set a default $MakePageListOpt['group'] or $SearchBoxOpt['group']). If one option is not used, then this option should not be predefined. If there is no needle show all pages; if group= is not used show all groups; if name= is not used show all names; if link= is not used show pages linking or not linking to anywhere; if count= is not used show all pages instead of a portion of them. (The only exception is the order= option which defaults to order=name because without it the results may be ordered inconsistently between page reloads, especially bad if you also use count=21..30.) How can a custom function retrieve the results of a pagelist as an array? ## DeletingPages How is a Wiki Group deleted? An admin can remove the group pages from wiki.d/. Note that a wiki page may also have related uploads. Fully deleting a group via the wiki isn't possible, since a delete counts as an "update" which causes the Recent Changes? page to be re-created. It is possible to modify the site's configuration to allow deletion of the group's RecentChanges page -- see Cookbook:RecentChangesDeletion. How is a Category deleted? To delete a category, delete all the [[!Category]] references from all pages where they occur, then delete the category page as explained above. ## PmWiki Installation Should I rename pmwiki.php to index.php? Renaming pmwiki.php is not recommended. Instead, create an index.php file that contains this single line <?php include_once('pmwiki.php'); How do I make pmwiki.php the default page for a website? 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 "https://example.com/pmwiki/pub") in local/config.php .

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?

How can I run PmWiki on a standalone (offline, portable) machine ?

How can I determine what version of PmWiki I'm running now?

See version - Determining and displaying the current version of PmWiki (pmwiki-2.3.21).

How can I test a new version of PmWiki on my wiki without changing the prior version used by visitors?

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).

Here's an example of what to add to your local/config.php file to disable uploading of .zip files, or of files with no extension:

$UploadExtSize['zip'] = 0; # Disallow uploading .zip files$UploadExtSize[''] = 0;     # Disallow files with no extension

How do I attach uploads to individual pages or the entire site, instead of organizing them by wiki group?

Use the $UploadPrefixFmt variable (see also the Cookbook:UploadGroups recipe). $UploadPrefixFmt = '/$FullName'; # per-page, in Group.Name directories$UploadPrefixFmt = '/$Group/$Name'; # per-page, in Group directories with Name subdirectories
$UploadPrefixFmt = ''; # site-wide 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?

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 Is there a way to allow file names with Unicode or additional characters? Yes, see $UploadNameChars

Where is the list of attachments stored?

It is generated on the fly by the

markup.

Downloading binary files such as pictures or ZIP archives with $EnableDirectDownload=0; sometimes results in corrupted files, why? Some recipe or local configuration may output something before the file. This may happen if you have PHP files with a closing "?>" marker at the end, and some text or white space after it. It is recommended to remove these closing markers from your local and cookbook files. Alternatively, there may be some PHP warning or message before the file data. On Unix-like systems you can peek into the file with the command less -f -L file.ext and see the first few characters or lines. See Troubleshooting on how to track the source for the errors/warnings. ## Security How do I report a possible security vulnerability of PmWiki? Pm wrote about this in a post to pmwiki-users from September 2006. In a nutshell he differentiates two cases: 1. The possible vulnerability isn't already known publicly: In this case please contact us by private mail. 2. The possible vulnerability is already known publicly: In this case feel free to discuss the vulnerability in public (e.g. on pmwiki-users or in the PITS). See his post mentioned above for details and rationals. What about the botnet security advisory at https://isc.sans.edu/diary/Reports+of+Bots+exploiting+pmwiki+and+tikiwiki/1672? 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. ## Wiki Vandalism and Assumptions you are using a Blocklist and Url approvals. You don't want to resort to password protecting the entire wiki, that's not the point after all. Ideally these protections will be invoked in config.php How do I stop pages being deleted, eg password protect a page from deletion? Use Cookbook:DeleteAction and password protect the page deletion action 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.

How do I stop pages being replaced with an empty (all spaces) page?

Add block: /^\s*$/ to your blocklist. how do I stop pages being completely replaced by an inane comment such as excellent site, great information, where the content cannot be blocked? Try using the newer automatic blocklists that pull information and IP addresses about known wiki defacers. (OR) Try using Cookbook:Captchas or Cookbook:Captcha (note these are different). (OR) Set an edit password, but make it publicly available on the Site.AuthForm template. How do I password protect the creation of new groups? How do I password protect the creation of new pages? How do I take a whitelist approach where users from known or trusted IP addresses can edit, and others require a password? 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'] = pmcrypt('foobar'); }


Replace 90.68. with the preferred network prefix and foobar with the default password for others.

For a single IP, you may use

if($_SERVER['REMOTE_ADDR'] == '127.0.0.1') { # your IP address here$_POST['authpw'] = 'xxx';                  # the admin password
}


Please note the security issues: this means that you have your admin passwords in clear in config.php and someone with access to the filesystem can read them (for example a technician of your hosting provider); your IP address may change from time to time (unless you have a fixed IP contract with your ISP). When that happens, someone with your old IP address will be logged in automatically as admin on your wiki. It is extremely unlikely to become a problem, but you should know it is possible; if you are behind a router, all other devices which pass through that router will have the same IP address for PmWiki - your wifi phone, your wife's netbook, a neighbour using your wifi connection, etc. All these people become admins of your wiki. Again, you should evaluate if this is a security risk; In some cases, your ISP will route your traffic through the same proxy as other people. In such a case, thousands of people may have the same IP address.

How do I password protect page actions?

See Passwords for setting in config.php

$HandleAuth['pageactionname'] = 'pageactionname'; # along with : $DefaultPasswords['pageactionname'] = pmcrypt('secret phrase');

or

$HandleAuth['pageactionname'] = 'anotherpageactionname'; How do I moderate all postings? Enable PmWiki.Drafts How do I make a read only wiki? In config.php set an "edit" password. How do I restrict access to uploaded attachments? See How do I hide the IP addresses in the "diff" pages? If the user fills an author name, the IP address is not displayed. To require an author name, set in config.php such a line:  $EnablePostAuthorRequired = 1;


The IP address can also be seen in a tooltip title when the mouse cursor is over the author name. To disable the tooltip, set in config.php:

$DiffStartFmt = "<div class='diffbox'><div class='difftime'><a name='diff\$DiffGMT' href='#diff\$DiffGMT'>\$DiffTime</a>
\$[by] <span class='diffauthor'>\$DiffAuthor</span> - \$DiffChangeSum</div>";  How do I stop some Apache installations executing a file which has ".php", ".pl" or ".cgi" anywhere in the filename How do I stop random people from viewing the ?action=source (wiki markup) of my pages? I have (:if auth edit:) text that I don't want the world to see. $HandleAuth['source'] = 'edit'; or $HandleAuth['source'] = 'admin'; How to I secure my cookies? How do I set a global password to resist spambots, and informed humans of the password? ## CustomMarkup How can I embed JavaScript into a page's output? 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 JavaScript-Editable recipe. For JavaScript that is to appear in headers or footers of pages, the skin template can be modified directly, or <script> statements can be inserted using the $HTMLHeaderFmt array.

How would I create a markup ((:nodiscussion:)) that will set a page variable ({$HideDiscussion}) which can be used by (:if enabled HideDiscussion:) in .PageActions? Add the following section of code to your config.php SDV($HideDiscussion, 0); 	#define var name
Markup('hideDiscussion', '<{$var}', '/\$$:nodiscussion:\$$/', 'setHideDiscussion'); function setHideDiscussion() { global$HideDiscussion;
$HideDiscussion = true; }  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"]'; 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. 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). Also make sure your markup is executed during the fulltext phase.

How can the text returned by my markup function be re-processed by the markup engine?

If the result of your markup contains more markup that should be processed, you have two options. First is to select a "when" argument that is processed earlier than the markup in your result. For example, if your markup may return [[links]], your "when" argument could be "<links" and your markup will be processed before the links markup. The second option is to call the PRR() function in your markup definition or inside your markup function. In this case, after your markup is processed, PmWiki will restart all markups from the beginning.

How do I get started writing recipes and creating my own custom markup?

How do I make a rule that runs once at the end of all other rule processing?

Use this statement instead of the usual Markup() call:

$MarkupFrameBase['posteval']['myfooter'] = "\$out = onetimerule(\$out);"; Category: ## CustomWikiStyles I tried this but background didn't work, though border and float worked? $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.

How would I set an image to the left of a paragraph in a WikiStyle? I'd like to provide an icon for paragraphs that are notes, important, warnings, etc.

See WikiStylesPlus and Callout.

How can I remove underlining from a link, but make it underlined blue when the mouse hovers?

Put in pub/css/local.css:

.noul a {text-decoration: none;}
.noul a:hover {text-decoration: underline; color: blue;}

Then use this markup:

  %noul% [[Link]] %%


## Internationalizations

If my wiki is internationalized by config.php, how do I revert a specific group to English?

Use $XLLangs = array('en'); in the group's group customization file. 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? 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');

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. What does the first parameter of this function stand for? How can it be used? 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-ca', 'PmWikiFrCa.XLPage'); XLPage('fr', 'PmWikiFr.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(). How can I add a translation for an individual string in a PHP file? Use the XLSDV() function to provide a translation for a specific (English) string. For instance, with this in config.php XLSDV('nl', array('my English expression'=>'mijn Nederlandse uitdrukking')); any instance of the variable expression $[my English expression] in wiki mark-up will be displayed as my English expression in default (English) context, but as mijn Nederlandse uitdrukking in Dutch (nl) context, i.e. when XLPage('nl',...) has been called for that page in config.php or a cookbook recipe.

If you need to get a translation in a PHP file, use the XL() function:

$local_string = XL("my English expression"); But beware: XLPage() uses XLSDV() internally for its translation pairs, too, and only the first definition is accepted! Thus, if the Dutch XLPage already contains a translation and you want to override that, you need to use your XLSDV('nl',...) before calling the correspondent XLPage('nl',...). Otherwise, by using XLSDV() after XLPage() - e.g. within a recipe that is included later in config.php - your translation will only work as long nobody defines 'my English expression' in that XLPage. ## LocalCustomizations There's no "config.php"; it's not even clear what a "local customisation file" is! 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 Group Customizations. Can I change the default page something other than Main.HomePage ($DefaultPage)?

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';

Note the recommendations in $DefaultName and the need to set $PagePathFmt as well if you are changing the default startup page for groups.

How do I get the group / page name in a local configuration file (e.g. local/config.php)?

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');  Note the importance of the order of customizations in config.php above to avoid caching problems. If you need the verbatim group and page name (from the request) early in config.php, $pagename is guaranteed to be set to

1. Any value of ?n= if it's set, or
2. Any value of ?pagename= if it's set, or
3. The "path info" information from REQUEST_URI (whatever follows SCRIPT_NAME), or
4. Blank otherwise

according to this posting

Can I remove items from the wikilib.d folder on my site?

The files named Site.* and SiteAdmin.* contain parts of the interface and the configuration and they should not be removed. The other files named PmWiki* contain the documentation and could be removed.

How do I customize my own 404 error page for non-existent pages?

To change the text of the message, try editing the Site.PageNotFound page.

Is the order of customizations in config.php important? Are there certain things that should come before or after others in that file?

I have an online hosted wiki, and a local copy on my home computer. How can I differentiate in config.php whether I'm online or on the local computer? So that I don't have to maintain the config.php twice.

You can try something like the following:

if($_SERVER['SERVER_ADDR'] == '127.0.0.1') { # Home wiki } else { # Online wiki } You can add $EnableDiag = 1; to config.php for both servers, and look at ?action=diag.

The $_SERVER variable will have different values on the different servers, notably 'SERVER_ADDR' or 'SERVER_NAME'. You can configure the different wikis based on the different values. ## GroupCustomizations How can I apply CSS styles to a particular group or page? Simply create a pub/css/Group.css or pub/css/Group.Page.css file containing the custom CSS styles for that group or page. See also Cookbook:LocalCSS. Why shouldn't passwords be set in group (or page) customization files? Why shouldn't group or page passwords be set in config.php? 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.

Isn't that processing order strange? Why not load per page configuration last (that is after global configuration an per group configuration)?

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 above (using include_once() or setting $EnablePGCust = 0;). ## Skins How do I change the Wiki's default name in the upper left corner of the Main Page? Put the following config.php $WikiTitle = 'My Wiki Site';

The docs/sample-config.php file has an example of changing the title.

How can I embed PmWiki pages inside a web page?

Source them through a PHP page, or place them in a frame.

How do I change the font or background color of the hints block on the Edit Page?

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.

## SkinTemplates

How do I customize the CSS styling of my PmWiki layout?

See Skins for how to change the default PmWiki skin. See also 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; }'; Where can the mentioned "translation table" be found for adding translated phrases? Is it possible to have the edit form in full page width, with no sidebar? If the sidebar is marked with <!--PageLeftFmt-->, adding (:noleft:) to Site.EditForm will hide it when a page is edited. Can I easily hide the Home Page title from the homepage? Yes, you can use in the wiki page either (:title Some other title:) to change it or (:notitle:) to hide it. Is it possible to hide the Search-Bar in the default PmWiki Skin? Yes, please see Cookbook:HideSearchBar. ## WebFeeds 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';

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 How can I use the RSS <enclosure> tag for podcasting? 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.

How to add "summary" to the title in a rss feed (ie. with ?action=rss)?

Add this line in your local/config.php

$FeedFmt['rss']['item']['title'] = '{$Group} / {$Title} :$LastModifiedSummary';

How to add "description" to the title in an rss feed, and summary to the body?

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. Some of my password-protected pages aren't appearing in the feed... how do I work around this? 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. How to add feed image? Add the following to local/config.php (this example is for ?action=rss): $FeedFmt['rss']['feed']['image'] =
" <title>Logo title</title>
<url>https://example.com/images/logo.gif</url>
<width>120</width>
<height>60</height>";

Do not forget NOT to start with a '<' as there would be no <image> tag around this... See here.

How do I insert RSS news feeds into PmWiki pages?

How can I specify default feed options in a configuration file instead of always placing them in the url?

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 file:

   if ($action == 'rss') SDVA($_REQUEST, array(
'group' => 'News',
'order' => '-time',
'count' => 10));


Are there ways to let people easily subscribe to a feed?

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]]. Can I create an RSS feed for individual page histories? How do I create a custom FeedPage similar to RecentChanges or AllRecentChanges, but with only certain groups or pages recorded? See Cookbook:CustomRecentChanges. In a nutshell, you'll declare a $RecentChangesFmt variable with your dedicated FeedPage, and then wrap it in a condition of your choice. For example:

   if (PageVar($pagename, '$Group')!='ForbiddenGroup') {
$RecentChangesFmt['Site.MyFeedPage'] = '* [[{$FullName}]]  . . . $CurrentTime$[by] $AuthorLink: [=$ChangeSummary=]';
}


How can I update my RSS feed to show every edit for pages on that feed, not just new pages added to the feed?

   $FeedFmt['rss']['item']['guid'] = '{$PageUrl}?guid=$ItemISOTime';  Alternatively, you can create the option for edit monitoring by adding a qualifier for RSS links. This allows the user to choose between default new pages RSS feeds and new edits RSS feeds (pmwiki.org has this option enabled).  ## For new pages updates: https://example.com/wiki/HomePage?action=rss ## For edits updates: https://example.com/wiki/HomePage?action=rss&edits=1 if(@$_REQUEST['edits'] && $action == 'rss')$FeedFmt['rss']['item']['guid'] = '{$PageUrl}?guid=$ItemISOTime';


## AuthUser

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

Yes -- put the group definition into the $AuthUser array (in config.php): $AuthUser['@editors'] = array('alice', 'carol', 'bob');

Can I have multiple admin groups?

Yes, define the groups with  array('@admins', '@moderators');  like this:

$DefaultPasswords['admin'] = array( pmcrypt('masterpass'), # global password '@admins', '@moderators', # +users in these groups 'id:Fred', 'id:Barney'); # +users Fred and Barney 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? This is caused by the way that PHP treats sessions. See PmWiki.AuthUser#sessions for more details. 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. Though every setting seems correct, authentication against LDAP is not working. There is nothing in ldap log, what's wrong? Be sure ldap php module is installed ( on debian apt-get install php(4|5)-ldap ; apache(2)ctl graceful ) 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. 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. 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'] = pmcrypt('secret');
$DefaultPasswords['admin'] = 'id:carol';  A username and password will then be required before login is successful. 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 Yes, see solution provided at PITS:00400. Is there a way that people could self-register through AuthUser? You can see HtpasswdForm or UserAdmin for recipes providing this feature. 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? How to allow a group or a page for reading or editing, only to signed-in users? You can set the password fields to id:*. Navigate to Group.Page?action=attr (for a single page) or to Group.GroupAttributes?action=attr (for the whole group) and fill the fields "New read password" and "New edit password" with id:* then save the form. ## PasswordsAdmin There seems to be a default password. What is it? 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 pmcrypt() function to ever return a 1-character encrypted value, the admin password is effectively locked until the admin sets one in config.php.

How do I use passwd-formatted files (like .htpasswd) for authentication?

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?

Enter '@lock' in GroupAttributes?action=attr to require an admin password for that group.

How do I edit protect, say, all RecentChanges pages?

How can I read password protect all pages in a group except the HomePage using configuration files?

As described in PmWiki.GroupCustomizations 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. How can I password protect the creation of new pages? How do I change the password prompt screen? 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. How do I change the prompt on the attributes (?action=attr) screen? Simply create a new page at Site.AttrForm?, and add the following line of code to config.php: $PageAttrFmt = 'page:Site.AttrForm';

Note that this only changes the text above the password inputs on the attributes page, but doesn't change the inputs themselves - the inputs have to be dealt with separately. See Cookbook:CustomAttrForm for more info.

I get http error 500 "Internal Server Error" when I try to log in. What's wrong?

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.

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?

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
}

## DesignNotes

Why doesn't PmWiki use hierarchical / nested groups?

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.

Why don't PmWiki's scripts have a closing ?> tag?

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 Instruction separation page in the PHP manual.

Does PmWiki support WYSIWYG editing (or something like the FCKEditor)?

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. See also Cookbook:Worse and Cookbook:PmSyntax.

Categories: