Quickstart: Plugins

Brian edited this page Mar 17, 2015 · 14 revisions

Jump to:

Plugins are the way to change the look and functionality of PencilBlue, which was designed, from the ground up, to be modified in almost any way imaginable. Plugins can be themes, feature additions, changes to core functionality, or even services that other plugins can build off of.

The Basics of Plugins

All plugins are stored in the /plugins directory, where they have their own folder, each one with a unique name. PencilBlue comes out-of-the-box with five plugins:

  • PencilBlue theme - the default theme of the platform /plugins/pencilblue
  • Portfolio theme - a theme designed for portfolio and brand sites /plugins/portfolio
  • Google Analytics - track site traffic with Google Analytics /plugins/ga
  • WordPress importer - import your WordPress blog into PencilBlue /plugins/wp_import
  • Sample plugin - an example plugin for developer reference /plugins/sample

The details.json File

Every plugin must have a details.json file in the root of its directory. This file describes the plugin to PencilBlue and defines settings to be used when the plugin is installed. Here are the common variables in a details.json file:

Variable Description
uid The unique ID of the plugin. This should be the same as the name of the plugin's folder.
name The name of the plugin to be displayed to the user.
description The description of what the plugin does.
icon The path to the fav icon. The path should be relative to the public folder for your plugin
pb_version The semantic version expression that indicates which versions of PencilBlue will work with the plugin
version The current version of the plugin.
author The creator of the plugin, including name, email, website, and individual contributors.
settings Settings for the plugin that will be changeable by the user. They are an array of objects with the setting name and default value.
permissions Custom permission sets that can be assigned to the roles within PencilBlue. Note: An admin is assumed to have all permissions.
main_module The main JavaScript file of the plugin. This file describes what the plugin will do on installation, removal, startup, and shutdown.
theme Settings for theme plugins, including changeable settings and content templates that can be used for individual articles and pages.

The Main Module File

Every plugin must have a main module file that describes how the plugin is to behave under certain conditions. An example of this file can be found in the sample plugin. The file must have four functions:

  • onInstall - actions to perform when the plugin is installed
  • onUninstall - actions to perform when the plugin is uninstalled
  • onStartup - actions to perform when PencilBlue starts
  • onShutdown - actions to perform when PencilBlue shuts down

Common actions on install and uninstall are creating and destroying custom object definitions and preparing data that the plugin will use. Common actions on startup and shutdown include creating global directives for the template service and adding custom menu items to the admin section.

In this example, the Adsense plugin, on install, creates the custom object that will hold the data needed to define ads.

module.exports = function(pb) {

  // The following will happen when the plugin is installed
  Adsense.onInstall = function(cb) {
    var self = this;
    // Create a new instance of the custom object service
    var cos = new pb.CustomObjectService();

    // Check to see if an adsense_ad object type already exists
    cos.loadTypeByName('adsense_ad', function(err, adsenseAd) {
        // If the adsense_ad object type doesn't exist, define it
        if(!adsenseAd) {
            var adValues = {name: 'adsense_ad', fields: {name: {field_type: 'text'}, ad_id: {field_type: 'number'}}};
            cos.saveType(adValues, function(err, adsenseAd) {
                cb(null, true);
            });
        }
        else {
            cb(null, true);
        }
    });
  };

  ...
};

In the following example, the Google Analytics plugin registers itself with the analytics manager on startup. It retrieves the google_analytics_tracking_id and demographics_support settings from the plugin settings defined in the details.json file, and returns the appropriate tracking script string to AnalyticsManager.

// The following will happen when PencilBlue starts up
GoogleAnalytics.onStartup = function(cb) {
    // Register an analytics provider with the analytics manager
    pb.AnalyticsManager.registerProvider('google_analytics', function(req, session, ls, cb) {
        // Get the tracking ID from the GA settings
        pb.plugins.getSetting('google_analytics_tracking_id', 'ga', function(err, trackingId) {
            if(!trackingId || trackingId.length === 0) {
                cb(null, '');
                return;
            }
            // Get the demographics support boolean from GA settings
            pb.plugins.getSetting('demographics_support', 'ga', function(err, demographicsSupport) {
                var website = pb.config.siteRoot.split('http://').join('').split('https://').join('');
                var script  = "<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', '" + trackingId + "', '" + website + "');" + (demographicsSupport ? "ga('require', 'displayfeatures');" : "") + "ga('send', 'pageview');</script>";

                // Pass the GA script string to the AnalyticsManager through the callback function
                cb(null, script);
            });
        });
    });
    cb(null, true);
};

Adding a Service to a Plugin

Plugins can offer services for use by themselves or other plugins. Services allow for the repeated use of common functions without having to duplicate code in every plugin performing the same actions.

All services reside in the /services folder of the plugin. All services must have an init function. This function will be called by PencilBlue when it loads the plugin into the system. The init function doesn't need to contain any functionality, but it must be there and the callback must provide TRUE as the second parameter or the service will be discarded by the plugin framework.

In this example, the sample plugin initializes its TextCreator service.

module.exports = function(pb) {

  // Initialize the service object
  function TextCreaterService() {};

  // This function will be called when PencilBlue loads the service
  TextCreaterService.init = function(cb) {
    pb.log.debug("TextCreaterService: Initialized");
    cb(null, true);
  };

  return TextCreatorService;
};

After you've initialized the service, you can create any function you want tied to that service. The service will be retrievable through the plugin service's getService function. In this example, we retrieve the sample plugin's TextCreatorService and call its getText function. The first parameter is the name of the service and the second is the uid of the plugin that owns it.

// Retrieve the object from /services/text_creator.js in the sample plugin
var TextCreator = pb.PluginService.getService('text_creator', 'sample');

var instance = new TextCreator();
instance.getText(function(err, text) {
    ...
});

Other Plugin File Types

Other plugin types are covered in their respective quickstart sections:

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.