+
\ No newline at end of file
diff --git a/docs/plugins/developing.rst b/docs/plugins/developing.rst
index 143ad3d8..34681bf1 100644
--- a/docs/plugins/developing.rst
+++ b/docs/plugins/developing.rst
@@ -13,6 +13,8 @@ Developing Plugins
This section is still a heavy WIP, so take it with a bit of caution ;)
+.. _sec-plugins-developing-structure:
+
OctoPrint Plugin Structure
==========================
@@ -37,7 +39,7 @@ a couple of properties describing the module:
Method called upon initializing of the plugin by the plugin subsystem, can be used to instantiate
plugin implementations, connecting them to hooks etc.
-A very simple example plugin which only hooks into OctoPrint's startup sequence and prints out "Hello World" to stdout would
+A very simple example plugin which only hooks into OctoPrint's startup sequence and logs "Oh hello!" would
be the following snippet:
.. code-block:: python
@@ -49,15 +51,17 @@ be the following snippet:
__plugin_name__ = "Example Plugin"
__plugin_version__ = "0.1"
- __plugin_description__ = "Prints \"Hello World!\" to stdout upon OctoPrint's startup"
+ __plugin_description__ = "Logs \"Oh hello!\" upon OctoPrint's startup"
def __plugin_init__():
global __plugin_implementations__
- __plugin_implementations__ = [HelloWorldPlugin()]
+ __plugin_implementations__ = [ExamplePlugin()]
- class HelloWorldPlugin(octoprint.plugin.StartupPlugin):
+ class ExamplePlugin(octoprint.plugin.StartupPlugin):
def on_startup(self, host, port):
- print("Hello World!")
+ self._logger.info("Oh hello!")
+
+.. _sec-plugins-developing-distribution:
Distributing your plugin
========================
@@ -72,43 +76,8 @@ You can distribute a plugin with OctoPrint via two ways:
your plugin's ``setup.py``, this way it will be found automatically by OctoPrint upon initialization of the
plugin subsystem [#f1]_.
- In this case you'll have a directory structure like the following:
-
- .. code-block:: none
-
- `-+ helloworld
- | `-+ static
- | | `-+ css
- | | `-- helloworld.css
- | | `-+ js
- | | `-- helloworld.js
- | | `-+ less
- | | `-- helloworld.less
- | `-+ templates
- | | `-- helloworld_settings_dialog.js
- | `-- __init__.py
- `-- setup.py
-
- The plugin itself will be distributed as a Python package, which your ``setup.py`` will refer to via the entry point
- like this:
-
- .. code-block:: python
-
- import setuptools
-
- def params():
- name = "OctoPrint-HelloWorld"
- version = "0.1"
- packages = ["helloworld"]
- install_requires = open("requirements.txt").read().split("\n")
-
- entry_points = {
- "octoprint.plugin" = ["helloworld = octoprint_helloworld"]
- }
-
- return locals()
-
- setuptools.setup(**params())
+ For an example of how the directory structure and related files would look like in this case, please take a
+ look at the `helloworld example from OctoPrint's example plugins `_.
This variant is highly recommended for pretty much any plugin besides the most basic ones since it also allows
requirements management and pretty much any thing else that Python's setuptools provide to the developer.
@@ -119,7 +88,6 @@ You can distribute a plugin with OctoPrint via two ways:
environments), so make sure to instruct your users to use the exact same Python installation for installing
the plugin that they also used for installing & running OctoPrint.
-
.. _sec-plugins-developing-mixins:
Available plugin mixins
diff --git a/docs/plugins/index.rst b/docs/plugins/index.rst
index bd085f73..25cff1f9 100644
--- a/docs/plugins/index.rst
+++ b/docs/plugins/index.rst
@@ -1,60 +1,18 @@
.. _sec-plugins:
-#####################
-Plugins Documentation
-#####################
+#######
+Plugins
+#######
Starting with OctoPrint 1.2.0, there's now a plugin system in place which allows to individually
extend OctoPrint's functionality.
-Right now plugins can be used to extend OctoPrint's settings dialog, to execute specific tasks on server startup and
+Right now plugins can be used to extend OctoPrint's web interface, to execute specific tasks on server startup and
shutdown, to provide custom (API) endpoints with special functionality, to react on system events or to add support for
additional slicers. More plugin types are planned for the future.
-.. _sec-plugins-installation:
-
-Installing Plugins
-==================
-
-Plugins can be installed either by unpacking them into one of the configured plugin folders (regularly those are
-``/plugins`` and ``~/.octoprint/plugins`` or by installing them as regular python modules via ``pip``.
-Please refer to the documentation of the plugin for installations instructions.
-
-The latter is the more common case since all currently published plugins not bundled with OctoPrint can and should be installed
-this way.
-
-For a plugin available on the Python Package Index (PyPi), the process is as simple as issuing a
-
-.. code-block:: bash
-
- pip install
-
-For plugins not available on PyPi, you'll have to give ``pip`` an URL from which to install the package (e.g. the URL to
-a ZIP file of the current master branch of a Github repository hosting a plugin, or even a ``git+https`` URL), example:
-
-.. code-block:: bash
-
- pip install https://github.com/OctoPrint/OctoPrint-Growl/archive/master.zip
-
-See `the pip install documentation `_ for what URL
-types are possible.
-
-.. _sec-plugins-available:
-
-Available Plugins
-=================
-
-Currently there's no such thing as a centralized plugin repository for available plugins.
-
-Plugins may be found in the lists provided in `the OctoPrint wiki `_
-and on the `OctoPrint organization Github page `_.
-
-Developing Plugins
-==================
-
-Please see the following sub topics for information on how to develop your own OctoPrint plugins.
-
.. toctree::
- :maxdepth: 2
+ :maxdepth: 3
+ using.rst
developing.rst
diff --git a/docs/plugins/using.rst b/docs/plugins/using.rst
new file mode 100644
index 00000000..898996e5
--- /dev/null
+++ b/docs/plugins/using.rst
@@ -0,0 +1,44 @@
+.. _sec-plugins-using:
+
+*************
+Using Plugins
+*************
+
+.. _sec-plugins-using-available:
+
+Finding Plugins
+===============
+
+Currently there's no such thing as a centralized plugin repository for available plugins.
+
+Plugins may be found in the lists provided in `the OctoPrint wiki `_
+and on the `OctoPrint organization Github page `_.
+
+.. _sec-plugins-using-installing:
+
+Installing Plugins
+==================
+
+Plugins can be installed either by unpacking them into one of the configured plugin folders (regularly those are
+``/plugins`` and ``~/.octoprint/plugins`` or by installing them as regular python modules via ``pip``.
+Please refer to the documentation of the plugin for installations instructions.
+
+The latter is the more common case since all currently published plugins not bundled with OctoPrint can and should be installed
+this way.
+
+For a plugin available on the Python Package Index (PyPi), the process is as simple as issuing a
+
+.. code-block:: bash
+
+ pip install
+
+For plugins not available on PyPi, you'll have to give ``pip`` an URL from which to install the package (e.g. the URL to
+a ZIP file of the current master branch of a Github repository hosting a plugin, or even a ``git+https`` URL), example:
+
+.. code-block:: bash
+
+ pip install https://github.com/OctoPrint/OctoPrint-Growl/archive/master.zip
+
+See `the pip install documentation `_ for what URL
+types are possible.
+
diff --git a/src/octoprint/plugin/types.py b/src/octoprint/plugin/types.py
index b2980b71..a584cdc8 100644
--- a/src/octoprint/plugin/types.py
+++ b/src/octoprint/plugin/types.py
@@ -186,149 +186,179 @@ class TemplatePlugin(Plugin):
Further keys to be included in the dictionary depend on the type:
``navbar`` type
+ .. figure:: ../images/template-plugin-type-navbar.png
+ :align: center
+ :alt: Structure of navbar plugins
+
Configures a navbar component to inject. The following keys are supported:
- template
- Name of the template to inject, defaults to ``_navbar.jinja2``.
- suffix
- Suffix to attach to the element ID of the injected template, will be ``_`` if not provided and not
- the first template of the type, with ``index`` counting from 1 and increasing for each template of the same
- type.
- custom_bindings
- A boolean value indicating whether the default view model should be bound to the navbar entry (``false``)
- or if a custom binding will be used by the plugin (``true``, default).
- data_bind
- Additional knockout data bindings to apply to the navbar entry, can be used to add further behaviour to
- the container based on internal state if necessary.
- classes
- Additional classes to apply to the navbar entry, as a list of individual classes
- (e.g. ``classes=["myclass", "myotherclass"]``) which will be joined into the correct format by the template engine.
- styles
- Additional CSS styles to apply to the navbar entry, as a list of individual declarations
- (e.g. ``styles=["color: red", "display: block"]``) which will be joined into the correct format by the template
- engine.
+ .. list-table::
+ :widths: 5 95
+
+ * - template
+ - Name of the template to inject, defaults to ``_navbar.jinja2``.
+ * - suffix
+ - Suffix to attach to the element ID of the injected template, will be ``_`` if not provided and not
+ the first template of the type, with ``index`` counting from 1 and increasing for each template of the same
+ type.
+ * - custom_bindings
+ - A boolean value indicating whether the default view model should be bound to the navbar entry (``false``)
+ or if a custom binding will be used by the plugin (``true``, default).
+ * - data_bind
+ - Additional knockout data bindings to apply to the navbar entry, can be used to add further behaviour to
+ the container based on internal state if necessary.
+ * - classes
+ - Additional classes to apply to the navbar entry, as a list of individual classes
+ (e.g. ``classes=["myclass", "myotherclass"]``) which will be joined into the correct format by the template engine.
+ * - styles
+ - Additional CSS styles to apply to the navbar entry, as a list of individual declarations
+ (e.g. ``styles=["color: red", "display: block"]``) which will be joined into the correct format by the template
+ engine.
``sidebar`` type
+ .. figure:: ../images/template-plugin-type-sidebar.png
+ :align: center
+ :alt: Structure of sidebar plugins
+
Configures a sidebar component to inject. The following keys are supported:
- name
- The name of the sidebar entry, if not set the name of the plugin will be used.
- icon
- Icon to use for the sidebar header, should be the name of a Font Awesome icon without the leading ``icon-`` part.
- template
- Name of the template to inject, defaults to ``_sidebar.jinja2``.
- template_header
- Additional template to include in the head section of the sidebar item. For an example of this, see the additional
- options included in the "Files" section.
- suffix
- Suffix to attach to the element ID of the injected template, will be ``_`` if not provided and not
- the first template of the type, with ``index`` counting from 1 and increasing for each template of the same
- type.
- custom_bindings
- A boolean value indicating whether the default view model should be bound to the sidebar container (``false``)
- or if a custom binding will be used by the plugin (``true``, default).
- data_bind
- Additional knockout data bindings to apply to the template container, can be used to add further behaviour to
- the container based on internal state if necessary.
- classes
- Additional classes to apply to both the wrapper around the sidebar box as well as the content pane itself, as a
- list of individual classes (e.g. ``classes=["myclass", "myotherclass"]``) which will be joined into the correct
- format by the template engine.
- classes_wrapper
- Like ``classes`` but only applied to the whole wrapper around the sidebar box.
- classes_content
- Like ``classes`` but only applied to the content pane itself.
- styles
- Additional CSS styles to apply to both the wrapper around the sidebar box as well as the content pane itself,
- as a list of individual declarations (e.g. ``styles=["color: red", "display: block"]``) which will be joined
- into the correct format by the template engine.
- styles_wrapper
- Like ``styles`` but only applied to the whole wrapper around the sidebar box.
- styles_content
- Like ``styles`` but only applied to the content pane itself
+ .. list-table::
+ :widths: 5 95
+
+ * - name
+ - The name of the sidebar entry, if not set the name of the plugin will be used.
+ * - icon
+ - Icon to use for the sidebar header, should be the name of a Font Awesome icon without the leading ``icon-`` part.
+ * - template
+ - Name of the template to inject, defaults to ``_sidebar.jinja2``.
+ * - template_header
+ - Additional template to include in the head section of the sidebar item. For an example of this, see the additional
+ options included in the "Files" section.
+ * - suffix
+ - Suffix to attach to the element ID of the injected template, will be ``_`` if not provided and not
+ the first template of the type, with ``index`` counting from 1 and increasing for each template of the same
+ type.
+ * - custom_bindings
+ - A boolean value indicating whether the default view model should be bound to the sidebar container (``false``)
+ or if a custom binding will be used by the plugin (``true``, default).
+ * - data_bind
+ - Additional knockout data bindings to apply to the template container, can be used to add further behaviour to
+ the container based on internal state if necessary.
+ * - classes
+ - Additional classes to apply to both the wrapper around the sidebar box as well as the content pane itself, as a
+ list of individual classes (e.g. ``classes=["myclass", "myotherclass"]``) which will be joined into the correct
+ format by the template engine.
+ * - classes_wrapper
+ - Like ``classes`` but only applied to the whole wrapper around the sidebar box.
+ * - classes_content
+ - Like ``classes`` but only applied to the content pane itself.
+ * - styles
+ - Additional CSS styles to apply to both the wrapper around the sidebar box as well as the content pane itself,
+ as a list of individual declarations (e.g. ``styles=["color: red", "display: block"]``) which will be joined
+ into the correct format by the template engine.
+ * - styles_wrapper
+ - Like ``styles`` but only applied to the whole wrapper around the sidebar box.
+ * - styles_content
+ - Like ``styles`` but only applied to the content pane itself
``tab`` type
+ .. figure:: ../images/template-plugin-type-tab.png
+ :align: center
+ :alt: Structure of tab plugins
+
Configures a tab component to inject. The value must be a dictionary, supported values are the following:
- name
- The name under which to include the tab, if not set the name of the plugin will be used.
- template
- Name of the template to inject, defaults to ``_tab.jinja2``.
- suffix
- Suffix to attach to the element ID of the injected template, will be ``_`` if not provided and not
- the first template of the type, with ``index`` counting from 1 and increasing for each template of the same
- type.
- custom_bindings
- A boolean value indicating whether the default view model should be bound to the tab pane and link
- in the navigation (``false``) or if a custom binding will be used by the plugin (``true``, default).
- data_bind
- Additional knockout data bindings to apply to the template container, can be used to add further behaviour to
- the container based on internal state if necessary.
- classes
- Additional classes to apply to both the wrapper around the sidebar box as well as the content pane itself, as a
- list of individual classes (e.g. ``classes=["myclass", "myotherclass"]``) which will be joined into the correct
- format by the template engine.
- classes_link
- Like ``classes`` but only applied to the link in the navigation.
- classes_content
- Like ``classes`` but only applied to the content pane itself.
- styles
- Additional CSS styles to apply to both the wrapper around the sidebar box as well as the content pane itself,
- as a list of individual declarations (e.g. ``styles=["color: red", "display: block"]``) which will be joined
- into the correct format by the template engine.
- styles_link
- Like ``styles`` but only applied to the link in the navigation.
- styles_content
- Like ``styles`` but only applied to the content pane itself
+ .. list-table::
+ :widths: 5 95
+
+ * - name
+ - The name under which to include the tab, if not set the name of the plugin will be used.
+ * - template
+ - Name of the template to inject, defaults to ``_tab.jinja2``.
+ * - suffix
+ - Suffix to attach to the element ID of the injected template, will be ``_`` if not provided and not
+ the first template of the type, with ``index`` counting from 1 and increasing for each template of the same
+ type.
+ * - custom_bindings
+ - A boolean value indicating whether the default view model should be bound to the tab pane and link
+ in the navigation (``false``) or if a custom binding will be used by the plugin (``true``, default).
+ * - data_bind
+ - Additional knockout data bindings to apply to the template container, can be used to add further behaviour to
+ the container based on internal state if necessary.
+ * - classes
+ - Additional classes to apply to both the wrapper around the sidebar box as well as the content pane itself, as a
+ list of individual classes (e.g. ``classes=["myclass", "myotherclass"]``) which will be joined into the correct
+ format by the template engine.
+ * - classes_link
+ - Like ``classes`` but only applied to the link in the navigation.
+ * - classes_content
+ - Like ``classes`` but only applied to the content pane itself.
+ * - styles
+ - Additional CSS styles to apply to both the wrapper around the sidebar box as well as the content pane itself,
+ as a list of individual declarations (e.g. ``styles=["color: red", "display: block"]``) which will be joined
+ into the correct format by the template engine.
+ * - styles_link
+ - Like ``styles`` but only applied to the link in the navigation.
+ * - styles_content
+ - Like ``styles`` but only applied to the content pane itself.
``settings`` type
+ .. figure:: ../images/template-plugin-type-settings.png
+ :align: center
+ :alt: Structure of settings plugins
+
Configures a settings component to inject. The value must be a dictionary, supported values are the following:
- name
- The name under which to include the settings pane, if not set the name of the plugin will be used.
- template
- Name of the template to inject, defaults to ``_settings.jinja2``.
- suffix
- Suffix to attach to the element ID of the injected template, will be ``_`` if not provided and not
- the first template of the type, with ``index`` counting from 1 and increasing for each template of the same
- type.
- custom_bindings
- A boolean value indicating whether the default settings view model should be bound to the settings pane and link
- in the navigation (``false``) or if a custom binding will be used by the plugin (``true``, default).
- data_bind
- Additional knockout data bindings to apply to the template container, can be used to add further behaviour to
- the container based on internal state if necessary.
- classes
- Additional classes to apply to both the wrapper around the navigation link as well as the content pane itself, as a
- list of individual classes (e.g. ``classes=["myclass", "myotherclass"]``) which will be joined into the correct
- format by the template engine.
- classes_link
- Like ``classes`` but only applied to the link in the navigation.
- classes_content
- Like ``classes`` but only applied to the content pane itself.
- styles
- Additional CSS styles to apply to both the wrapper around the navigation link as well as the content pane itself,
- as a list of individual declarations (e.g. ``styles=["color: red", "display: block"]``) which will be joined
- into the correct format by the template engine.
- styles_link
- Like ``styles`` but only applied to the link in the navigation.
- styles_content
- Like ``styles`` but only applied to the content pane itself
+ .. list-table::
+ :widths: 5 95
+
+ * - name
+ - The name under which to include the settings pane, if not set the name of the plugin will be used.
+ * - template
+ - Name of the template to inject, defaults to ``_settings.jinja2``.
+ * - suffix
+ - Suffix to attach to the element ID of the injected template, will be ``_`` if not provided and not
+ the first template of the type, with ``index`` counting from 1 and increasing for each template of the same
+ type.
+ * - custom_bindings
+ - A boolean value indicating whether the default settings view model should be bound to the settings pane and link
+ in the navigation (``false``) or if a custom binding will be used by the plugin (``true``, default).
+ * - data_bind
+ - Additional knockout data bindings to apply to the template container, can be used to add further behaviour to
+ the container based on internal state if necessary.
+ * - classes
+ - Additional classes to apply to both the wrapper around the navigation link as well as the content pane itself, as a
+ list of individual classes (e.g. ``classes=["myclass", "myotherclass"]``) which will be joined into the correct
+ format by the template engine.
+ * - classes_link
+ - Like ``classes`` but only applied to the link in the navigation.
+ * - classes_content
+ - Like ``classes`` but only applied to the content pane itself.
+ * - styles
+ - Additional CSS styles to apply to both the wrapper around the navigation link as well as the content pane itself,
+ as a list of individual declarations (e.g. ``styles=["color: red", "display: block"]``) which will be joined
+ into the correct format by the template engine.
+ * - styles_link
+ - Like ``styles`` but only applied to the link in the navigation.
+ * - styles_content
+ - Like ``styles`` but only applied to the content pane itself
``generic`` type
Configures a generic template to inject. The following keys are supported:
- template
- Name of the template to inject, defaults to ``_settings.jinja2``.
+ .. list-table::
+ :widths: 5 95
+
+ * - template
+ - Name of the template to inject, defaults to ``_settings.jinja2``.
.. note::
As already outlined above, each template type has a default template name (i.e. the default navbar template
of a plugin is called ``_navbar.jinja2``), which may be overridden using the template configuration.
- If a plugin needs to include two navbar templates, it needs to provide two entries here, at least one with ``template``
- overridden. If only one entry for a given template type is present with an overridden ``template`` parameter,
- OctoPrint will assume that the default template does not exist and hence only include the defined template,
- skipping the default one.
+ If a plugin needs to include more than one template of a given type, it needs to provide an entry for each of
+ those, since the implicit default template will only be included automatically if no other templates of that
+ type are defined.
:return: a list containing the configuration options for the plugin's injected templates
"""