소스 검색

docs: Discourage usage of overrides and add hook to example plugin

JC Brand 3 년 전
부모
커밋
990aefc6cb
2개의 변경된 파일72개의 추가작업 그리고 89개의 파일을 삭제
  1. 1 1
      docs/source/development.rst
  2. 71 88
      docs/source/plugin_development.rst

+ 1 - 1
docs/source/development.rst

@@ -23,7 +23,7 @@ to fix a bug or to add new functionality.
 .. toctree::
 .. toctree::
    :maxdepth: 2
    :maxdepth: 2
 
 
-   setup_dev_environment 
+   setup_dev_environment
    plugin_development
    plugin_development
    api/index
    api/index
    testing
    testing

+ 71 - 88
docs/source/plugin_development.rst

@@ -16,7 +16,7 @@ and is itself composed out of plugins.
 There are only a few files that are included in the default build of Converse
 There are only a few files that are included in the default build of Converse
 which aren't plugins.
 which aren't plugins.
 
 
-An important one is `converse-core.js <https://github.com/conversejs/converse.js/blob/master/src/headless/converse-core.js>`_,
+An important one is `core.js <https://github.com/conversejs/.js/blob/master/src/headless/core.js>`_,
 which is responsible for bootstrapping the plugin architecture,
 which is responsible for bootstrapping the plugin architecture,
 setting up and maintaining the connection to the XMPP
 setting up and maintaining the connection to the XMPP
 server and declaring the public (`window.converse </docs/html/api/converse.html>`_) and protected (`_converse.api </docs/html/api/-_converse.api.html>`_) APIs.
 server and declaring the public (`window.converse </docs/html/api/converse.html>`_) and protected (`_converse.api </docs/html/api/-_converse.api.html>`_) APIs.
@@ -180,11 +180,59 @@ The code for it could look something like this:
 These dependencies are closured so that they don't pollute the global
 These dependencies are closured so that they don't pollute the global
 namespace, that's why you need to access them in such a way inside the module.
 namespace, that's why you need to access them in such a way inside the module.
 
 
-Overrides
----------
+Overriding templates
+--------------------
+
+Converse uses `lit-html <https://lit-html.polymer-project.org/guide>`_
+templates and templates are imported as separate files.
+
+It's possible to configure your module bundler (e.g. Webpack) in such as way that a
+different file is loaded when a template is imported.
+
+This allows you to create your own templates that are used instead of the ones
+that would have originally been imported.
+
+With Webpack (which Converse uses internally), you can specify an
+``alias`` for the template you want to override. This alias then points to your
+own custom template.
+
+For example, in your webpack config file, you could add the following to the
+``config`` object that gets exported:
+
+.. code-block:: javascript
+
+    resolve: {
+        extensions: ['.js'],
+        modules: [
+            path.join(__dirname, 'node_modules'),
+            path.join(__dirname, 'node_modules/converse.js/src')
+        ],
+        alias: {
+            'plugins/profile/templates/profile.js$': path.resolve(__dirname, 'templates/custom-profile.js')
+        }
+    }
+
+This will override the template that gets imported at the path ``plugins/profile/templates/profile.js``
+with your own template at the path ``templates/custom-profile.js`` (relative to your webpack config file).
+
+
+Object and class Overrides
+--------------------------
+
+.. note:: Using the `overrides` feature from pluggable.js is discouraged. It's
+    much better to use events, promises and `hooks`_ to modify the behaviour of
+    Converse.
+
+    The pluggable.js `overrides` will only work on objects and classes that are
+    set as attributes on the `_converse` object, which doesn't apply to many
+    newer classes and objects, such as the web components. For these clasess,
+    overrides won't work at all.
+
+    This section is left here for completeness, because in some special cases
+    overrides are still used.
 
 
 Plugins can override core code or code from other plugins. You can specify
 Plugins can override core code or code from other plugins. You can specify
-overrides in the object passed to  ``converse.plugins.add``.
+overrides in the object passed to ``converse.plugins.add``.
 
 
 In an override you can still call the overridden function, by calling
 In an override you can still call the overridden function, by calling
 ``this.__super__.methodName.apply(this, arguments);`` where ``methodName`` is
 ``this.__super__.methodName.apply(this, arguments);`` where ``methodName`` is
@@ -242,7 +290,7 @@ monkey patching which pollutes the call stack and can make your code fragile
 and prone to bugs when Converse gets updated. Too much use of ``overrides``
 and prone to bugs when Converse gets updated. Too much use of ``overrides``
 is therefore a "code smell" which should ideally be avoided.
 is therefore a "code smell" which should ideally be avoided.
 
 
-A better approach is to listen to the events emitted by Converse, and to add
+A better approach is to use the events and `hooks`_ emitted by Converse, and to add
 your code in event handlers. This is however not always possible, in which case
 your code in event handlers. This is however not always possible, in which case
 the overrides are a powerful tool.
 the overrides are a powerful tool.
 
 
@@ -260,40 +308,6 @@ For example:
         Object.assign(_converse.ChatBoxView.prototype, { doSomething });
         Object.assign(_converse.ChatBoxView.prototype, { doSomething });
 
 
 
 
-Overriding a template
-~~~~~~~~~~~~~~~~~~~~~
-
-Converse uses `lit-html <https://lit-html.polymer-project.org/guide>`_
-templates.
-
-It's not possible to override a template with the plugin's ``overrides``
-feature, instead you should configure a new path to your own template via your
-module bundler.
-
-For example, with Webpack (which Converse uses internall), you can specify an
-``alias`` for the template you want to override. This alias then points to your
-own custom template.
-
-For example, in your webpack config file, you could add the following to the
-``config`` object that gets exported:
-
-.. code-block:: javascript
-
-    resolve: {
-        extensions: ['.js'],
-        modules: [
-            path.join(__dirname, 'node_modules'),
-            path.join(__dirname, 'node_modules/converse.js/src')
-        ],
-        alias: {
-            'plugins/profile/templates/profile.js$': path.resolve(__dirname, 'templates/custom-profile.js')
-        }
-    }
-
-This will override the template that gets imported at the path ``plugins/profile/templates/profile.js``
-with your own template at the path ``templates/custom-profile.js`` (relative to
-your webpack config file).
-
 
 
 .. _`dependencies`:
 .. _`dependencies`:
 
 
@@ -515,8 +529,8 @@ The `Actions <https://github.com/conversejs/community-plugins/tree/master/packag
 ``like`` or ``dislike`` to chat messages.
 ``like`` or ``dislike`` to chat messages.
 
 
 
 
-A full example plugin
----------------------
+An example plugin
+-----------------
 
 
 Below follows a documented example of a plugin. This is the same code that gets
 Below follows a documented example of a plugin. This is the same code that gets
 generated by `generator-conversejs <https://github.com/jcbrand/generator-conversejs>`_.
 generated by `generator-conversejs <https://github.com/jcbrand/generator-conversejs>`_.
@@ -590,8 +604,8 @@ generated by `generator-conversejs <https://github.com/jcbrand/generator-convers
              *      _converse.api.promises.add('myPromise');
              *      _converse.api.promises.add('myPromise');
              *
              *
              * Your plugin should then, when appropriate, resolve the
              * Your plugin should then, when appropriate, resolve the
-             * promise by calling `_converse.api.emit`, which will also
-             * emit an event with the same name as the promise.
+             * promise by calling `_converse.api.trigger`, which will also
+             * trigger an event with the same name as the promise.
              * For example:
              * For example:
              *
              *
              *      _converse.api.trigger('operationCompleted');
              *      _converse.api.trigger('operationCompleted');
@@ -605,53 +619,22 @@ generated by `generator-conversejs <https://github.com/jcbrand/generator-convers
              *
              *
              *      _converse.api.waitUntil('operationCompleted', function { ... });
              *      _converse.api.waitUntil('operationCompleted', function { ... });
              */
              */
-        },
 
 
-        /* If you want to override some function or a model or
-         * view defined elsewhere in Converse, then you do that under
-         * the "overrides" namespace.
-         */
-        overrides: {
-            /* For example, the private *_converse* object has a
-             * method "onConnected". You can override that method as follows:
-             */
-            onConnected: function () {
-                // Overrides the onConnected method in Converse
-
-                // Top-level functions in "overrides" are bound to the
-                // inner "_converse" object.
-                const _converse = this;
-
-                // Your custom code can come here ...
-
-                // You can access the original function being overridden
-                // via the __super__ attribute.
-                // Make sure to pass on the arguments supplied to this
-                // function and also to apply the proper "this" object.
-                _converse.__super__.onConnected.apply(this, arguments);
 
 
-                // Your custom code can come here ...
-            },
-
-            /* Override Converse's XMPPStatus model so that we can override the
-             * function that sends out the presence stanza.
+            /* In your plugin, you can also listen for hooks.
+             * Hooks allow you to add or modify data and properties used by
+             * Converse.
+             *
+             * For example, the getToolbarButtons hook allows you to add new buttons to the chat toolbar.
+             * https://conversejs.org/docs/html/api/-_converse.html#event:getToolbarButtons
              */
              */
-            XMPPStatus: {
-                sendPresence: function (type, status_message, jid) {
-                    // The "_converse" object is available via the __super__
-                    // attribute.
-                    const _converse = this.__super__._converse;
-
-                    // Custom code can come here ...
-
-                    // You can call the original overridden method, by
-                    // accessing it via the __super__ attribute.
-                    // When calling it, you need to apply the proper
-                    // context as reference by the "this" variable.
-                    this.__super__.sendPresence.apply(this, arguments);
-
-                    // Custom code can come here ...
-                }
-            }
+             api.listen.on('getToolbarButtons', (toolbar_el, buttons) => {
+                buttons.push(html`
+                    <button class="my-button" @click=${alert('hello world!')}>
+                        <converse-icon class="fa fa-eye" size="1em" color="blue"></converse-icon>
+                    </button>
+                `);
+                return buttons;
+            });
         }
         }
     });
     });