Extension Structure

Starting from Plesk 11, developers can pack extensions in a cross-platform format, in a ZIP archive with a metadata file placed in the root directory. Such extensions are also supported by Plesk for Windows.

Plesk for Linux is backwards-compatible with previously used extension (module) packages in RPM and Deb package formats. However, we highly recommend that you pack and distribute extensions in ZIP archives.

In this chapter:

File Structure


Conflict Resolution on Upgrade

Removal Procedure

Creating and Packaging Extensions

Class Naming Conventions


File Structure

A typical ZIP archive with an extension has the following structure of files and directories:


The description of the most important files and directories is as follows:

  • meta.xml

    The XML-formatted description of an extension. During the extension installation, the file is extracted to


    where PRODUCT_ROOT_D is /usr/local/psa on Linux systems and %plesk_dir% on Windows systems.

  • /htdocs

    All entry points of an extension, CSS, Javascript, and graphics files should be placed in this directory. During installation, the contents of this directory are extracted directly into /PRODUCT_ROOT_DIR/admin/htdocs/modules/EXTENSION_ID/.

  • /htdocs/public

    Includes scripts that do not require authorization (bypassing controllers).

  • /plib

    This directory should contain PHP classes that are responsible for the logic of an extension. During installation, the contents of this directory are extracted directly into PRODUCT_ROOT_D/admin/plib/modules/MODULE_ID/.

  • /plib/hooks

    This directory should contain Plesk's hooks.

  • /plib/scripts

    This directory should contain scripts that the system runs instantly before the extension installation, after the installation, or after the removal.

    The following scripts are available:

    • pre-install.php - runs before extension files are copied. This script makes sure that the system meets the extension’s requirements. Extension files are not available at this stage.
    • post-install.php - runs after extension files are copied. This script prepares the system for the installation of the extension. Using this script, you can create databases or prepare the necessary directory structure.
    • pre-uninstall.php - runs before the removal of an extension. This script helps remove files used by the extension - databases, templates, user content.

    If a script exits with a non-zero status, the current action is interrupted with an error. The script output will be displayed to the Plesk administrator as an error message.

  • /sbin/

    This directory should contain scripts that require elevated privileges during execution.

  • /var

    The directory for storing data used by the extension, for example, SQLite databases.

    During the extension installation, the contents of this directory are extracted to PRODUCT_ROOT_D/var/modules/EXTENSION_ID/. This directory is not removed when upgrading an extension.




A file that describes an extension, meta.xml, can look as follows:

<?xml version="1.0"?>
  <name>Test extension</name>
  <description>Add description here...</description>

The description of the available elements within the module node is as follows:

  • id

    The identifier of an extension. It is used as a part of the URL of the extension root. For example, if an extension ID is sample-extension, the extension is available at http://<plesk-host-name>:<port>/modules/sample-extension.

  • name

    The name the administrators will see in the extensions list in Plesk (Server Management > Extensions) after installing the extension.

  • (Optional) description

    The extension description the administrators will see in the extensions list in Plesk (Server Management > Extensions) after installing the extension.

  • version

    The extension version. Can be an arbitrary string, though we recommend using the following format: X.Y (where X and Y are numbers), e.g. 1.0. Administrators can see it in the extensions list.

  • release

    The module package version. It corresponds to the package changes that do not affect the code of the extension, but change something in the package itself (such as the post-install script). Can be an arbitrary string, though we recommend using the following format: X (where X is a number), e.g. 1. Administrators can see it in the extensions list.

  • (Optional) vendor

    The vendor name.

  • (Optional) url

    The extension's vendor site.

  • (Optional) plesk_min_version

    The minimal version of Plesk which supports the extension.

  • (Optional) plesk_max_version

    The maximum version of Plesk which supports the extension.

  • (Optional) help_url

    The link to the extension documentation. Administrators can see it in the extensions list.

  • (Optional) os

    Operating systems supported by the extension. Possible values: unix and win.

  • (Optional) encoder

    Use this element if your extension is encoded by ionCube. Possible values: ioncube.


Conflict Resolution on Upgrade

When administrators upload a new version of an extension to Plesk, the possible conflicts between the existing and new files are resolved in the following way.

  • If a file already exists, it is overwritten.
  • If a directory already exists, files inside it are overwritten.
  • Files that were present in the previous version of an extension, but are missing in the newer version, are removed.

If one of these conflict resolution rules is not satisfied (for example, an existing file is blocked and cannot be overwritten), the upgrade procedure fails.


Removal Procedure

The following files are removed when an extension is removed:

  • PRODUCT_ROOT_D/admin/htdocs/modules/EXTENSION_ID/
  • PRODUCT_ROOT_D/admin/plib/modules/EXTENSION_ID/

Here PRODUCT_ROOT_D is /usr/local/psa on Linux systems and %plesk_dir% on Windows systems.

If an extension file cannot be removed, the removal procedure fails.

All files that are used by an extension should be removed by the pre-uninstall script.


Creating and Packaging Extensions

You can create the file structure necessary for an extension in one step, using the following command-line call:

plesk bin extension --create <EXTENSION_NAME>

Read more about the utility in the following documents:

With this utility, you can create a ready-for-distribution extension (by creating a ZIP archive of the extension file structure). The following call prepares the archive in the current directory:

plesk bin extension -p my-project

If you need to create an archive in a different directory, supply the utility call with the -destination /path/to/directory/ option.


Class Naming Conventions

The system allows to call your classes from almost all places of your code without preliminary requiring them. For this, you should properly name the classes and put the file which contains the class into a particular directory. This simplification is not necessary in most cases, it just makes your code more compact, but sometimes you are required to adhere to the naming conventions. For example, if you wish to add a dashboard widget, you are required follow the conventions because the system needs to automatically discover and load this class.

The naming conventions are as follows:

  • The class name must start with the Modules_ExtensionName prefix. Here ExtensionName is the ID of your extension processed using the following instruction:
    1. Remove the dashes (-).
    2. Change the first letter and letters that precede dashes to uppercase.

    Example: my-site is transformed to MySite.

  • The class name must include the path to the directory where the file containing the class resides. The slashes (/) in the path are substituted by underscores (_). The path must be given relatively to the extension's /plib/library/ directory.

    For example, if a class is in /plib/library/website/Promo.php and the extension ID is my-site, the class name must be:


Zend uses a similar approach for auto-loading classes. Read more about it in http://framework.zend.com/manual/1.11/en/learning.autoloading.design.html .


The auto-loading of classes does not work in the /htdocs/public/ directory. If you need this feature, start the auto-loading manually by adding the following code to the beginning of a file: