Add documentation on writing hooks

This commit is contained in:
JC Brand 2022-04-26 12:44:31 +02:00
parent 18ca225450
commit a31f87f25b
3 changed files with 107 additions and 20 deletions

View File

@ -9,40 +9,47 @@ Starting up a dev environment
Installing the 3rd party dependencies
=====================================
We use development tools which depend on Node.js and npm (the Node package manager).
If you don't have Node.js installed, you can download and install the latest
version `here <https://nodejs.org/download>`_.
Alternatively you can `use your operating system's package manager to install
Node.js <https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions>`_.
Also make sure you have ``Git`` installed. `See here <http://git-scm.com/book/en/Getting-Started-Installing-Git>`_.
Now use ``git`` to check out the Converse repository:
To develop and customize Converse, you'll first need to check out Converse's Git
repository:
::
git clone https://github.com/conversejs/converse.js.git
cd converse.js
Now go into the repository checkout and run ``make dev`` in order to set up the
development environment.
We use development tools which depend on Node.js and NPM (the Node package manager).
It's recommended that you use `NVM <https://github.com/nvm-sh/nvm>`_ (the Node version manager)
to make sure you have the right version of Node.
Refer to the `NVM Github page <https://github.com/nvm-sh/nvm#install--update-script>`_ for instructions on how to install it.
Once NVM is installed, you can run the following inside your checkout of the Converse Git repository:
::
nvm install
.. note::
You will always have to first run ``nvm install`` in a new terminal session before working on Converse.
To set up the Converse development environment, you now run ``make dev``.
::
cd converse.js
make dev
If you're using Windows, or don't have GNU Make installed, you can run the
Alternatively, if you're using Windows, or don't have GNU Make installed, you can run the
following:
::
cd converse.js
npm install
npm run lerna
This will install the Node.js development tools and Converse's dependencies.
This will install the Node development tools and Converse's dependencies.
The front-end dependencies are those JavaScript files on which
Converse directly depends and which will be loaded in the browser as part of
@ -80,3 +87,4 @@ under the `GPLv3 <https://github.com/signalapp/libsignal-protocol-javascript/blo
which requires all other dependent JavaScript code to also be open sourced under the same
license. You might not be willing to adhere to those terms, which is why you
need to decide for yourself whether you're going to load libsignal or not.

View File

@ -436,6 +436,85 @@ Please refer to the `API documentation </docs/html/api/http://localhost:8008/doc
for an overview of what's available to you. If you need new events or promises, then
`please open an issue or make a pull request on Github <https://github.com/jcbrand/converse.js>`_
Hooks
-----
Converse has the concept of ``hooks``, which are special events that allow you
to modify it's behaviour at runtime.
A hook is similar to an event, but it differs in two meaningful ways:
1. Converse will wait for all handlers of a hook to finish before continuing inside the function from where the hook was triggered.
2. Each hook contains a payload, which the handlers can modify or extend, before returning it (either to the function that triggered the hook or to subsequent handlers).
These two properties of hooks makes it possible for 3rd party plugins to
intercept and update data, allowing them to modify Converse without the need of
resorting to `overrides`_.
A hook is triggered in the following way:
.. code-block:: javascript
async function hookTriggerExample () {
const payload = { foo: 'bar' };
const updated_payload = await api.hook('hookName', this, payload);
return updated_payload;
}
The above could be shortened:
.. code-block:: javascript
async function hookTriggerExample () {
return await api.hook('hookName', this, { foo: 'bar' });
}
The ``async/await`` syntax could also be removed, but then it's less clear to
the reader that this function returns a promise.
Let's assume that in a plugin somewhere a listener is registered for this hook:
.. code-block:: javascript
function hookListenerExample () {
api.listen.on('hookname', (context, payload) => {
return {...payload, 'baz': 'buzz'};
});
}
The ``context`` parameter in our listener is usually the ``this`` of the function
that triggered the hook (as is the case in ``hookTriggerExample``),
but could also be a ``Model`` instance.
The ``payload`` parameter is the same payload that was passed in in
``hookTriggerExample``.
The ``hookListenerExample`` function accepts the payload and returns a new one
which contains the original payload together with a new key and value.
The ``updated_payload`` that is now returned from ``hookTriggerExample`` looks
as follows:
::
{ foo: 'bar', bazz: 'buzz' }
Our plugin was able to add data to the payload without requiring any kind of
knowledge from ``hookTriggerExample`` about ``hookListenerExample`` and
without any kind of coupling betwee the code.
A good example of a real-world hook in Converse, is the
`getMessageActionButtons <https://conversejs.org/docs/html/api/-_converse.html#event:getMessageActionButtons>`_
which allows you to add, modify or delete the actions you can take on a message
in a chat.
The `Actions <https://github.com/conversejs/community-plugins/tree/master/packages/actions>`_
3rd party community plugin makes use of this hook to add extra actions such as
``like`` or ``dislike`` to chat messages.
A full example plugin
---------------------

View File

@ -37,9 +37,6 @@ You might want to open `dev.html <https://github.com/conversejs/converse.js/blob
how ``converse.initialize`` is called and to potentially change any of the
settings.
If you're running ``make devserver``, you need to open http://localhost:8080
instead.
Starting a web server with live reloading
-----------------------------------------
@ -49,3 +46,6 @@ can run ``make devserver`` (which will use `webpack-dev-server <https://github.c
Instead of ``dev.html`` being used, `webpack.html <https://github.com/conversejs/converse.js/blob/master/webpack.html>`_
is now being used as the HTML template, and you'll need to modify that file if
you want to change the settings passed to ``converse.initialize``.
If you're running ``make devserver``, you need to open http://localhost:8080.