.. _plugin_developing: Developing new Plugins ====================== If you want to write a plugin, it's a very good idea to checkout existing plugins. A good starting point for example is the `Portal Plugin`_. Also make sure to check out the cookiecutter-flaskbb-plugin project, which is a cookiecutter template which helps you to create new plugins. For example, the structure of a plugin could look like this: .. sourcecode:: text your_package_name |-- setup.py |-- my_plugin |-- __init__.py |-- views.py |-- models.py |-- forms.py |-- static | |-- style.css |-- templates |-- myplugin.html |-- migrations |-- 59f7c49b6289_init.py Metadata -------- FlaskBB Plugins are usually following the naming scheme of ``flaskbb-plugin-YOUR_PLUGIN_NAME`` which should make them better distinguishable from other PyPI distributions. A proper plugin should have at least put the following metadata into the ``setup.py`` file. .. sourcecode:: python setup( name="flaskbb-plugin-YOUR_PLUGIN_NAME", # name on PyPI packages=["your_package_name"], # name of the folder your plugin is located in version='1.0', url=, license=, author=, author_email=, description=, long_description=__doc__, include_package_data=True, zip_safe=False, platforms='any', entry_points={ 'flaskbb_plugin': [ 'unique_name_of_plugin = your_package_name.pluginmodule', # most important part ] } ) The most important part here is the ``entry_point``. Here you tell FlaskBB the unique name of your plugin and where your plugin module is located inside your project. Entry points are a feature that is provided by setuptools. FlaskBB looks up the ``flaskbb_plugin`` entrypoint to discover its plugins. Have a look at the `setup script`_ documentation and the `sample setup.py`_ file to get a better idea what the ``setup.py`` file is all about it. For a full example, checkout the `Portal Plugin`_. .. _`setup script`: https://docs.python.org/3.6/distutils/setupscript.html#additional-meta-data .. _`sample setup.py`: https://github.com/pypa/sampleproject/blob/master/setup.py .. _`Portal Plugin`: https://github.com/sh4nks/flaskbb-plugins/tree/master/portal Settings -------- Plugins can create settings which integrate with the 'Settings' tab of the Admin Panel. The settings are stored in a dictionary with a given structure. The name of the dictionary must be ``SETTINGS`` and be placed in the plugin module. The structure of the ``SETTINGS`` dictionary is best explained via an example:: SETTINGS = { # This key has to be unique across FlaskBB. # Using a prefix is recommended. 'forum_ids': { # Default Value. The type of the default value depends on the # SettingValueType. 'value': [1], # The Setting Value Type. 'value_type': SettingValueType.selectmultiple, # The human readable name of your configuration variable 'name': "Forum IDs", # A short description of what the settings variable does 'description': ("The forum ids from which forums the posts " "should be displayed on the portal."), # extra stuff like the 'choices' in a select field or the # validators are defined in here 'extra': {"choices": available_forums, "coerce": int} } } .. currentmodule:: flaskbb.utils.forms .. table:: Available Setting Value Types :widths: auto ======================================== ================= Setting Value Type Parsed & Saved As ======================================== ================= :attr:`SettingValueType.string` :class:`str` :attr:`SettingValueType.integer` :class:`int` :attr:`SettingValueType.float` :class:`float` :attr:`SettingValueType.boolean` :class:`bool` :attr:`SettingValueType.select` :class:`list` :attr:`SettingValueType.selectmultiple` :class:`list` ======================================== ================= .. table:: Available Additional Options via the ``extra`` Keyword =========== ====================== ======================================== Options Applicable Types Description =========== ====================== ======================================== ``min`` string, integer, float **Optional.** The minimum required length of the setting value. If used on a numeric type, it will check the minimum value. ``max`` string, integer, float **Optional.** The maximum required length of the setting value. If used on a numeric type, it will check the maximum value. ``choices`` select, selectmultiple **Required.** A callable which returns a sequence of (value, label) pairs. ``coerce`` select, selectmultiple **Optional.** Coerces the select values to the given type. =========== ====================== ======================================== Validating the size of the integer/float and the length of the string fields is also possible via the ``min`` and ``max`` keywords:: 'recent_topics': { ... 'extra': {"min": 1}, }, The ``select`` and ``selectmultiple`` fields have to provide a callback which lists all the available choices. This is done via the ``choices`` keyword. In addition to that they can also specify the ``coerce`` keyword which will coerce the input value into the specified type.:: 'forum_ids': { ... 'extra': {"choices": available_forums, "coerce": int} } For more information see the :ref:`settings` chapter.