Skip to content

basil.js Plugin System #337

Open
Open
@trych

Description

@trych

We have been talking about this in the past, I have been toying around with the idea for a while and been trying out some things.

I think we should include a simple plugin system in basil.js.

I just implemented the basics for such a system in the plugins branch that I just uploaded and even in this basic implementation the system is already quite powerful.

The current implementation works like this: The user can place a plugins folder next to the basil.js file. Within this plugins folder there can be subfolders, each of them is considered a plugin. If basil.js finds a index.jsx file in such a plugin folder, the code within will be executed. All this happens before the main script flow of the user script is started. This allows to inject new functions into the global basil namespace (so, basically to add new custom basil functions) or to overwrite existing basil functions. (Later we could also add the possibility of "hooks" that trigger at specific events like document creation or after the main script flow finishes etc.)

To allow for easy disabling of plugins, a folder can be renamed to start with an underscore (_examplePlugin), in this case the plugin will be ignored.

Additionally there is the possibility to install "local" plugins on a per script basis, by placing a plugins folder next to the script file of the user. These plugins will be registered the same way, but they only refer to the script file they are placed next to (also this local plugins folder could further come with a list of global plugins that should be ignored to be able to further fine tune the plugin structure of each single script. This is not implemented yet in the branch at its current state). Due to the nature of ExtendScript, the local plugin folder currently works only when the script is run via Sublime Text or the InDesign Scripting panel (as I have found no way to retrieve the user script file when run from ESTK or Visual Studio Code).

Just to give you a quick and very simple example what is possible and how a plugin code could look like: Let's write a script that creates a new function bananaAlert() that alerts a 🍌-emoji. Let's further alter basil's println() function in a way that it also adds some bananas to its output. A plugin like this would simply be a index.jsx file that is placed into a folder banana next to the basil.js file. The index.js file would contain code like this:

pub.bananaAlert = function() {
  alert("🍌");
}

pub.println = function() {
  // just copying basil's native println() function and tweaking it slightly
  var msg = "🍌🍌🍌 " + Array.prototype.slice.call(arguments).join(" 🍌🍌🍌 ") + " 🍌🍌🍌";
  $.writeln(msg);
  if (progressPanel)
    progressPanel.writeMessage(msg + "\n");
};

And then a user script like this

// @include ~/Documents/basiljs/basil.js;

function draw() {
  println("Your random number is " + random(100));
  println("All", "the", "single", "monkeys");

  bananaAlert();
}

would output something like this:

20191023-141740_Screenshot_SublimeText

(and alert 🍌).

Hope this all makes sense and that you agree that such a plugin architecture adds huge value to basil.js. I think it will also help us devs if we could not (right away) agree on the best implementation of a feature, so that we could just write a plugin that solves our specific problem and that could then be used in class for example.

Would love to hear your opinions and feedback, so check out the plugins branch and give it a try! 😎

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions