Add Event Listeners
The bulk of the work of an Antora extension is done by the event listeners.
An event listener is a function that’s called whenever an event it’s listening for is emitted.
Any value returned by the listener is ignored.
The register function is responsible for associating these listener functions with particular events.
It does so by passing the event name and the listener function to the on
method of the generator context, called adding a listener.
The API of the generator context follows that of a Node.js EventEmitter.
Let’s build on the extension we have defined by updating it to add an event listener.
We’ll listen for the playbookBuilt
and sitePublished
events, which are the first and last events to be emitted by the generator.
This gives us the opportunity to roughly measure how long it took to generate and publish the site.
module.exports.register = function () {
this
.on('playbookBuilt', () => {
console.time('generation time')
})
.on('sitePublished', () => {
console.timeEnd('generation time')
})
}
In Example 1, we use the on
method of the generator context to add two listeners, one for when the playbookBuilt
event is emitted and one for when the sitePublished
event is emitted.
The on
method returns the generator context, so we can use it to chain calls, as show in the previous example.
Since built-in events are only emitted once, you can register the listener for a built-in event using
Using |
By default, listeners are invoked in the order they are added.
To guarantee our timer starts before listeners from other extensions are called, our playbookBuilt
listener should be called before other listeners of the playbookBuilt
event and our sitePublished
listener should be called after other listeners of the sitePublished
event.
There are two changes we must make to get this to work.
First, we can use the prependListener
method as an alternative to on
to add the playbookBuilt
listener before other listeners that have already been associated with that event.
module.exports.register = function () {
this
.prependListener('playbookBuilt', () => {
console.time('generation time')
})
.on('sitePublished', () => {
console.timeEnd('generation time')
})
}
Second, we should list our extension last in the playbook. Taking these two steps ensures our timer runs around all other listeners.
If you want to time a specific stage of the generator, you can update this extension to listen to other generator events.
To extend the timer all the way to when Node.js exits, you can listen for the
To learn more about the |
The EventEmitter API, which the generator context inherits, also allows listeners to be retrieved, removed, and added again. That opens up the possibility that one extension can rearrange listeners added by other extensions, if the need arises. Extensions can also emit and listen for custom events using the same methods.
To do something more interesting than time the execution and print messages to the console, we need to use context variables. Let’s learn how that’s done next.