Each Content Item (such as a note, image, document or table) has a number of Control Icons attached to it. The most common ones are:
Common controls are made available to the individual plugins using methods provided by the
Individual plugins are free to make use of those controls as they deem fit - though a uniform look is encouraged.
Some plugins also implement special controls; for example, the
notes plugin (formatted HTML notes) also implements a revision (history) feature - and provides a control to access that feature.
EXAMPLE: outline of implementing a control in a plugin
documents plugin (to store documents of any type, such as PDF or MS Word files), like all plugins, needs to provide a DELETE control. All it has to do is:
pluginSupportclass, which returns the control (HTML code, including graphs and links.) The code for the request is:
$this->pluginSupport->controlLinks_Delete($this->pluginCode, $docID, $categoryID);
deleteObject($objectID), to carry out the actual deletion of the Content Item. This method gets invoked by the control generated in step 1.
Every plugin is required to provide a set of standard methods to implement (its share of) the work to perform the actual actions of the various standard controls. The Core module automatically takes care of the rest of the work.
For example, the
deleteObject($objectID) implemented by the
documents plugin takes care of deleting the actual document file, as well as deleting the record of that document kept by the plugin. The higher-level method
controlLinks_Delete, provided by the
pluginSupport class, in addition to invoking the plugin-specific
deleteObject method, also invokes methods provided by the Core module. These methods take care of, for example, clearing records associated with general properties of the Content Item being deleted, such as its size and permissions.
In short: a lot of the work is done by the Core module, and accessed by individual plugins through the
pluginSupport class. This makes plugin implementation vastly easier.
createDialogBoxin viewer.php, with the last argument being the JS function
populateEditMetadataBox, in viewer.php, fetches from the server the HTML code to provide a way to edit the specified Content Item's metadata
fetchFromServer, in core.js, which uses the
fetchAPI to contact
plugin=cm&handler=editMetadata&mode=embed&itemType=d&itemID=1234, where 1234 is the ID of the document in question. The full server invocation is:
contentManager(for now inside siteInitialization.php). That's the class that provides the requested method
editMetadata(the "handler" prefix is implied.)
What happens when a user requests to add a new content item? For example, when creating a note or a site link (annotated web bookmark)... or uploading a photo or document.
BRIEF SUMMARY FOR PLUGIN DEVELOPERS
Provide the following methods in your plugin class:
handler_addContentModule(): assembles and returns HTML (typically a form) to let the user define the new content.
addObject(): takes care of the housekeeping operations involved in adding the new content item. It must return the ID assigned the newly-added content item; in case of failure, the plugin is expected to throw an exception.
Plugins may either handle their own database tables (high-level API provided) or, as of version 3.1, take advantage of a new (RDF-style) triple store, which is strongly recommended.
If your plugin uses a form to create new content, you can copy and adapt, for example, the counterpart methods in the
siteLinks plugin (in the file
If your plugin uploads files (such as photos or documents), see also Uploading Content.
PART 1 - Letting the user specify what they want to add : CLIENT-SIDE, viewer.php
viewer.php) toggles the visibility of the box used to add Content Items (initially hidden), if it already exists - or dynamically creates it otherwise
addItem_XYZfor some value XYZ, where XYZ is of the form "previousItemType_previousItemID" (e.g. "n_12"), or "0" if inserting at the very beginning of the page. That ID value is used to uniquely identify the box to use, and it indirectly indicates the position (in the ordered list of Content Items attached to the current Category) after which to insert the new item
addItem, with the following arguments:
addImmediateItem(), for Content Items that require no parameters at their creation (e.g. the clock plugin).
addImmediateItem()takes the following arguments:
PART 2 - Specifying parameters to the newly-created Content Items (when applicable)
addItemcreates and displays a dynamically-generated, plugin-provided DIV element (such as a form) that can be used to add a Content Item of the specified type at the requested position (order ID) on the page.
addItemreplaces the original, generic "Add new content" box (for all plugin types) with one specific to the chosen plugin, with an actual data-entry form
obtainAddFormFromServer, which contacts ther server-side script
PART 3 - Letting the user specify what they want to add : SERVER-SIDE, pluginHandler.php
pluginHandler.php, which dispatches the call to the appropriate plugin object (depending on the plugin code), and invokes a method called
handler_addContentModule()in that plugin object
handler_addContentModule()method must assemble and return an HTML form. This form gets returned to the front-end
addItem, which inserts it in the page, in lieu of the original new-content addition box
formBuilderclass (one of Brain Annex common modules)
doAddContent.php?type=CODE, where CODE is the plugin code. The form must also pass hidden inputs for
PART 4 - Adding the new content specified by the user
doAddContent.phpis part of the core module. The bulk of the work is done in the invocation of the method
addNewContentItemmethod (part of the
contentManagerclass, for now hosted in the file
siteInitialization.php) dispatches tasks to various housekeeping modules, such as
categories... and finally invokes the plugin-specific method
addObject(), for the plugin that started the new content addition process. This concludes the operations by the form handler. The new Content Item is now created and appropriately catalogued - with most of the work done by the core modules, and just the bare minimun by the plugin itself!
viewer.php) offer pop-up boxes to add new content
uploadermodule to take care of the actual upload
coremodule, to handle permissions, resource usage, setting the position of the uploaded item on the page, and to command the individual content-specific plugin to do its own management (such as maintaining a table of items and their metadata, creating thumbnails of uploaded images, etc.)
viewer.php) instantiates the core module (aka the orchestrator module), which in turn initiates all plugins and other modules
addItemList, with the position in the page passed as argument
addItemListtoggles the reveal/hide a box used to add Content Items. The box's ID is
addItem, with 2 arguments: the ID of the pop-up box (representing the position in the page where to insert the new item) and the code for the plugin that handles that particular content type. For example, for document upload, the involved plugin is "documents", with plugin code "d"
addItemuses XMLHttpRequest to contact the
pluginHandler.phpscript on the server. Various arguments are passed, including the code for the plugin type (for example "d" for "documents") and the method to use, which for uploading is
pluginHandler.phpscript on the server receives the XMLHttpRequest, then selects the appropriate plugin (for example "documents") and invokes the passed method (
addContentModule). Each content plugin that provides file upload must implement method by that name: it generates and returns an HTM form to upload files specific to that plugin type
class='dropzone' id='myDropzone_pluginCode', where pluginCode varies by plugin. The dropzone elements are used to interface with the dropzone software, which handles the front-end of the uploads, including the drag-and-drop graphics
doAddContent.phpscript. It contacts the
uploadermodule, which receives and processes the file just uploaded to the server. The uploader also accepts a customizable function, named
nameHandler, provided by the calling code in the
nameHandler, is where plugin-specific actions take place. The
nameMappingmethod of the plugin in question (for example, "documents") is invoked – the plugins decides what name to store the file under. Next, the
addNewContentItemmethod of the core module is invoked, with information about the just-uploaded file (such as its type, size and the original file name.)
addNewContentItemmethod of the core module (in the file
siteInitialization.php) performs various actions:
categoriesmodule to set the permissions of the newly-uploaded content object (new uploads inherit the permissions of the Category they are uploaded into)
resourceUsagemodule to store the filesize
categoriesmodule to insert the new object in the specified position in the Category it was uploaded into
addObjectmethod of the particular plugin in question, to let the plugin take care of accepting the uploaded content item. Arguments passed include the metadata and the full name of the temporary file being used for the upload (e.g. "/tmp/phpE2qaT3") – since the upload process has not yet been completed
uploadermodule, and the upload is completed!
viewer.php) offer clickable icons to delete content
pluginHandler.phpdispatches the deletion request to the method
doDeleteContentItem, provided by the class
contentManager(for now hosted in the file siteInitialization.php)