diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index eff912b..1cdcd23 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -16,9 +16,59 @@ Plugins are discovered and loaded when the server is started. !!! info "Enable Plugin Support" To enable custom plugins, plugin support must be activated in the [server configuration](../start/config.md). -Multiple plugins are supported: +### Plugin Base Class -- [Reporting plugins](./plugins/report.md) -- [Barcode plugins](./plugins/barcode.md) -- [Action plugins](./plugins/action.md) -- [Integration plugins](./plugins/integration.md) +Custom plugins must inherit from the [IntegrationPluginBase class](https://github.com/inventree/InvenTree/blob/master/InvenTree/plugin/integration.py). Any plugins installed via the methods outlined above will be "discovered" when the InvenTree server launches. + +### Plugin Options + +Some metadata options can be defined as constants in the plugins class + +``` python +PLUGIN_SLUG = None # Used in URLs, setting-names etc. when a unique slug as a reference is needed -> the plugin name is used if not set +PLUGIN_TITLE = None # A nice human friendly name for the plugin -> used in titles, as plugin name etc. + +AUTHOR = None # Author of the plugin, git commit information is used if not present +PUBLISH_DATE = None # Publishing date of the plugin, git commit information is used if not present +VERSION = None # Version of the plugin +WEBSITE = None # Website for the plugin, developer etc. -> is shown in plugin overview if set +``` + +Refer to the [sample plugins](https://github.com/inventree/InvenTree/tree/master/InvenTree/plugin/samples) for further examples. + +### Plugin Config + +A *PluginConfig* database entry will be created for each plugin "discovered" when the server launches. This configuration entry is used to determine if a particular plugin is enabled. + +The configuration entries must be enabled via the [InvenTree admin interface](../settings/admin.md). + +!!! warning "Disabled by Default" + Newly discovered plugins are disabled by default, and must be manually enabled by an admin user + +### Plugin Mixins + +Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [django](https://docs.djangoproject.com/en/stable/topics/class-based-views/mixins/) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. + +Supported mixin classes are: + +- [ActionMixin](./plugins/action.md) +- [APICallMixin](./plugins/api.md) +- [AppMixin](./plugins/app.md) +- [BarcodeMixin](./plugins/barcode.md) +- [EventMixin](./plugins/event.md) +- [NavigationMixin](./plugins/navigation.md) +- [ScheduleMixin](./plugins/schedule.md) +- [SettingsMixin](./plugins/settings.md) +- [UrlsMixin](./plugins/urls.md) + +## Installing a Plugin + +Plugins can either be loaded from paths in the InvenTree install directory or as a plugin installed via pip. We recommend installation via pip as this enables hassle-free upgrades. + +For development new plugins can be placed ina a subdirectory in `src/InvenTree/plugins`. Built-In plugins ship in `src/InvenTree/plugin/builtin`. To achive full unit-testing for all mixins there are some sample implementations in `src/InvenTree/plugin/samples`. These are not loaded in production mode. + +### Plugin Installation File + +Plugins installation can be simplified by providing a list of plugins in a plugin configuration file. This file (by default, 'plugins.txt' in the same directory as the server configuration file) contains a list of required plugin packages. + +Plugins can be installed from this file by simply running the command `invoke plugins`. diff --git a/docs/extend/plugins/action.md b/docs/extend/plugins/action.md index 94c2feb..36eb245 100644 --- a/docs/extend/plugins/action.md +++ b/docs/extend/plugins/action.md @@ -2,7 +2,7 @@ title: Action Plugins --- -### Action Plugins +## ActionMixin Arbitrary "actions" can be called by POSTing data to the `/api/action/` endpoint. The POST request must include the name of the action to be performed, and a matching ActionPlugin plugin must be loaded by the server. Arbitrary data can also be provided to the action plugin via the POST data: diff --git a/docs/extend/plugins/api.md b/docs/extend/plugins/api.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/extend/plugins/app.md b/docs/extend/plugins/app.md new file mode 100644 index 0000000..d953b21 --- /dev/null +++ b/docs/extend/plugins/app.md @@ -0,0 +1,10 @@ +--- +title: App Mixin +--- + +## AppMixin + +If this mixin is added to a plugin the directory the plugin class is defined in is added to the list of `INSTALLED_APPS` in the InvenTree server configuration. + +!!! warning "Danger Zone" + Only use this mixin if you have an understanding of djangos [app system](https://docs.djangoproject.com/en/stable/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree before releasing. diff --git a/docs/extend/plugins/barcode.md b/docs/extend/plugins/barcode.md index c5d188d..6e7b16d 100644 --- a/docs/extend/plugins/barcode.md +++ b/docs/extend/plugins/barcode.md @@ -1,5 +1,5 @@ --- -title: Barcode Plugins +title: Barcode Mixin --- ### Barcode Plugins diff --git a/docs/extend/plugins/event.md b/docs/extend/plugins/event.md new file mode 100644 index 0000000..55f5ca2 --- /dev/null +++ b/docs/extend/plugins/event.md @@ -0,0 +1,3 @@ +--- +title: Event Mixin +--- \ No newline at end of file diff --git a/docs/extend/plugins/integration.md b/docs/extend/plugins/integration.md index fb109d8..e247ee1 100644 --- a/docs/extend/plugins/integration.md +++ b/docs/extend/plugins/integration.md @@ -24,12 +24,7 @@ WEBSITE = None # Website for the plugin, developer etc. -> is shown in plugin o -#### Installing a Plugin - -Plugins can either be loaded from paths in the InvenTree install directory or as a plugin installed via pip. We recommend installation via pip as this enables hassle-free upgrades. - -For development new plugins can be placed ina a subdirectroy in `src/InvenTree/plugins`. Built-In plugins ship in `src/InvenTree/plugin/builtin`. To achive full unit-testing for all mixins there are some sample implementations in `src/InvenTree/plugin/samples`. These are not loaded in production mode. - +## #### Mixins Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [django](https://docs.djangoproject.com/en/stable/topics/class-based-views/mixins/) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. diff --git a/docs/extend/plugins/navigation.md b/docs/extend/plugins/navigation.md new file mode 100644 index 0000000..86e3ce4 --- /dev/null +++ b/docs/extend/plugins/navigation.md @@ -0,0 +1,25 @@ +--- +title: Navigation Mixin +--- + +## NavigationMixin + +Use the class constant `NAVIGATION` for a array of links that should be added to InvenTrees navigation header. +The array must contain at least one dict that at least define a name and a link for each element. The link must be formatted for a URL pattern name lookup - links to external sites are not possible directly. The optional icon must be a class reference to an icon (InvenTree ships with fontawesome 4 by default). + +``` python +class MyNavigationPlugin(NavigationMixin, IntegrationPluginBase): + + PLUGIN_NAME = "NavigationPlugin" + + NAVIGATION = [ + {'name': 'SampleIntegration', 'link': 'plugin:sample:hi', 'icon': 'fas fa-box'}, + ] + + NAVIGATION_TAB_NAME = "Sample Nav" + NAVIGATION_TAB_ICON = 'fas fa-plus' +``` + +The optional class constants `NAVIGATION_TAB_NAME` and `NAVIGATION_TAB_ICON` can be used to change the name and icon for the parent navigation node. + + diff --git a/docs/extend/plugins/report.md b/docs/extend/plugins/report.md deleted file mode 100644 index d4b4f89..0000000 --- a/docs/extend/plugins/report.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Reporting Plugins ---- - -### Reporting Plugins - -InvenTree can generate customized reports (for example stocktake information, packing lists, acceptance test reports, etc). - -!!! missing "TODO" - Include more information here on reporting plugins diff --git a/docs/extend/plugins/schedule.md b/docs/extend/plugins/schedule.md new file mode 100644 index 0000000..df0d38e --- /dev/null +++ b/docs/extend/plugins/schedule.md @@ -0,0 +1,3 @@ +--- +title: Schedule Mixin +--- \ No newline at end of file diff --git a/docs/extend/plugins/settings.md b/docs/extend/plugins/settings.md new file mode 100644 index 0000000..484ed81 --- /dev/null +++ b/docs/extend/plugins/settings.md @@ -0,0 +1,48 @@ +--- +title: Settings Mixin +--- + +## SettingsMixin + +The *SettingsMixin* allows the plugin to save and load persistent settings to the database. + +- Plugin settings are stored against the individual plugin, and thus do not have to be unique +- Plugin settings are stored using a "key:value" pair + +Use the class constant `SETTINGS` for a dict of settings that should be added as global database settings. + +The dict must be formatted similar to the following sample. Take a look at the settings defined in `InvenTree.common.models.InvenTreeSetting` for all possible parameters. + + +``` python +class PluginWithSettings(SettingsMixin, IntegrationPluginBase): + + PLUGIN_NAME = "PluginWithSettings" + + SETTINGS = { + 'API_ENABLE': { + 'name': 'API Functionality', + 'description': 'Enable remote API queries', + 'validator': bool, + 'default': True, + }, + 'API_KEY': { + 'name': 'API Key', + 'description': 'Security key for accessing remote API', + 'default': '', + }, + 'API_URL': { + 'name': _('API URL'), + 'description': _('Base URL for remote server'), + 'default': 'http://remote.url/api', + }, + } +``` + +This mixin defines the helper functions `plugin.get_setting` and `plugin.set_seting` to access all plugin specific settings: + +```python +api_url = self.get_setting('API_URL') +``` + + diff --git a/docs/extend/plugins/urls.md b/docs/extend/plugins/urls.md new file mode 100644 index 0000000..1892a94 --- /dev/null +++ b/docs/extend/plugins/urls.md @@ -0,0 +1,23 @@ +--- +title: URLs Mixin +--- + +## UrlsMixin + +Use the class constant `URLS` for a array of URLs that should be added to InvenTrees URL paths or override the `plugin.setup_urls` function. + +The array has to contain valid URL patterns as defined in the [django documentation](https://docs.djangoproject.com/en/stable/topics/http/urls/). + +``` python +class MyUrlsPlugin(URLsMixin, IntegrationPluginBase): + + PLUGIN_NAME = "UrlsMixin" + + URLS = [ + url(r'increase/(?P\d+)/(?P\d+)/', self.view_increase, name='increase-level'), + ] +``` + +The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [url tag](https://docs.djangoproject.com/en/stable/ref/templates/builtins/#url)). + + diff --git a/mkdocs.yml b/mkdocs.yml index 804349e..192a789 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -111,10 +111,15 @@ nav: - Python Interface: extend/python.md - Plugins: - Overview: extend/plugins.md - - Reporting: extend/plugins/report.md - - Barcode: extend/plugins/barcode.md - - Action: extend/plugins/action.md - - Integration: extend/plugins/integration.md + - Action Mixin: extend/plugins/action.md + - API Mixin: extend/plugins/api.md + - App Mixin: extend/plugins/app.md + - Barcode Mixin: extend/plugins/barcode.md + - Event Mixin: extend/plugins/event.md + - Navigation Mixin: extend/plugins/navigation.md + - Schedule Mixin: extend/plugins/schedule.md + - Settings Mixin: extend/plugins/settings.md + - URL Mixin: extend/plugins/urls.md - Themes: extend/themes.md - Third-Party: extend/integrate.md - App: