diff --git a/docs/api/index.rst b/docs/api/index.rst index c4142e9f..4f1d643f 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -1,8 +1,8 @@ .. _sec-api: -################# -API Documentation -################# +### +API +### .. toctree:: :maxdepth: 2 diff --git a/docs/events/index.rst b/docs/events/index.rst index 55200cab..58e3dd71 100644 --- a/docs/events/index.rst +++ b/docs/events/index.rst @@ -1,8 +1,8 @@ .. _sec-events: -#################### -Events Documentation -#################### +###### +Events +###### .. contents:: diff --git a/docs/images/template-plugin-type-navbar.png b/docs/images/template-plugin-type-navbar.png new file mode 100644 index 00000000..f00be863 Binary files /dev/null and b/docs/images/template-plugin-type-navbar.png differ diff --git a/docs/images/template-plugin-type-settings.png b/docs/images/template-plugin-type-settings.png new file mode 100644 index 00000000..ae9c849e Binary files /dev/null and b/docs/images/template-plugin-type-settings.png differ diff --git a/docs/images/template-plugin-type-sidebar.png b/docs/images/template-plugin-type-sidebar.png new file mode 100644 index 00000000..88db66a8 Binary files /dev/null and b/docs/images/template-plugin-type-sidebar.png differ diff --git a/docs/images/template-plugin-type-tab.png b/docs/images/template-plugin-type-tab.png new file mode 100644 index 00000000..32febed2 Binary files /dev/null and b/docs/images/template-plugin-type-tab.png differ diff --git a/docs/images/template_plugin_types.ep b/docs/images/template_plugin_types.ep new file mode 100644 index 00000000..d036b24c --- /dev/null +++ b/docs/images/template_plugin_types.ep @@ -0,0 +1,309 @@ + +sidebar1421408377849_14071531847true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + styles_content / styles
classes_content / classes
]]>
+ + + + + + + + + +
data_bind
styles_wrapper / styles
classes_wrapper / classes
]]>
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
tab1421409530685_85131531847true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + data_bind
styles_link / styles
classes_link / classes
]]>
+ + + + + + + + + +
data_bind
styles_content / styles
classes_content / classes
]]>
+ + + + + + + + + +
settings1421410253180_35791531847true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + data_bind
styles_content / styles
classes_content / classes
]]>
+ + + + + + + + + +
data_bind
styles_link / styles
classes_link / classes
]]>
+ + + + + + + + + +
navbar1421410510071_96931531847true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + data_bind
styles
classes
]]>
+ + + + + + + + + +
\ 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 """