Saturday, 13 August 2016

Post 63: writing nodeBB plugin

Structure and files:
# nodeBB-plugin-thad-test
|  # lib
|  |  - controllers.js
|  # static
|  |  # lib
|  |  |  - admin.js
|  |  |  - main.js
|  |  # templates
|  |  |  # admin
|  |  |  |  # plugins
|  |  |  |  |  - thadTest.tpl
|  - library.js
|  - package.json
|  - plugin.json
|  - README.md
|  - ... (other files that are not important though like README.md; .gitignore; .npmignore)

----------------
The file content:
controller.js

'use strict';

var Controllers = {};

Controllers.renderAdminPage = function (req, res, next) {
 /*
  Make sure the route matches your path to template exactly.

  If your route was:
   myforum.com/some/complex/route/
  your template should be:
   templates/some/complex/route.tpl
  and you would render it like so:
   res.render('some/complex/route');
 */

 res.render('admin/plugins/thadTest', {});
};

module.exports = Controllers;
admin.js

'use strict';
/* globals $, app, socket */

define('admin/plugins/quickstart', ['settings'], function(Settings) {

 var ACP = {};

 ACP.init = function() {
  Settings.load('quickstart', $('.quickstart-settings'));

  $('#save').on('click', function() {
   Settings.save('quickstart', $('.quickstart-settings'), function() {
    app.alert({
     type: 'success',
     alert_id: 'quickstart-saved',
     title: 'Settings Saved',
     message: 'Please reload your NodeBB to apply these settings',
     clickfn: function() {
      socket.emit('admin.reload');
     }
    });
   });
  });
 };

 return ACP;
});


main.js
"use strict";

(function() {
 /*
  This file shows how client-side javascript can be included via a plugin.
  If you check `plugin.json`, you'll see that this file is listed under "scripts".
  That array tells NodeBB which files to bundle into the minified javascript
  that is served to the end user.

  Some events you can elect to listen for:

  $(document).ready();   Fired when the DOM is ready
  $(window).on('action:ajaxify.end', function(data) { ... });   "data" contains "url"
 */

 console.log('nodebb-plugin-thad-test: Hello world');
 // Note how this is shown in the console on the first load of every page
}());


thadTest.tpl

thadTest Settings
Adjust these settings. You can then retrieve these settings in code via: meta.settings.get('quickstart');


library.js
"use strict";

var controllers = require('./lib/controllers'),
 plugin = {};

plugin.init = function(params, callback) {
 var router = params.router,
  hostMiddleware = params.middleware,
  hostControllers = params.controllers;
  
 // We create two routes for every view. One API call, and the actual route itself.
 // Just add the buildHeader middleware to your route and NodeBB will take care of everything for you. 
 router.get('/admin/plugins/quickstart', hostMiddleware.admin.buildHeader, controllers.renderAdminPage);
 router.get('/api/admin/plugins/thadTest', controllers.renderAdminPage);
 
 callback();
};

plugin.addAdminNavigation = function(header, callback) {
 header.plugins.push({
  route: '/plugins/thadTest',
  icon: 'fa-tint',
  name: 'Quickstart'
 });

 callback(null, header);
};

module.exports = plugin;


package.json
{
  "name": "nodebb-plugin-thad-test",
  "version": "0.2.6",
  "description": "nodebb-plugin-thadeuszlay-test",
  "main": "library.js",
  "repository": {
    "type": "git",
    "url": "https://github.com/thadeuszlay/nodebb-plugin-thad-test"
  },
  "keywords": [
    "nodebb",
    "plugin",
    "test",
    "shell"
  ],
  "author": {
    "name": "thadeuszlay",
    "email": "thadeuszlay@gmail.com"
  },
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/thadeuszlay/nodebb-plugin-thade-test/issues"
  },
  "readmeFilename": "README.md",
  "nbbpm": {
    "compatibility": "^1.0.0"
  }
}


plugin.json
{
  "name": "nodebb-plugin-thad-test",
  "version": "0.2.6",
  "description": "nodebb-plugin-thadeuszlay-test",
  "main": "library.js",
  "repository": {
    "type": "git",
    "url": "https://github.com/thadeuszlay/nodebb-plugin-thad-test"
  },
  "keywords": [
    "nodebb",
    "plugin",
    "test",
    "shell"
  ],
  "author": {
    "name": "thadeuszlay",
    "email": "thadeuszlay@gmail.com"
  },
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/thadeuszlay/nodebb-plugin-thade-test/issues"
  },
  "readmeFilename": "README.md",
  "nbbpm": {
    "compatibility": "^1.0.0"
  }
}



README.md
# Quickstart Plugin for NodeBB

A starter kit for quickly creating NodeBB plugins. Comes with a pre-setup LESS file, server side JS script with an `action:app.load` hook, and a client-side script. Most plugins need at least one of the above, so this ought to save you some time. For a full list of hooks have a look at our [wiki page](https://github.com/NodeBB/NodeBB/wiki/Hooks), and for more information about creating plugins please visit our [documentation portal](https://docs.nodebb.org/).

Fork this or copy it, and using your favourite text editor find and replace all instances of `nodebb-plugin-quickstart` with `nodebb-plugin-your-plugins-name`. Change the author's name in the LICENSE and package.json files.

Once you're done don't forget to publish it on NPM, and make a thread about it [here](https://docs.nodebb.org/en/latest/plugins/hooks.html).


## Hello World

It will do some random stuff. As of time of writing, I don't even know myself what exactly. Really simple, just edit `static/lib/main.js` and paste in `console.log('hello world');`, and that's it!

## Installation

    npm install nodebb-plugin-thad-test

## Screenshots

Don't forget to add screenshots!

Routing

In order to display your plugin correctly in the nodeBB admin page you have to set the route correctly:

in controller.js:
Controllers.renderAdminPage = function (req, res, next) {
 res.render('admin/plugins/thadTest', {});
};



in library.js:
"use strict";

plugin.init = function(params, callback) {
...
 router.get('/api/admin/plugins/thadTest', controllers.renderAdminPage);
...
};

plugin.addAdminNavigation = function(header, callback) {
 header.plugins.push({
  route: '/plugins/thadTest',
...
  name: 'Name in the dropdown list'
 });
};

module.exports = plugin;
Tweet