You are looking at the old Apostrophe 0.5 documentation. It is deprecated for new projects. Check out the latest version!

Command line tasks in Apostrophe

← Previous: Scene upgrades: when anonymous visitors need access to fancy features

We often need to carry out command line tasks with access to the same database and capabilities that regular Apostrophe code has access to. Apostrophe makes it really easy to register command line tasks as part of your application.

If the command line is:

node app.js

The app will start listening for connections as usual. But if it is:

node app.js project:send-emails

The app will execute that task. We'll see how to implement that task below.

To see the available tasks, just type:

node app.js apostrophe:help

This will list all of the registered tasks.

Registering your own tasks

All you have to do is include a tasks option in app.js. Each task is a simple callback function that takes four arguments, site, apos, argv, and callback. Tasks are grouped together into categories.

Here's an example:

tasks: {
  project: {
    sendEmails: function(site, apos, argv, callback) {
      // Do time consuming, asynchronous things!
      // When we're finished:
      return callback(null);
    }
  }
}

This structure allows for projects with many tasks, grouped into categories.

The code above allows us to run this task:

node app project:send-emails

Task names are alwaysCamelCase in the source code. On the command line, you have a choice: you can type them like this...

node app project:send-emails

Or like this:

node app project.sendEmails

Accessing command line arguments

It's really, really easy.

If there is a --go option on the command line, here's how to test for that in your task:

if (argv.go) { ... }

If there is a --color=blue option, that's easy to access to:

console.log(argv.color);

You can also access positional arguments. If the user types:

node app project:send-emails 100

You can access that extra argument as argv._[1]. (argv._[0] is the name of your task.)

See the optimist module for more information.

"What if an error happens?"

Pass it to the callback.

"How do I call methods that need a req object?"

Good question. Lots of Apostrophe methods expect a req object, because permissions are tied to the identity of the user, and certain types of caching are tied to the lifetime of a request.

If your task needs to call a function like snippets.get which requires a req object, call this function to get a req object that always has unlimited permissions:

apos.getTaskReq()

"How do I hook into existing tasks?"

The apos object is an EventEmitter. In English, that means you can write:

apos.on('task:apostrophe:migrate:before', function() {
  apos.taskBusy();
  // Do a variety of things asynchronously
  apos.taskDone();
}

Or:

apos.on('task:apostrophe:migrate:after', function() {
  apos.taskBusy();
  // Do a variety of things asynchronously
  apos.taskDone();
}

"What do apos.taskBusy and apos.taskDone do?"

These only matter if you're hooking into an existing task.

Apostrophe needs to know when your event handler is finished. But you're likely to call asynchronous functions (functions with callbacks), so Apostrophe can't just assume that your event handler is finished when it returns.

apos.taskBusy() solves this problem. If your event handler needs to do lots of asynchronous stuff, call apos.taskBusy(). Apostrophe will not move on until you call apos.taskDone().

Next: Indent and Outdent in the rich text editor →