Plugin API July 27, 2005
Notes:

Introduction

Back to the developer docs index

This document contains information on how you can write your own Nucleus plugins

Table Of Contents

Introduction back to top

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.

Writing your first plugin back to top

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;
		}
	}

}
?>
  1. Copy this code in a file called NP_HelloWorld.php, and put it in your plugins directory. Make sure that there are no spaces after the last ?> or before the first <?php.. NP stands for "Nucleus Plugin", if you were wondering about that.
  2. Open the Nucleus Administration area and go into Nucleus Management/Manage Plugins
  3. You'll find out that there's a HelloWorld plugin you can install. Do this. If everything worked out correctly, you'll see that your plugin is now listed in the list of installed plugins.
  4. Now edit one of your skins and insert the following statement at a place of which you know where it will show up on the actual page.
    <%HelloWorld%>
    Note that the name (HelloWorld) is case sensitive!
  5. Now visit a page that uses the skin you edited: notice the "Hello World" at the location where you've added the plugin-skinvar.

So, that wasn't so hard after all. Read on to find out more.

The class NucleusPlugin back to top

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)
Method SignatureExplanation
getName() Returns the name of the plugin. This will be the name that will show up on the list of installed plugins. You should definately redefine this method, since the default implementation returns Undefined
getAuthor() Returns the name of author of the plugin. This name will show up on the list of installed plugins. You should definately redefine this method, since the default implementation returns Undefined
getURL() Returns the URL of the site where the plugin can be downloaded, or where additional information about the plugin can be found. If no such site exists, a mailto:-link with the authors email address is appropriate. You should definately redefine this method, since the default implementation returns Undefined
getDescription() Returns a longer description of the plugin. This will show up on the list of installed plugins. The default implementation returns Undefined
getVersion() Returns the current version of the plugin. Returns 0.0 by default
getMinNucleusVersion() (v2.0b) Returns the minimum required Nucleus version. By default, this returns 155 (v1.55). If you are using plugin features that were introduced later, please implement this function (e.g. v2.0 => 200). Please note that Nucleus v1.55 does not use this function at all, so it remains possible to install newer plugins there, even if they use newer features.
getMinNucleusPatchLevel() (v3.1) Returns the minimum required Nucleus patch level that needs to be present when running the minimal required Nucleus version (getMinNucleusVersion). By default, this returns 0. This function is generally used when new plugin features are available only as patches to the latest released Nucleus version.
init() Initializes the plugin. This method gets called immediately after the plugin object is created and the plugid-attribute has been set. By default, this method does nothing.
doSkinVar($skinType) When plugins are called using the <%plugin(...)%>-skinvar, this method will be called. the $skinType parameter contains the type of skin (item, archive, ...) from where the plugin is called. Don't get confused by the fact that there's only one parameter. Multiple parameters can still be passed. More info on implementing the doSkinVar method. By default, this method does no output at all.
doTemplateVar(&$item) Basically the same as doSkinVar, but this time for calls of the <%plugin(...)%>-var in templates (item header/body/footer and dateheader/footer). By default, this method forwards the handling to the doSkinVar-method, using template as skintype. More information on implementing the doTemplateVar method
doTemplateCommentsVar(&$item, &$comment) (v2.0b) Basically the same as doSkinVar, but this time for calls of the <%plugin(...)%>-var in templates (comments-related parts). By default, this method forwards the handling to the doSkinVar-method, using template as skintype. More information on implementing the doTemplateCommentsVar method
doAction($type) When a plugin wants to allow user interaction, it can allow actions through action.php. This is the script that Nucleus uses itself to handle new comments and karma votes. Called with the correct parameters, the doAction-method from a plugin can be called. The $type contains an optional message type. Extra variables from the request can be accessed from within the doAction method. By default, this method returns a string No Such Action which will trigger an error message. More info on doAction.
install() This method gets called on the moment the plugin is installed. It can perform initializing actions, such as the creation of database tables, the creation of plugin options, etc... By default, this method does nothing.
unInstall() Called when the plugin is uninstalled. It's a good thing to clean up information your plugin created in the database at this point. By default, this method does nothing.
getEventList() Plugins can subscribe to events. Events get generated whenever Nucleus performs a certain action. An AddItem event for example, will call all plugins that subscribed to this event. The called method will be event_AddItem($params). The $params-parameter is an associative array containing several fields of information, like the itemid for AddItem. Returns an empty array by default, indicating that the plugin does not subscribe to any event at all. More information about events.
getTableList() This method should return an array of database tables that the plugin has created. It's used in the backup feature that Nucleus offers, so plugin tables are also included in the backup. By default, returns an empty array.
hasAdminArea() Should return 1 if the plugin has an admin area of its own, and 0 if it doesn't. By default, 0 is returned.
getPluginDep() (v3.2) Returns an array of plugin names. Nucleus refuses to install the plugin if any of these plugins is not installed. By default, an empty array is returned. More information on plugin dependencies.

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)
Method SignatureExplanation
createOption(...)
createBlogOption(...)(v2.2)
createCategoryOption(...)(v2.2)
createMemberOption(...)(v2.2)
createItemOption(...)(v3.2)
Creates a new option
deleteOption(...)
deleteBlogOption(...)(v2.2)
deleteCategoryOption(...)(v2.2)
deleteMemberOption(...)(v2.2)
deleteItemOption(...)(v3.2)
Deletes an option
setOption(...)
setBlogOption(...)(v2.2)
setCategoryOption(...)(v2.2)
setMemberOption(...)(v2.2)
setItemOption(...)(v3.2)
Sets the value of an option
getOption(...)
getBlogOption(...)(v2.2)
getCategoryOption(...)(v2.2)
getMemberOption(...)(v2.2)
getItemOption(...)(v3.2)
Retrieves the value of an option
getAllBlogOptions(...)(v2.2)
getAllCategoryOptions(...)(v2.2)
getAllMemberOptions(...)(v2.2)
getAllItemOptions(...)(v3.2)
For a given option, returns an associative of all values (one value per context)
getBlogOptionTop(...)(v3.2)
getMemberOptionTop(...)(v3.2)
getCategoryOptionTop(...)(v3.2)
getItemOptionTop(...)(v3.2)
For a given option, returns the top of all values
getID() Returns the ID for this plugin (this is the ID internally used inside Nucleus)
getAdminURL() Returns the URL of where the admin area of the plugin is located (if there is no such admin area, this information is invalid)
getDirectory() Returns the path in the servers filesystem where the extra files for the plugin are stored (if there are no such files, this information makes no sense). The result is something like ".../nucleus/plugins/plugname/"
getShortName() Returns the part of the plugin classname without the "NP_"-part, and in all-lowercase. This information is used in the functions getAdminURL and getDirectory

Skinvars back to top

Description

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')

Notes

Template variables back to top

Description

Template plugin variables work in the same way as skin plugin vars. There are two differences:

  1. They are called from within templates instead of from within skins
  2. They don't take a $skinType parameter. Instead, they take extra parameters with info on the item and comment that is currently being parsed: 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')

Notes

Actions back to top

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.

Events back to top

Nucleus Plugins can subscribe to events that occur whenever something important happens. The plugin can then execute some actions, or output some text.

Example

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.

Subscribing to events

Here's the steps you need to take to subscribe to an event:

  1. Add the event name to the array returned by the getEventList-method
  2. Create a method with signature event_EventName($data), in which the handling of the event is done

Multiple 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.

Parameters

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 below 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

Event List

Events on which a plugin can subscribe
NameWhenParameters
InitSkinParse Just before the skin is initialized
skin
The SKIN-object that is handling the parse
type
Type of skinpart (one of 'index', 'item', 'archive', 'archivelist', 'member', 'error', 'search', 'imagepopup', 'fileparser')
PreSkinParse Immediately before the parsing of a skin begins
skin
The SKIN-object that is handling the parse
type
Type of skinpart (one of 'index', 'item', 'archive', 'archivelist', 'member', 'error', 'search', 'imagepopup', 'fileparser')
contents
The content of the skin
PostSkinParse Immediately after parsing a skin
skin
The SKIN-object that is handling the parse
type
Type of skinpart (one of 'index', 'item', 'archive', 'archivelist', 'member', 'error', 'search', 'imagepopup', 'fileparser')
PreItem Before an item is parsed, but after the item header has been placed
blog
BLOG object
item
object containing item data
PostItem After an item has been parsed, but before the item footer has been parsed
blog
BLOG object
item
object containing item data
PreComment Before a comment is shown
comment
associative array containing comment data
PostComment After a comment has been shown
comment
associative array containing comment data
PreDateHead Before a date header is shown
blog
BLOG object
timestamp
Timestamp for date header
PostDateHead After a date header has been parsed
blog
BLOG object
timestamp
Timestamp for date header
PreDateFoot Before a date footer is parsed
blog
BLOG object
timestamp
Timestamp for day that is closed
PostDateFoot After a date footer has been parsed
blog
BLOG object
timestamp
Timestamp for day that is closed
LoginSuccess After a successful login
member
MEMBER object
LoginFailed After a failed login
username
login name that was used in the login attempt
Logout After logout
username
name of the user that logged out
PreBlogContent Before blog content has been inserted through a skinvar
blog
BLOG object
type
Type of skinvar that's being called ('blog', 'otherblog', 'archive', 'archivelist', 'item', 'searchresults', 'othersearchresults', 'categorylist', 'otherarchive', 'otherarchivelist')
PostBlogContent After blog content has been inserted through a skinvar
blog
BLOG object
type
Type of skinvar that's being called ('blog', 'otherblog', 'archive', 'archivelist', 'item', 'searchresults', 'othersearchresults', 'categorylist', 'otherarchive', 'otherarchivelist')
PreAddComment Before adding a comment to the database
comment
comment data (associative array)
PostAddComment After adding a comment to the database
comment
comment data (associative array)
commentid
comment ID
PostRegister After a new user has registered
member
New MEMBER object
PostAddItem After an item has been added to the database
itemid
new itemid in database
PostUpdateItem Immediately after an item gets updates in the database
itemid
item ID
PreAddItem Immediately before an item is added to the database
title
title
body
body text
more
extended text
blog
BLOG object
authorid
ID of author
timestamp
UNIX timestamp
closed
1 (no comments allowed) or 0 (comments allowed)
draft
1 (draft) or 0 (not draft)
catid
ID fo category
PreUpdateItem Immediately before an item gets updates in the database
itemid
item ID
title
title
body
body text
more
extended text
blog
BLOG object
closed
1 (no comments allowed) or 0 (comments allowed)
catid
ID fo category
PrepareItemForEdit Called after getting an item from the database, and before presenting it to the user to be edited.
item
associative array containing item data
PreUpdateComment Immediately before a comment is updated and saved into the database
body
Comment body
PrepareCommentForEdit After a comment is retrieved from the database, and before it is presented to the user to be edited.
comment
comment data (associative array)
PrePluginOptionsEdit (v2.0b) before the 'edit plugin options' form is created.
(v2.2) extra parameters
(v3.2) extra parameter for every option
context
(v2.2) global, blog, member, item or category
options
Array with for each option an associative array, having the following indices: name, value, oid, description, type, typeinfo, contextid, extra. Extra options can be added here (if you want to do something with them, you'll need to subscribe to PostPluginOptionsUpdate as well)
Using the extra-field you can add extra html (by example formcontrols) to the option. If you do so, you should compare pid with getID() and also check name before adding things to extra
plugid
plugin ID (compare with GetID() to find out if this concerns you) (only present when context is global)
contextid
context ID (blogid, memberid, catid, itemid depending on context)
PrePluginOptionsUpdate (v3.2) Before the options for a plugin have been updated. (using this event you can validate/change the new value for an option)
context
(v2.2) global, member, blog, item or category
plugid
plugin ID (compare with GetID() to find out if this concerns you)
optionname
Name of the option
contextid
context ID (blogid, memberid, catid, itemid depending on context)
value
New value for the option
PostPluginOptionsUpdate (v2.0b) After the options for a plugin have been updated.
(v2.2) Different parameters depending on context
context
(v2.2) global, member, blog, item or category
plugid
plugin ID (compare with GetID() to find out if this concerns you) (global context)
blogid
(v2.2) blog ID (blog context)
blog
(v2.2) BLOG object (blog context)
memberid
(v2.2) member ID (member context)
member
(v2.2) MEMBER object (member context)
catid
(v2.2) category ID (category context)
itemid
(v2.2) item ID (item context)
member
(v2.2) ITEM object (item context)
PostAuthentication (v2.0b) After the login procedure has been completed. This occurs on each page request.
loggedIn
result of $member->isLoggedIn()
PreAddItemForm (v2.0b) Immediately before an add item form (bookmarklet or admin area) is created.
contents
reference to an associative array, in which the values 'title', 'body' and 'more' can be filled with initial values for the formfields. To avoid multiple plugins to alter these values, set the 'hasBeenSet' value to 1 when you're done (and check for it before starting)
blog
reference to a BLOG object
AddItemFormExtras (v2.0b) Somewhere inside the add item page or bookmarklet. Here, plugins can add their custom fields without having to alter one of the .template files.
blog
reference to a BLOG object
EditItemFormExtras (v2.0b) Somewhere inside the edit item page or bookmarklet. Here, plugins can add their custom fields without having to alter one of the .template files.

Don't add too much data, and please generate valid XHTML, looking like this:
<h3>plugin name</h3>
<p>your stuff</p>
This way, multiple plugins can add options here while things keep a good structure. Also try to use prefixes for your fieldnames, in order to avoid nameclashes (e.g. plug_tb_url)
blog
reference to a BLOG object
variables
(read-only) An associative array containing all sorts of information on the item that's being edited: 'itemid', 'draft', 'closed', 'title', 'body', 'more', 'author', 'authorid', 'timestamp', 'karmapos', 'karmaneg', 'catid'
itemid
shortcut to the item ID
BlogSettingsFormExtras (v2.0) On the blog settings page. You can add your own forms here.

Don't add too much data, and please generate valid XHTML, looking like this:
<h4>plugin name</h4>
<form method="post" action="..."><p>
your stuff
</p></form>
This way, multiple plugins can add options here while things keep a good structure. Also try to use prefixes for your fieldnames, in order to avoid nameclashes (e.g. plug_tb_url)
blog
reference to a BLOG object
PreDeleteItem (v2.0) Immediately before an item gets deleted in the database
itemid
id of the item that will be deleted
PostDeleteItem (v2.0) Immediately after an item has been deleted in the database
itemid
id of the deleted item
PreDeleteCategory (v2.0) Immediately before a category gets deleted from the database
catid
category ID
PostDeleteCategory (v2.0) Immediately after a category has been deleted from the database
catid
category ID
PreDeleteBlog (v2.0) Immediately before a blog gets deleted from the database
blogid
ID of the blog that will be deleted
PostDeleteBlog (v2.0) Immediately after a blog has been deleted from the database
blogid
ID of the blog that was deleted from the database
PreDeleteMember (v2.0) Immediately before a member gets deleted from the database
member
reference to the MEMBER object associated with the member that needs to be deleted
PostDeleteMember (v2.0) Immediately after a member has been deleted from the database
member
reference to the MEMBER object associated with the member that has been deleted
PreDeleteTeamMember (v2.0) Immediately before a member gets deleted from a weblog team
member
reference to the MEMBER object
blogid
ID of the blog
PostDeleteTeamMember (v2.0) Immediately after a member has been deleted from a weblog team
member
reference to the MEMBER object
blogid
ID of the blog
PreDeleteComment (v2.0) Immediately before a comment gets deleted from the database
commentid
ID of the comment that will be deleted
PostDeleteComment (v2.0) Immediately after a comment has been deleted from the database
commentid
ID of the deleted comment
ActionLogCleared (v2.0) After the action log has been cleared None
PreDeleteTemplate (v2.0) Immediately before a template gets deleted from the database
templateid
ID of the template that will be deleted
PostDeleteTemplate (v2.0) Immediately after a template has been deleted from the database
templateid
ID of the deleted template
PreDeleteSkin (v2.0) Immediately before a skin gets deleted from the database
skinid
ID of the skin that will be deleted
PostDeleteSkin (v2.0) Immediately after a skin has been deleted from the database
skinid
ID of the deleted skin
PreDeletePlugin (v2.0) Immediately before a plugin gets deleted from the database
plugid
ID of the plugin that will be deleted
PostDeletePlugin (v2.0) Immediately after a plugin has been deleted from the database
plugid
ID of the deleted plugin
PreDeleteBan (v2.0) Immediately before an IP ban gets deleted from the database
blogid
ID of the blog for which the ban will be deleted
iprange
banned IP range
PostDeleteBan (v2.0) Immediately after an IP ban has been deleted from the database
blogid
ID of the blog for which the ban has been deleted
iprange
banned IP range
PreAddCategory (v2.0) Immediately before a new category is created in the database
blog
reference to BLOG object
name
name of new category
description
description of new category
PostAddCategory (v2.0) Immediately after a new category has been created in the database
blog
reference to BLOG object
name
name of new category
description
description of new category
catid
New category ID
PreAddBlog (v2.0) Immediately before a new blog is created
name
name of new blog
shortname
shortname of new blog
timeoffset
time offset of new blog
description
description of new blog
defaultskin
ID of default skin for new blog
PostAddBlog (v2.0) Immediately after a new blog has been created
blog
new BLOG object
PreAddPlugin (v2.0) Immediately before a plugin is added
file
filename of the new plugin
PostAddPlugin (v2.0) Immediately after a plugin has been added
plugin
An object of the newly added plugin
PreAddTeamMember (v2.0) Immediately before a member gets added to a blog team
blog
BLOG object
member
MEMBER object
admin
boolean indicating if the newly added member will have blog admin rights or not
PostAddTeamMember (v2.0) Immediately after a member has been added to a blog team
blog
BLOG object
member
MEMBER object
admin
boolean indicating if the newly added member has admin rights or not
PreAddTemplate (v2.0) Immediately before a new template is created (note: this one also gets called when a template is cloned))
name
name of the new template
description
description of the new template
PostAddTemplate (v2.0) Immediately after a new template has been created
name
name of the new template
description
description of the new template
templateid
ID of the new template
PreAddSkin (v2.0) Immediately before a new skin is created (note: this one also gets called when a skin is cloned))
name
name of the new skin
description
description of the new skin
type
content type of the skin
includeMode
includeMode of the new skin
includePrefix
includePrefix of the new skin
PostAddSkin (v2.0) Immediately after a new skin has been created
name
name of the new skin
description
description of the new skin
type
content type of the skin
includeMode
includeMode of the new skin
includePrefix
includePrefix of the new skin
skinid
ID of the new skin
PreAddBan (v2.0) Immediately before a new ban is added to a weblog
blogid
ID of the blog
iprange
IP range to be banned
reason
textual message describing the reason for the ban
PostAddBan (v2.0) Immediately after a new ban has been added
blogid
ID of the blog
iprange
IP range to be banned
reason
textual message describing the reason for the ban
PreMoveItem (v2.0) Immediately before an item is moved to another blog/category
itemid
ID of the item
destblogid
ID of the destination blog
destcatid
ID of the destination category
PostMoveItem (v2.0) Immediately after an item has been moved to another blog/category
itemid
ID of the item
destblogid
ID of the new blog
destcatid
ID of the new category
PreMoveCategory (v2.0) Immediately before a catgeory is moved to another blog
catid
ID of the catgeory
sourceblog
source BLOG object
destblog
destination BLOG object
PostMoveCategory (v2.0) Immediately after a catgeory has been moved to another blog
catid
ID of the catgeory
sourceblog
source BLOG object
destblog
destination BLOG object
MemberSettingsFormExtras (v2.0) On the member settings page. You can add your own forms here.

Don't add too much data, and please generate valid XHTML, looking like this:
<h4>plugin name</h4>
<form method="post" action="..."><p>
your stuff
</p></form>
This way, multiple plugins can add options here while things keep a good structure. Also try to use prefixes for your fieldnames, in order to avoid nameclashes (e.g. plug_tb_url)
member
reference to a MEMBER object
GeneralSettingsFormExtras (v2.0) On the general settings page. You can add your own forms here.

Don't add too much data, and please generate valid XHTML, looking like this:
<h4>plugin name</h4>
<form method="post" action="..."><p>
your stuff
</p></form>
This way, multiple plugins can add options here while things keep a good structure. Also try to use prefixes for your fieldnames, in order to avoid nameclashes (e.g. plug_tb_url)
None
AdminPrePageHead (v2.5) On admin area pages, immediately before the page head is printed. This event could be used to add extra script/css includes in the head section
extrahead
Extra information to be included in the head section of the HTML page. Append your extras here.
action
Currently executed action or pagetype
AdminPrePageFoot (v2.5) On admin area pages, immediately before the page footer is printed.
action
Currently executed action or pagetype
PreSendContentType (v2.5) Immediately before a content type is being set in the HTTP header
contentType
content type (e.g. application/xhtml+xml)
charset
Character set
pageType
String indicating which type of page we're displaying: skin (skinparts), media (media library), admin-action (admin area), bookmarklet-action (bookmarklet)
QuickMenu (v2.5) At the end of the Admin Area quick menu. This can be used to add extra plugin entries. To add entries, push associative arrays on the options array. An example can be found in the section about creating a plugin admin area.
options
Array
BookmarkletExtraHead (v2.5) Somewhere inside the head section of the bookmarklet XHTML code.
extrahead
Information to be included in the head section of the XHTML code. Add your extras here.
FormExtra (v3.2) Inside one of the comment, membermail or account activation forms. This event allows plugins to insert extra fields in the form. This event corresponds with the ValidateForm event that is fires when the form is handled.
type
Type of the form from which the event fired.
  • activation
  • additemform (note: this is not the add item form from the admin area!)
  • commentform-loggedin
  • commentform-notloggedin
  • membermailform-loggedin
  • membermailform-notloggedin
member
When type is activation, this field contains the details of the member that's being activated
ValidateForm (v3.2) Called when one of the comment, membermail or account activation forms is being handled. This event allows plugins to perform their own validation on the data, and prevent further handling if something is wrong. When used together with the FormExtra field, it can be used to add extra fields to forms.
type
Type of the form being handled
  • membermail
  • comment
  • activation
error
When the plugin wants to stop the handling of the form, it needs to fill out a non-empty error string message in this error field. This error message will then be presented to the user.
comment
On comment-type forms, contains an associative array with the comment data.
member
On activation-type forms, contains information about the member being activated.

Saving options back to top

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:

  1. Global options: Editable on the admin area from the plugins section.
  2. Blog options: Editable from the blogsettings pages.
  3. Category options: Editable from the blogsettings pages (on the 'edit category' page).
  4. Member options: Editable on the 'edit member' pages
  5. Item options: Editable on the 'add item' or 'edit item' pages

Option types

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

Option meta

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');

Restrictions

  1. The name of an option can contain a maximum of 20 characters
  2. The description of an option can contain a maximum of 255 characters
  3. The value for an option has no limit (Prior to v2.5 the limit was 128 characters)
  4. The characters '=', '|' and ';' can not be used inside a select list (for a select-option), or in option-metadata

The methods

createOption($name, $desc, $type, $defValue = '', $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)

[v2.2] createBlogOption($name, $desc, $type, $defValue = '', $typeExtras = '')

Creates an option in the blog context (see createOption)

[v2.2] createCategoryOption($name, $desc, $type, $defValue = '', $typeExtras = '')

Creates an option in the category context (see createOption)

[v2.2] createMemberOption($name, $desc, $type, $defValue = '', $typeExtras = '')

Creates an option in the member context (see createOption)

[v3.2] createItemOption($name, $desc, $type, $defValue = '', $typeExtras = '')

Creates an option in the item context (see createOption)

setOption($name, $value)

changes the value of an option that was already in the database

parameter value
$name Option name
$value New value for option

[v2.2] setBlogOption($blogid, $name, $value)

Changes the value for a blog option. The blogid attribute indicates for which blog the option is valid. (other options: see setOption)

[v2.2] setCategoryOption($catid, $name, $value)

Changes the value for a category option. The catid attribute indicates for which category the option is valid. (other options: see setOption)

[v2.2] setMemberOption($memberid, $name, $value)

Changes the value for a member option. The memberid attribute indicates for which member the option is valid. (other options: see setOption)

[v3.2] setItemOption($itemid, $name, $value)

Changes the value for an item option. The itemid attribute indicates for which item the option is valid. (other options: see setOption)

getOption($name)

Returns the value for an option in the database

parameter value
$name Option name

[v2.2] getBlogOption($blogid, $name)

Returns the value for a blog option. blogid indicates for which blog a value is requested (other parameters: see getOption)

[v2.2] getCategoryOption($catid, $name)

Returns the value for a category option. catid indicates for which category a value is requested (other parameters: see getOption)

[v2.2] getMemberOption($memberid, $name)

Returns the value for a member option. memberid indicates for which member a value is requested (other parameters: see getOption)

[v3.2] getItemOption($itemid, $name)

Returns the value for an item option. itemid indicates for which item a value is requested (other parameters: see getOption)

deleteOption($name)

Deletes an option from the database

parameter value
$name Option name

[v2.2] deleteBlogOption($name)

Deletes a blog option (see deleteOption)

[v2.2] deleteCategoryOption($name)

Deletes a category option (see deleteOption)

[v2.2] deleteMemberOption($name)

Deletes a member option (see deleteOption)

[v3.2] deleteItemOption($name)

Deletes an item option (see deleteOption)

[v2.2] getAllBlogOptions($name)

Returns all values for a given blog option. The result is an associative array with a value for each existing blogid

[v2.2] getAllCategoryOptions($name)

Returns all values for a given category option. The result is an associative array with a value for each existing catid

[v2.2] getAllMemberOptions($name)

Returns all values for a given member option. The result is an associative array with a value for each existing memberid

[v3.2] getAllItemOptions($name)

Returns all values for a given item option. The result is an associative array with a value for each existing itemid

[v3.2] getBlogOptionTop($name, $amount = 10, $sort = '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 blogid ('id')

parameter value
$name Option name
$amount The amount of options you want
$sort Sort ascending ('asc') or descending ('desc')

[v3.2] getMemberOptionTop($name, $amount = 10, $sort = '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)

[v3.2] getCategoryOptionTop($name, $amount = 10, $sort = '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 categoryid ('id') (parameters: see getBlogOptionTop)

[v3.2] getItemOptionTop($name, $amount = 10, $sort = '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 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.

Database tables back to top

Access to Nucleus tables

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:

  1. Instead of using a fixed tablename like nucleus_item, use the global function sql_table('item') to generate the prefixed tablename
  2. Make sure your plugin returns 1 (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 {
...
}

?>

Your own tables

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

Plugin Admin Area back to top

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.

Basics

To provide an admin area, you'll need take these steps:

  1. Create a subdirectory of the plugins directory, and name it pluginname if your plugin is NP_PluginName. Note that the name should be lowercase!
  2. In that directory, create a file called index.php, which looks like this:
    <?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();
    
    ?>
  3. Subscribe to the 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'
    			)
    		);
    	}
  4. Implement this method in your plugin:
    function hasAdminArea()
    {
    	return 1;
    }

Considerations

The PluginAdmin class

The purpose of the PluginAdmin is to help you. Once created, you can use $oPluginAdmin->plugin to access the instance of your plugin.

Plugin HelpPage back to top

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.

Basics

To provide a helppage, you'll need take these steps:

  1. Create a subdirectory of the plugins directory, and name it pluginname if your plugin is NP_PluginName. Note that the name should be lowercase! This is actually the same directory as for the admin area.
  2. In that directory, create a file called help.html. In this file you can document your plugin. This is a good template to start from:
    <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>
  3. Return a value larger than 0 for supportsFeature('HelpPage'):
    function supportsFeature($what) {
    	switch($what) {
    	case 'HelpPage':
    		return 1;
    	  default:
    		return 0;
    	}
      }

Plugin Dependency Check back to top

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.

How to write a plugin that utilize this function

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.