Plugins development guide

Last update by Elxis Team

A tutorial on how to create content plugins for Elxis CMS.

Content plugins are applications being executed inside Elxis content items (or else). They are component Content specific applications. On Elxis 2006.x/2008.x/2009.x they were called bots, although plugins are not exactly the same as bots they share the same principles.

Introduction to plugins

A plugin alters given text by replacing special formatted text blocks with HTML code. The replacement is usually done via PCRE regular expressions. The general format of a plugin code is:

{plugin_name optional_attrbutes}optional_code{/plugin_name}

The plugin_name used as keyword above should be the same as the plugin name used in XML file and in plugin's php file naming.


Physical location and naming

Plugins are component's Content specific applications. You will find them under: components/com_content/plugins/

The name of a plugin should be unique. Non alphanumeric characters are not allowed in the name. Let's take as example for this tutorial the built-in plugin YouTube which displays videos from youtube.com. The name of this plugin is youtube and so inside the XML installation file the name tag should be <name>youtube</name>. The plugin should have at least the following files:

components/com_content/plugins/youtube/youtube.plugin.php
components/com_content/plugins/youtube/youtube.plugin.xml

Rest files are optional and depends on what the developer wants to do or how he wants to arrenge his code on each plugin. The XML file is the Elxis extension's installation XML file and it is formatted as all the rest extension types [1]. Custom language files should be placed in a sub-folder named language and follow this naming pattern: [language].plugin_[plugin name].php. Example:

components/com_content/plugins/youtube/language/en.plugin_youtube.php
components/com_content/plugins/youtube/language/el.plugin_youtube.php
components/com_content/plugins/youtube/language/fr.plugin_youtube.php

Plugin PHP file

Now, let's take a closer look in the contents of the plugin's PHP file (youtube.plugin.php in our case).

Inside this file there should be a class named {plugin_name}Plugin (in our case youtubePlugin). This class is an implementation of the contentPlugin interface and therefor should have at least the following public methods:

class youtubePlugin implements contentPlugin {
__construct()
process(&$row, $published, $params)
syntax()
tabs()
helper($pluginid, $tabidx, $fn)
head()
handler($pluginid, $fn)
}

Plugin methods

Method process is used on site frontend. All other public methods are used on backend by the plugins helper window [2]. Off course your plugin can have more methods, in this example we focus only on the methods the interface requires.

process

Replaces the plugin code with the HTML output. Object $row is the whole article. The replacements on the introtext and maintext columns is performed in the combined $row->text.

  • $published is a boolean declaring if the item (article) is published or not.
  • $params is an instance of the Elxis XML parameters library containing the configuration parameters of the specific plugin.

To see the process method in action let's create a process method which will replace all {info}ANYTHING{/info} instances with <div class="elx_info">ANYTHING</div>


public function process(&$row, $published, $params) {
$regex = "#{info}(.*?){/info}#s";
if (!$published) {
$row->text = preg_replace($regex, '', $row->text);
return true;
}
preg_match_all($regex, $row->text, $matches, PREG_PATTERN_ORDER);
if (!$matches) { return true; }
foreach ($matches[0] as $i => $match) {
$contents = $matches[1][$i];
if ($contents == '') {
$html = '<div class="elx_warning">You didnt wrote an informational text!</div>';
} else {
$html = '<div class="elx_info">'.$contents.'</div>';
}
$row->text = preg_replace("#".$match."#", $html, $row->text);
}
return true;
}

syntax

Returns a string containg the generic syntax for the plugin. Example:

{youtube width="300" height="200"}VIDEOCODE{/youtube}

tabs

Returns an array contenting the names of the tabs the helper uses. If your plugin doesn't have a helper or the helper has just one tab return an empty array. Example:

public function tabs() {
return array('Wow screen', 'Help', 'Credits');
}

helper

Provides the contents for each tab. Elxis will automatically provide you with the tab index number (starting from 1 for the first tab), the plugin id number (the id of the plugin extension in Elxis database) and the fn(function name) which is an index of the javascript function that will be trigged by the js Elxis Plugin plugin for the CKEditor. Example:

public function helper($pluginid, $tabidx, $fn) {
if ($tabidx == 1) {
echo 'Wow content!';
} else if ($tabidx == 2) {
echo 'Show some help';
} else if ($tabidx == 3) {
echo 'Display plugin credits';
}
}

To insert ready to use plugin code inside the helper's code input box use the addPluginCode javascript function. Example:

<a href="javascript:void(null);" class="plug_link" onclick="addPluginCode('{youtube}XXX{/youtube}')">OK</a>

head

Returns an array of stylesheet and javascript files that are required by the plugin's helper to be loaded on the document's head section. If your plugin does not use any external css/js files returns an empty array.

Example 1

public function head() {
$elxis = eFactory::getElxis();
$response = array(
'js' => array(
$elxis->secureBase().'/components/com_content/plugins/xxx/js/custom.js',
$elxis->secureBase().'/components/com_content/plugins/xxx/js/custom2.js',
$elxis->secureBase().'/components/com_content/plugins/xxx/js/custom3.js'
),
'css' => array(
$elxis->secureBase().'/components/com_content/plugins/xxx/css/mycss.css'
)
);
return $response;
}

Example 2 (no css/js files required):

public function head() {
return array();
}

handler

handler handles plugin's special tasks (if any) such as form submits. After the handler is executed you should redirect the user back to the helper window. If you don't have special tasks just redirect the user. Note that if your plugin has multiple handler tasks use in your request towards hander a variable name such as action to distinguise them. In the example below there are not tasks for the handler, so we just redirect the user in case for some reson (normally there is no reason) the handler was called.

public function handler($pluginid, $fn) {
$elxis = eFactory::getElxis();
$url = $elxis->makeAURL('content:plugin/', 'inner.php').'?id='.$pluginid.'&fn='.$fn;
$elxis->redirect($url);
}

Calling the replacer

To call the plugins replacer (processor) on a content item (or else) use the following:

$ePlugin = eFactory::getPlugin();
$ePlugin->process($row);

or in a more compact syntax:

eFactory::getPlugin()->process($row);

elxisPlugin methods

The elxisPlugin library provides you with some very helpful methods you can use if you want to remove all plugins from an article (removePlugins), get an array of the plugins used in a given text (usedPlugins) or parse a string containg the plugin attributes and get them as an array (parseAttributes).


Final notes

Tips on security

If your plugin's handler uploads files on the system you should be VERY careful with it. Don't allow files with extensions other's than the safe ones. Don't allow the upload of files anywhere in Elxis file system except inside the proper folders. Sanitize users requests with caution and use session tokens to verify the origin of the request.

Performance

Elxis plugins are ultra fast! The system has been built in a way that triggers a plugin only when it is absolutely needed.

Using plugins in other components

Even if plugins were designed for component Content you can use them in other components too. Just process an object containg a text property and plugins will be executed against it. Example:

$row = new stdClass;
$row->id = 5;
$row->text = 'Any text here with a {xxx}sample{/xxx} plugin in it!';
eFactory::getPlugin()->process($row);

Notes

  1. See the modules development guide for a sample on an XML installation file.
  2. Elxis has a system for easy integration of plugin's code into the WYSIWYG editor. This is the guided input method which triggers the plugin's helper.

It has been read 8236 times

You are free to copy, distribute and transmit the articles in this site for non-commercial purposes.
Creative Commons 3.0