Notes:
getMinNucleusVersion
appropriately.Nucleus plugins allow just about anyone to extend the functionality that Nucleus offers, without having to alter the PHP code itself. Plugins are simple php scripts that must implement certain methods, and can easily be exchanged between Nucleus users. Installing goes as easy as adding the plugin file to the plugin directory and letting Nucleus know it's there.
Some advantages of plugins are listed below:
All plugin files should be placed in the directory that is listed in config.php
. Commonly, this will be /your/path/nucleus/plugins/
. Plugin files can be recognized by their form: NP_
name
.php
. Some plugins require a subdirectory with the same name to store extra files or their admin area.
Note: the names are case-sensitive, so they should start with NP_
, not Np_
or np_
. Also note that when the plugin uses a subdirectory, the name of that directory should be all lowercase.
Ok, lets start by writing a simple plugin. Basically, each plugin is a PHP class that inherits from the predefined class NucleusPlugin
. Below is an example of a HelloWorld
-plugin:
<?php class NP_HelloWorld extends NucleusPlugin { // name of plugin function getName() { return 'Hello World'; } // author of plugin function getAuthor() { return 'Wouter Demuynck'; } // an URL to the plugin website // can also be of the form mailto:foo@bar.com function getURL() { return 'http://nucleuscms.org/'; } // version of the plugin function getVersion() { return '1.0'; } // a description to be shown on the installed plugins listing function getDescription() { return 'Just a sample plugin.'; } function doSkinVar($skinType) { echo 'Hello World!'; } function supportsFeature ($what) { switch ($what) { case 'SqlTablePrefix': return 1; default: return 0; } } } ?>
So, that wasn't so hard after all. Read on to find out more.
All Nucleus plugins must inherit from the PHP class NucleusPlugin
. If this sounds complicated, don't worry, it isn't. It even makes your life easier, allowing you to only implement the methods that your plugin needs, and giving access to some auxiliary functions.
Below is an overview of the methods that the NucleusPlugin
offers, and that you can re-implement in your own plugin. If you want to see the source of the class itsself, it's located at nucleus/libs/PLUGIN.php
Overview of the class NucleusPlugin
(redefinable methods)
Next to the methods that can be implemented, the class NucleusPlugin
offers some extra methods which you should not implement yourself. They can be called from within your plugin using the $this→functionName()
syntax.
Overview of the class NucleusPlugin
(non-redefinable methods)
You can create your own skinvars, and call them using <%plugin(
PlugName
,
parameters
)%>
or <%PlugName(parameters)%>
(when this does not conflict with an existing skinvar). Parameters are comma-separated.
To handle skinvars, you'll need to implement the doSkinVar
method. Some samples of signatures are given below:
function doSkinVar($skinType) function doSkinVar($skinType, $param1, $param2) function doSkinVar($skinType, $skinVar, $param1, $param2) function doSkinVar($skinType, $skinVar, $param1 = 'default value')
$skinType
parameter will be one of 'index', 'item', 'archive', 'archivelist', 'member', 'error', 'search', 'imagepopup' or template'$skinVar
is actually the first parameter that's being interpreted as a type of skinvar (e.g. <%plugin(PlugName,VarType)%>
)doSkinVar()
(no parameters) and retrieve the parameters using the PHP function func_get_args()
. Could be handy if you have different types of skinvars with different numbers of arguments$currentSkinName
Template plugin variables work in the same way as skin plugin vars. There are two differences:
$skinType
parameter. Instead, they take extra parameters with info on the item and comment that is currently being parsed:doTemplateVar
-method gets a &$item
parameter.doTemplateCommentsVar
-method gets an &$item
parameter as well as a &$comment
parameter.Note the ampersands!
Template variables are called in exactly the same way as skinvars (using <%plugin(
PlugName
,
parameters
)%>
or <%PlugName(parameters)%>
)
By default, all template variables are passed on to the doSkinVar
-method, using 'template
' as skinType
-parameter.
If you want to provide your own implementation, you'll need to redefine the method doTemplateVar
and/or doTemplateCommentsVar
. It works in the same way as doSkinVar
, except that now the skinType
-parameter is missing.
function doTemplateVar(&$item) function doTemplateVar(&$item, $param1, $param2) function doTemplateVar(&$item, $type, $param1, $param2) function doTemplateVar(&$item, $type, $param1 = 'default value') function doTemplateCommentsVar(&$item, &$comment) function doTemplateCommentsVar(&$item, &$comment, $param1, $param2) function doTemplateCommentsVar(&$item, &$comment, $type, $param1, $param2) function doTemplateCommentsVar(&$item, &$comment, $type, $param1 = 'default value')
$currentTemplateName
Plugins can perform actions through action.php
, the same script that's being used to receive comments and karma votes. You can call it using both GET and POST methods. Required parameters are action
(should be 'plugin'), name
(name of the plugin) and type
(type of requested action)
To enable these actions, you should implement the doAction($actionType)
method in your plugin. Extra parameters from the request can be received using requestVar(
'name
')
(requestVar
takes care of magic_quotes_gpc that PHP might have added)
When your doAction
method returns a string, it will be interpreted as an error, and an error message will be shown.
Nucleus Plugins can subscribe to events that occur whenever something important happens. The plugin can then execute some actions, or output some text.
Below is an example of how a plugin subscribes to the PreAddComment
-event, an event that is generated immediately before a comment is added to a blog.
class NP_Acronyms extends NucleusPlugin { ... function getEventList() { return array('PreAddComment'); } ... function event_PreAddComment(&$data) { // replace acronym HTML $data['comment']['body'] = strreplace('HTML', '<acronym title="HyperText Markup Language">HTML</acronym>', $data['comment']['body']); } }
This plugin replaces the text HTML
in each comment by the text <acronym title=“HyperText Markup Language”>HTML</acronym>
. The acronym
-tag is a HTML-tag that allows authors to provide extra information on acronyms.
Here's the steps you need to take to subscribe to an event:
getEventList
-methodevent_
EventName
($data)
, in which the handling of the event is doneMultiple plugins can subscribe to the same event. The order in which these plugins are notified is the same order as the ordening in the plugin list of the admin area. Plugins higher in the list get notified earlier on.
The event_
EventName
-method gets only one parameter, $data
, of which the contents differs depending on the event. It is an associative array with data. Objects and arrays that are passed in this array, are passed by reference, so the changes you make there will be remembered.
The event list uses some colors to indicate if changes in the parameters will be seen by nucleus or not:
Objects that are passed as parameters are indicates as follows: object. Most objects are also passed by reference, making them look like object by ref
A series of methods are offered to make it easy for plugins to set and retrieve options. These options can be directly edited from inside the Nucleus admin area, taking the need away for the plugin to provide an admin area of its own, and avoiding that options need to be set inside the PHP file itself.
Options are available in different contexts:
Several types of options are provided
text
Simple text
yesno
Either the value 'yes
' or the value 'no
' (on edit, shown as radio button)
password
Text field (starred on edit)
textarea (v2.2)
Text field with multiple rows and columns
select (v2.2)
Drop down menu. Needs extra info in the following form: Option 1|value1|Option 2|value2|Option 3|value3
As of Nucleus v3.2, some option types can be limited to only accept certain values using option-metadata. This metadata is stored in the $typeExtras
-field, and is a semicolon-seperated list of values. Note: In a select-option, the select list must be the first value in $typeExtras
.
key | explanation |
---|---|
datatype | Using 'datatype ' you can give some extra hints to Nucleus about the datatype you want to use. Currently only 'numerical ' is available. 'numerical ' will cause Nucleus to only accept numerical values for this option (using both client-side and server-side check) (available for optiontypes: 'select ' and 'text ') |
access | If set to 'readonly ', the option will not be editable (available for optiontypes: 'text ' and 'textarea ')If set to 'hidden ', the option will be completely hidden for the end-user (available for optiontypes: 'text ') |
some examples:
// following code creates a text-option that only accepts numerical values $this->createBlogOption('FooBar', 'foobar', 'text', '0', 'datatype=numerical'); // following code creates a select-option that only accepts numerical values $this->createItemOption('FooBar', 'foobar', 'select', '0', '0|0|1|1|2|2;datatype=numerical'); // following code creates a textarea-option that is readonly $this->createOption('FooBar', 'foobar', 'textarea', 'This textarea is readonly', 'access=readonly');
, $typeExtras =
)Creates a new option in the global context
parameter | value |
---|---|
$name | Option name |
$desc | Textual description, to be shown on the page where options can be edited |
$type | Option type (see above) |
$defValue | Initial value |
$typeExtras | Extra info on option type (see above) |
, $typeExtras =
)
Creates an option in the blog context (see createOption
)
, $typeExtras =
)
Creates an option in the category
context (see createOption
)
, $typeExtras =
)
Creates an option in the member
context (see createOption
)
, $typeExtras =
)
Creates an option in the item
context (see createOption
)
changes the value of an option that was already in the database
parameter | value |
---|---|
$name | Option name |
$value | New value for option |
Changes the value for a blog option. The blogid
attribute indicates for which blog the option is valid. (other options: see setOption
)
Changes the value for a category option. The catid
attribute indicates for which category the option is valid. (other options: see setOption
)
Changes the value for a member option. The memberid
attribute indicates for which member the option is valid. (other options: see setOption
)
Changes the value for an item option. The itemid
attribute indicates for which item the option is valid. (other options: see setOption
)
Returns the value for an option in the database
parameter | value |
---|---|
$name | Option name |
Returns the value for a blog option. blogid
indicates for which blog a value is requested (other parameters: see getOption
)
Returns the value for a category option. catid
indicates for which category a value is requested (other parameters: see getOption
)
Returns the value for a member option. memberid
indicates for which member a value is requested (other parameters: see getOption
)
Returns the value for an item option. itemid
indicates for which item a value is requested (other parameters: see getOption
)
Deletes an option from the database
parameter | value |
---|---|
$name | Option name |
Deletes a blog option (see deleteOption
)
Deletes a category option (see deleteOption
)
Deletes a member option (see deleteOption
)
Deletes an item option (see deleteOption
)
Returns all values for a given blog option. The result is an associative array with a value for each existing blogid
Returns all values for a given category option. The result is an associative array with a value for each existing catid
Returns all values for a given member option. The result is an associative array with a value for each existing memberid
Returns all values for a given item option. The result is an associative array with a value for each existing itemid
Returns the top of the values for a given option. The result is an array where every element is an array with a value ('value') for each blogid ('id')
parameter | value |
---|---|
$name | Option name |
$amount | The amount of options you want |
$sort | Sort ascending ('asc') or descending ('desc') |
Returns the top of the values for a given option. The result is an array where every element is an array with a value ('value') for each memberid ('id') (parameters: see getBlogOptionTop
)
Returns the top of the values for a given option. The result is an array where every element is an array with a value ('value') for each categoryid ('id') (parameters: see getBlogOptionTop
)
Returns the top of the values for a given option. The result is an array where every element is an array with a value ('value') for each itemid ('id') (parameters: see getBlogOptionTop
)
Note: You can't call these functions from inside constructors of plugin classes. If you want to execute them when the plugin is loaded, place them in the init()
method instead.
Up to v2.0, accessing the nucleus tables was just a matter of performing an SQL query on one of the nucleus_
tables. Since it is possible to use a custom table name in Nucleus versions >2.0, some precautions are needed in plugin development:
nucleus_item
, use the global function sql_table('item')
to generate the prefixed tablename1
(true
) when supportsFeature('SqlTablePrefix')
is called on it. If it doesn't, you won't be able to load the plugin on Nucleus versions > 2.0 when a custom prefix has been set (as a precaution)
Note that the sql_table
global function in not available in Nucleus versions up to v2.0. If you use this method and want your plugin to work on Nucleus versions ⇐ 2.0, add the following snippet of code on top of your plugin class:
<?php // plugin needs to work on Nucleus versions &=2.0 as well if (!function_exists('sql_table')) { function sql_table($name) { return 'nucleus_' . $name; } } class NP_HelloWorld extends NucleusPlugin { ... } ?>
If your plugin needs database tables of it's own, you should create then in the install
method and remove them in the unInstall
method.
Some pointers
nucleus_plug_
plugname
to avoid conflicts with other plugins. Generate them through sql_table('plug_plugname')
to make it work with custom prefixesmysql_query()
sql_connect()
at the end of your function. It might also be good to do this from the constructor, to avoid reconnecting constantly. You could then save your link identifier in $this→db
and pass that along with every query.getTableList()
method to make sure your table gets backupped when using the backup function.As of Nucleus v2.5, plugins can create admin area pages that integrate with the Nucleus admin area. These pages can be accessed either from the plugin admin page, or the quickmenu on the left.
To provide an admin area, you'll need take these steps:
NP_PluginName
. Note that the name should be lowercase!<?php // if your 'plugin' directory is not in the default location, // edit this variable to point to your site directory // (where config.php is) $strRel = '../../../'; include($strRel . 'config.php'); if (!$member->isLoggedIn()) doError('You\'re not logged in.'); include($DIR_LIBS . 'PLUGINADMIN.php'); // create the admin area page $oPluginAdmin = new PluginAdmin('PluginName'); $oPluginAdmin->start(); echo '<h2>Plugin Name</h2>'; echo '<p>Page contents here<p>'; $oPluginAdmin->end(); ?>
QuickMenu
event and add this code in your plugin:function event_QuickMenu(&$data) { array_push( $data['options'], array( 'title' => 'Plugin Name', 'url' => $this->getAdminURL(), 'tooltip' => 'Tooltip text' ) ); }
function hasAdminArea() { return 1; }
$strRel
variable in the index.php
needs to be adapted manually if the plugins directory is not located in nucleus/plugins/
The purpose of the PluginAdmin
is to help you. Once created, you can use $oPluginAdmin→plugin
to access the instance of your plugin.
As of Nucleus v3.2 plugins can provide a helppage with an overview of the plugins' functionality, the available skinvars and templatevars, where to get more info,…
The helppage will be accessible from the plugin overview in the admin area.
To provide a helppage, you'll need take these steps:
<h3>Plugin overview</h3> <p>The only purpose of this plugin is to show how the plugin helppages work</p> <h3>Installation</h3> <p>If you can read this you correctly installed the plugin :-)</p> <h3>SkinVars</h3> <p>Because this plugin is only a testcase it doesn't has any skinvars/templatevars but suppose it would have: <ul><li><b><%HelpPageTestCase1%></b>: does something</li> <li><b><%HelpPageTestCase1(foobar)%></b>: does something else</li></ul></p> <h3>Support and Bug reports</h3> <p>For additional support and/or bug reports please use this forum thread: <a href="http://forum.nucleuscms.org/viewtopic.php?t=<TOPIC_ID_GOES_HERE>"> http://forum.nucleuscms.org/viewtopic.php?t=<TOPIC_ID_GOES_HERE></a></p> <h3>Version History</h3> <ul><li>Version 0.1: initial testcaseversion</li> <li>Version 0.0: pre-initial version ;-)</li></ul>
function supportsFeature($what) { switch($what) { case 'HelpPage': return 1; default: return 0; } }
Starting from 3.2, a new plugin interface is added to allow one to declare any dependency on other plugin(s). This is useful for any plugin that requires another plugin to function. It is particularly useful for a plugin to detect broken dependencies that prevent if from functioning properly.
Let start from a real world example:
NP_PageLinkList depends on NP_BlogWithOffset to function, so we want to make sure if a user install NP_PageLinkList whithout first install NP_BlogWithOffset. With this API, Nucleus offers a way for a plugin to detect any missing dependency before it is installed.
In this case, we want to code into NP_PageLinkList to mark that it requires NP_BlogWithOffset. When the plugin is installed, the core calls a function in the plugin called getPluginDep()
. This function returns a list of plugin it requires, and the core will check against all installed plugins and refuse to install the plugin if a dependency is missing.
All we have to do is added this function to NP_PageLinkList:
function getPluginDep() { return array('NP_BlogWithOffset'); }
The plugin dependency check also prevents plugins from being uninstalled if other plugins have a dependancy on it.