Docs for plugins that define more plugin hooks, closes #1765

pull/2173/head
Simon Willison 2023-08-31 16:06:30 -07:00
rodzic 98ffad9aed
commit fd083e37ec
1 zmienionych plików z 57 dodań i 0 usunięć

Wyświetl plik

@ -325,3 +325,60 @@ This object is exposed in templates as the ``urls`` variable, which can be used
Back to the <a href="{{ urls.instance() }}">Homepage</a>
See :ref:`internals_datasette_urls` for full details on this object.
.. _writing_plugins_extra_hooks:
Plugins that define new plugin hooks
------------------------------------
Plugins can define new plugin hooks that other plugins can use to further extend their functionality.
`datasette-graphql <https://github.com/simonw/datasette-graphql>`__ is one example of a plugin that does this. It defines a new hook called ``graphql_extra_fields``, `described here <https://github.com/simonw/datasette-graphql/blob/main/README.md#adding-custom-fields-with-plugins>`__, which other plugins can use to define additional fields that should be included in the GraphQL schema.
To define additional hooks, add a file to the plugin called ``datasette_your_plugin/hookspecs.py`` with content that looks like this:
.. code-block:: python
from pluggy import HookspecMarker
hookspec = HookspecMarker("datasette")
@hookspec
def name_of_your_hook_goes_here(datasette):
"Description of your hook."
You should define your own hook name and arguments here, following the documentation for `Pluggy specifications <https://pluggy.readthedocs.io/en/stable/#specs>`__. Make sure to pick a name that is unlikely to clash with hooks provided by any other plugins.
Then, to register your plugin hooks, add the following code to your ``datasette_your_plugin/__init__.py`` file:
.. code-block:: python
from datasette.plugins import pm
from . import hookspecs
pm.add_hookspecs(hookspecs)
This will register your plugin hooks as part of the ``datasette`` plugin hook namespace.
Within your plugin code you can trigger the hook using this pattern:
.. code-block:: python
from datasette.plugins import pm
for plugin_return_value in pm.hook.name_of_your_hook_goes_here(
datasette=datasette
):
# Do something with plugin_return_value
Other plugins will then be able to register their own implementations of your hook using this syntax:
.. code-block:: python
from datasette import hookimpl
@hookimpl
def name_of_your_hook_goes_here(datasette):
return "Response from this plugin hook"
These plugin implementations can accept 0 or more of the named arguments that you defined in your hook specification.