Getting started with plugin development
This page will describe the practical steps required to create a plug-in from a GitHub repository and published as an NPM package. We will use a minimal example based on adding a new datatype for angular degrees. The finished example is available as the saltcorn/angles-type repository on GitHub. Note that you do not have to use GitHub or for that matter any kind of version control, you can use any other method you are familiar with for creating an NPM package.
1. Create a GitHub repository
Create a GitHub repository on the your account. You should add a .gitignore file based on the Node template. If you are contributing this to the Saltcorn store, you will also need to choose a licence. Clone this repository into your home directory. For the example repository name, to clone this repository in my home directory I run on the command line: git clone [email protected]:saltcorn/angles-type.git
. If you enter this directory (cd angles-type
) and list the files (ls
) there should now only be a single file present: the LICENCE file.
2. Create package and index files
You need to create at least two files in your new package: the package.json
which describes the contents of the NPM package, and a JavaScript file containing the code for the plug-in. We will call this JavaScript file index.js
but you can give it a different name as long as you put the chosen filename in the main
field in the package.json
. Typically, the JavaScript file is either called index.js
or it is the name of the plug-in followed by .js
but this is just our convention.
The package.json should look something like this:
{
"name": "saltcorn-angles-type",
"version": "0.1.0",
"description": "Angular degrees data type",
"main": "index.js",
"dependencies": {},
"author": "Tom Nielsen",
"license": "MIT",
"repository": "github:saltcorn/angles-type",
"publishConfig": {
"access": "public"
}
}
The name
field is the name of the NPM package (this does not have to match your repository name).
You should list any Saltcorn packages you are going to import modules from under dependencies
.
A blank module JavaScript file (in our case, index.js
) need only export an object with a single field sc_plugin_api_version
indicating the version of the Saltcorn plug-in API used. Currently, only one version is supported, version 1
. Therefore our minimal plug-in which does absolutely nothing, has the following JavaScript file (index.js
):
module.exports = { sc_plugin_api_version: 1 };
Let's load this into a locally running Saltcorn instance so we can check that the plug-in load correctly.
3. Installing a local plugin
Make sure you are running Saltcorn locally on your desktop, either a development environment based on SQLite or with a PostgreSQL server running in the background. Also make sure you are logged in to an account with administrative privileges.
Go to the "Plugins" menu option under "Settings". Near the top right hand corner, there is a button with three dots that expand into a drop-down menu. Choose the option "Add another plugin" (because we will be installing a plug-in that is not in the store) from this menu.
You will then see a form that lets you enter the details of a plug-in. Choose these options:
- Name: the name of the plug-in as you specified it in the
name
field in the package.json file, here "saltcorn-angles-type". - Source: choose "local"
- Location: enter the full path to the directory that contains your plug-in. It does not matter whether you end in a slash or not
Then click Create. If everything works, then after a few seconds you should be directed back to the plug-in store with a success message: "Plugin saltcorn-angles-type installed".
Alternatively (easier, 2024):
if your local plugin is cloned in your home directory, you can install it on the command line with:
saltcorn install-plugin -d /path/to-plugin
You can also swap between local and npm installs. Use
saltcorn dev:localize-plugin /path/to/plugin
To change a plug-in that has been installed from NPM via the module store to running off a local checkout. Use
saltcorn dev:localize-plugin -u
To go the other way to convert a local install to npm install
4. Running server while developing
We are currently using this command to run in development mode
npm run tsc; while [ 1 ]; do SALTCORN_NWORKERS=1 saltcorn serve --dev;done
This will restart the server whenever you save changes to a file from a local plug-in or from the core saltcorn code
5. Commit and publish
Because this part of the tutorial is about the practical aspects, we will now see how to publish this (entirely useless) plugin. In the next part we will actually be defining our new datatype.
As we have made a little bit of progress, setting up the plug-in directory structure, we should now commit with git and push to GitHub. If you are using the git command line, run git commit -am 'blank plugin' && git push
. If you're using a graphical git client, perform the equivalent actions.
To publish this to NPM, you should have an NPM account set up and be logged in from the command line with npm login
- you only have to do this once and it will remember your login, even after you restart your computer. To publish your plug-in, run npm publish
. If you are publishing under an organisation, you may get an error message stating that payment is required. Simply run again with npm publish --access=public
.
6. Beware dragons
In former example of package.json above there was dependencies of saltcorn packages (namely data and markup), but there are bug in npm that forces you to skip this dependecies ever if eslint insists:
It you adding, for example, @saltcorn/data
to package.json, it will be installed to your plugin's node_modules and will be different than one that used by saltcorn itself. It's impractical but harmful for stateless packages like @saltcorn/markup, but very dangerous for data, server, db-common and so on. I.e. getState() will return non-initialized singleton instead of actual tenant state, and so on.