ExtensionHub

Summary: Configuration panel for extensions
Version: 2025-11-16
Prerequisites: PmWiki 2.3.31+, PHP 7.0+
Status: Experimental
Maintainer: Petko
License: GPL
Users: +1 (view / edit)
Discussion: ExtensionHub-Talk

Configuration panel for PmWiki extensions (recipes/modules).

This page is a work in progress. Having a few very busy weeks, I'll work on this as time permits. I'll send a message to pmwiki-users when ready. --Petko

Description

Introducing a new family of PmWiki recipes that are easy to install, configure, and maintain.

Extensions

Easy installation:

  • Extensions are placed in the pmwiki/extensions directory.
  • They can be uncompressed, or even left as zip-compressed archives.
  • They can be checked out or pulled from public version control repository, for easy updates.

Easy configuration:

  • There is no need to edit config.php and other local files.
  • The Hub (the page SiteAdmin.ExtensionHub on your own wiki) lists all available extensions and allows to enable and configure them.
  • The wiki administrator can enable, disable, and edit extension configurations.
  • Extensions can have different configurations for different page name patterns. This is more flexible than the local/Group.php and local/Group.Page.php customizations.

And, helper functions for extension authors (see ExtensionDesign).

Hub

The SiteAdmin.ExtensionHub is a configuration panel for extensions. It shows a table with all available extensions, and allows to enable/disable and configure these.

The Hub manages configuration settings for each extension, enables or disables the extension based on the page patterns defined by the wiki admin, and with the priority/actions defined by the developer.

Installation and updates (Hub)

This requires:

  • PmWiki version 2.3.31 or more recent.
  • PHP 7.0 or more recent on the server.

On a wiki farm, you only install the Hub and all extensions once. You can enable the Hub from farmconfig.php, but individual extensions are enabled and configured per field.

Manually

Install:
  1. Unzip extensions-2025-11-16.zip then rename the directory to just "extensions".
  2. Place the directory "extensions" on your server in your $FarmD directory (as a sibling to the "scripts" directory, in the same directory where pmwiki.php is located).
  3. In config.php or farmconfig.php, add the following line near the top of the file:
    include_once("$FarmD/extensions/hub.php");
    This line should be added after including scripts/xlpage-utf-8.php, but before including scripts/authuser.php (if you include it).

Update an existing Hub installation:

  1. Review the Release notes for changes.
  2. Get the archive extensions-2025-11-16.zip.
  3. On the wiki, replace the file pmwiki/extensions/hub.php with the one from the archive.

From the GitHub repo

Install:
  1. In your pmwiki directory, clone the repo:
    git clone https://github.com/5ko/extensions.git
  2. In config.php or farmconfig.php, add the following line near the top of the file:
    include_once("$FarmD/extensions/hub.php");
    This line should be added after including scripts/xlpage-utf-8.php, but before including scripts/authuser.php (if you include it).

Update an existing installation:

  1. Review the Release notes for changes.
  2. From inside your pmwiki/extensions directory, call:
    git pull

Configuration (Hub)

If you have a farm, you need to correctly configure $FarmPubDirUrl (you probably already have).

If for some reason the Hub cannot correctly detect your public extensions path, you can set to config.php such a line:

$ExtPubDirUrl = 'https://www.example.com/extensions';

This is the public browser-reachable path to the /extensions directory.

Internationalization

The following strings can be translated in an XLPage:

To do.

Usage (Extension configuration)

PmWiki extensions are recipes with a specific structure, designed to work with the Hub. You can find compatible extensions at Cookbook:Extensions.

There are 3 ways to install an extension:

  1. Check out or pull the code from version control, e.g. a GitHub repository. Do this inside the pmwiki/extensions directory on the server. This method also allows for easy upgrades.
  2. Download a compressed (zip) archive with the extension, provided by the developer, and place it in the pmwiki/extensions directory on the server. In some cases you don't need to uncompress the extension, see below.
  3. Extract (unzip) the compressed extension in the pmwiki/extensions directory on the server.
Should you uncompress individual extensions?

Using compressed extensions (as zip archives) has benefits and downsides:

Benefits for compressed extensions:

  • Easier deployment and updates: Installing and upgrading extensions as zip archives simplifies the deployment process. Administrators can download a single file and (re)place it in the pmwiki/extensions directory.
  • Reduced disk space: Compressed extensions occupy less disk space compared to their uncompressed counterparts.
  • Read-only distribution: The files in the compressed extension are read-only and are unlikely to be modified unintentionally, which reduces the risk of accidentally breaking an extension.
  • Version control: Administrators can easily track and manage different versions of extensions without cluttering the filesystem.
  • PHP files inside compressed extensions are only loaded by the Hub and cannot be called directly from a browser, which may prevent unintended access.

Downsides for compressed extensions:

  • Performance overhead: Decompressing the extensions at runtime may introduce a performance overhead, albeit usually negligible, and static files served from extensions are cached by the browsers for a reasonable amount of time. However, if the extensions are large or there are many of them, or if the website has many visitors in a short time, this overhead might become noticeable.
  • Readability and debugging: It can be more challenging to read and debug code directly from compressed archives. Extracting the files might be necessary for troubleshooting purposes.
  • Depending on server configuration, compressed extensions may be downloadable with a browser, if someone guesses the extension URL. The Hub comes with a .htaccess configuration for Apache forbidding this, but it may not work in some cases, or on other servers. You should evaluate how risky is this.

Benefits and downsides of uncompressed extensions:

  • Faster processing, no decompression overhead.
  • PHP and other files in the extension directory may be reachable via the browser (like for PmWiki skins). For scripts and wikiplain.d pages it might enable unintended access. It is recommended PHP files to start with <?php if (!defined('PmWiki')) exit(); to only run if loaded by PmWiki.

Compressed or not, like with skins and classic recipes, you should only install extensions from trusted sources and authors.

If the extension directory has both a compressed and an uncompressed extension with the same name, the uncompressed one will be loaded.

Extensions placed in pmwiki/extensions are available to the wiki administrators, but they need to be enabled before they become operational. This is done in the page SiteAdmin.ExtensionHub on your wiki, without the need to edit PHP files on the server.

Navigate to SiteAdmin.ExtensionHub on your wiki. By default this page, and the related "hub" action are restricted to "admin" users. You should see a table listing all extensions:

ExtensionVersionPriorityActionsConfigurations
BootstrapIcons2025-11-16150*
CodeHighlight2025-03-26a150*
Filterable2025-07-22150*

(Non-functional form)

To enable and configure a new extension, locate its row, from the drop-down select "New configuration" (it should already be selected) then press "Edit". A new page will open with something like this:

Applies to pages:

Glob patterns like Group1.*,Group2.*,-*.HomePage

Leave fields empty to reset to default values.

Place the configuration:

  Cancel

(Non-functional form)

Select the checkbox "Enable configuration". In the "Page patterns" field type "*" for all pages, or a different glob pattern, for example for selected groups. The configuration will be enabled on pages that match the pattern, and you could have different configurations for different page patterns.

If there are 2 or more configurations, a drop-down allows to reorder them. In this case, the first configuration where the page name matches the patterns, will be loaded. See Multiple configurations per extension.

Press "Save" to save the configuration.

Some extensions provide their own annotated configuration fields. In this case, they will appear between the page patterns and the Save button. (You may need to enable the extension before a custom form is visible.) Please consult the extension documentation.

Multiple configurations per extension

If you have multiple configurations for different page name patterns, there are 2 different modes which name pattern "wins" and which configuration will be loaded.

Historically, the page name patterns of all stored configurations were checked, and if the current page matched, the configuration was enabled, in the order they were created. Subsequent matching configurations were merged with the existing one, later values of the new configuration replacing existing values of the previous match.

For example, on the page Main.HomePage, if an extension has these separate configurations with name patterns:

  • * - any page, matches, the configuration is loaded
  • *.HomePage - matches, the configuration is loaded and merged with *

So in the end, the last match "wins", possibly any unset values merged from previous configurations.

This may lead to unexpected results. To simplify things, version 2025-11-09 adds a new "priority" mode. The save configuration form includes a drop-down where you can move the configuration before or after another configuration. The new mode checks the patterns in order, and stops at the first match.

So you would need to move your more general patterns after specific patterns:

  • *.HomePage - matches, the configuration is loaded, stop here
  • * - pattern not checked, not loaded

If you have many different configurations per extension and cannot quickly review and reorder them, you can disable the new priority mode by adding to config.php:

$xHub['EnablePriority'] = 0;

Notes

To do / some day / maybe

  • It should be possible to optimize/speed up the retrieval of the current page configurations outside of the Hub page and actions.
  • Internationalization - easy way for extensions to ship with translations.
  • Skins - allow for skins to be installed, enabled, and configured like extensions, with automatically discoverable wikilib.d or wikiplain.d pages, possibly resources.
  • It may be possible to split the "configuration + loading" of extensions and ship it with the PmWiki core, while having the "compressed serve" part separate.
  • Should we enable permissions selection for custom actions? Say an action enabled by an extension would be available only to editors or admins, should this be configurable in the hub? Currently the extension can decide this.

Change log / Release notes

  • 2025-11-16: Fix priority label for multiline patterns. Strip carriage returns from saved configurations.
  • 2025-11-09: Potentially breaking change: add $xHub['EnablePriority'], reordering configurations, see Multiple configurations per extension. Hub and Extension versions are now saved with configurations, to allow extensions to detect when a new version uses a different data format.
  • 2025-11-08: Update for PHP 8.5, use configurable $SiteAdminGroup.
  • 2024-08-13a: Fix bug with multi-line page patterns.
  • 2024-08-13: extGetConfig() unset some values only needed by the hub, name patterns field convert to textarea (both suggested by Simon).
  • 2024-05-31: Configurable status icons, change colors to green (active), red (inactive), yellow (new). Add conditional "extension_enabled". Hub configuration form: larger name patterns field.
  • 2024-05-30: Refactor saving configurations to fix bug when unchecking option checkboxes.
  • 2024-05-18: Custom form keys only allow [a-zA-Z0-9_] chars. Keys prefixed with "enc_" or "passwd" will save their values base64 encoded. The values will be decoded when the extension requests them with extGetConfig().
  • 2024-04-20a: Fix paths for Windows (bug reported by HansB). Refactor .htaccess.
  • 2024-04-15a: Fix RecipeCheck incompatibility, reported by Simon.
  • 2024-04-10: Add functions extAddHeaderResource() and extAddFooterResource().
  • 2024-03-02b: Fix for compressed extensions with version suffix.
  • 2024-03-02: Refactor extGetConfig() to merge a default array.
  • 2024-02-24: Add class HubPlainPageStore, function extAddWikiPlainDir(). FmtExtList() to require admin perms.
  • 2024-02-21: Add page SiteAdmin.ExtensionHub. Page patterns suggestions for existing groups. In .htaccess replace "Options -Indexes" with "IndexIgnore *" (more likely to be available on shared hostings).
  • 2024-02-20: Update PageVariables for Hub actions.
  • 2024-02-19: First public release, ready to be tested.

See also

Cookbook /
ExtensionDesign  How to create extensions compatible with ExtensionHub (Experimental)
Extensions  Recipes compatible with ExtensionHub, see ExtensionDesign.

Contributors

Written and maintained by Petko.

Comments

See discussion at ExtensionHub-Talk

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