How MODx Plugins Work
Plugins are custom code that is inserted at specified points in the various processes of the core of MODx. They make use of event functions that are sprinkled throughout the parser and the other processing scripts, such as displaying the forms for creating or editing documents, saving documents, snippets, etc. and at various points during user logins. In this manner it is possible to customize the core behavior of MODx without changing the core scripts.
Plugins are created in the same manner as most other MODx content; there is a form with a few fields for its name, a description, and a textarea field for the plugin code. The key to using a plugin is the System Events tab. This tab contains checkboxes enabling the plugin to "listen" as it were for whatever events are checked. The code in the plugin is executed at the point in the MODx script where that event function is specified.
A number of third-party snippets also use this "event" model to allow customization without actually hacking the original script. The eForm snippet is an example of this. It behaves differently, however, in that it does not make use of plugins; instead it uses functions embedded in custom snippets that must be called before the eForm snippet is called in order to make the custom function available to eForm. Another snippet is the TreasureChest e-commerce snippet. TreasureChest, however, does make use of plugins, by inserting its event names into the system_eventnames table in the MODx database on installation.
Creating a Plugin
To create a plugin, go to Resources, Manage Resources in the main manager menu.
- Select the Plugins tab, and click on the New Plugin link.
- Give the plugin a name, and a description.
- The next checkbox will enable or disable the plugin. A disabled plugin won't run.
- The next checkbox is to prevent users who have not been assigned the Administrator role from editing or deleting the plugin.
- Enter the php code for the plugin in the Plugin code textarea field.
The Configuration tab has four fields:
- Existing category or New category - This has no effect on the plugin's behavior; it's strictly for organizing your plugins. Either select an existing category from the drop-down list, or enter a new category.
- Import module shared parameters - If the plugin works with a module, you can share the module's parameters. The module has to be configured to share its parameters with your plugin, then the module or modules will be available for selection in the drop-down.
- Plugin configuration - any global configuration settings for your plugin. A common configuration might be the path to the plugin's include or other support files.
The System Events tab is where you select the event or events you want your code to intercept. For the most part, the events' naming convention makes it pretty clear at what point they are invoked. However, the Template Service events are worth taking a closer look at.
- OnLogPageHit - as soon as it's determined which document this is, immediately after the onWebPageInit event, a check is made whether or not the document's 'track_visitors' field is set to 1; if it is, this event is made available.
- OnLoadWebDocument - this event is invoked when the document's template (or its content, if it uses a blank template) is loaded, before any parsing is begun. At this point, the documentContent and documentObject arrays are available. The documentObject array contains the fields from the site_content table of the database for this document. The documentContent variable contains the raw unparsed HTML of the template (or content).
- onWebPagePrerender - this is the last event of the document parsing process, and is invoked immediately before the finished document is sent to the server. This event is probably the most commonly used one; since the entire document is available in the documentOutput variable, additional parsing and modifications to the finished document can be added here. For example, the email obfuscation plugins use this event to modify all links that are mailto: links.
to be continued...