[Doc] Big overhaul of TemplatePlugin docs & component ordering

This commit is contained in:
Gina Häußge 2015-03-31 18:23:18 +02:00
parent 8a3993ca59
commit 5c228e6071
4 changed files with 344 additions and 183 deletions

View file

@ -11,6 +11,10 @@ settings.
Note that many of these settings are available from the "Settings" menu in OctoPrint itself.
.. contents::
.. _sec-configuration-config_yaml-serial:
Serial
------
@ -52,6 +56,8 @@ Use the following settings to configure the serial connection to the printer:
additionalPorts:
- /dev/myPrinterSymlink
.. _sec-configuration-config_yaml-server:
Server
------
@ -95,6 +101,8 @@ Use the following settings to configure the server:
`into OctoPrint's wiki <https://github.com/foosel/OctoPrint/wiki/Reverse-proxy-configuration-examples>`_ for a couple
of examples on how to configure this.
.. _sec-configuration-config_yaml-webcam:
Webcam
------
@ -133,6 +141,8 @@ Use the following settings to configure webcam support:
options:
interval: 2
.. _sec-configuration-config_yaml-feature:
Feature
-------
@ -162,6 +172,8 @@ Use the following settings to enable or disable OctoPrint features:
# Specifies whether support for SD printing and file management should be enabled
sdSupport: true
.. _sec-configuration-config_yaml-folder:
Folder
------
@ -194,6 +206,8 @@ Use the following settings to set custom paths for folders used by OctoPrint:
# and/or sliced objects to print in the future.
watched: /path/to/watched/folder
.. _sec-configuration-config_yaml-temperature:
Temperature
-----------
@ -210,21 +224,128 @@ Use the following settings to configure temperature profiles which will be displ
extruder: 180
bed: 60
.. _sec-configuration-config_yaml-appearance:
Appearance
----------
Use the following settings to tweak OctoPrint's appearance a bit to better distinguish multiple instances/printers
appearance:
appearance or to modify the order and presence of the various UI components:
.. code-block:: yaml
appearance:
# Use this to give your printer a name. It will be displayed in the title bar (as "<Name> [OctoPrint]") and in the
# navigation bar (as "OctoPrint: <Name>")
name: My Printer Model
# Use this to give your printer a name. It will be displayed in the title bar
# (as "<Name> [OctoPrint]") and in the navigation bar (as "OctoPrint: <Name>")
name: My Printer
# Use this to color the navigation bar. Supported colors are red, orange, yellow, green, blue, violet and default.
color: blue
# Use this to color the navigation bar. Supported colors are red, orange,
# yellow, green, blue, violet and default.
color: default
# Makes the color of the navigation bar "transparent". In case your printer uses
# acrylic for its frame ;)
colorTransparent: false
# Configures the order and availability of the UI components
components:
# Defines the order of the components within their respective containers.
#
# If overridden by the user the resulting order for display will be calculated as
# follows:
#
# - first all components as defined by the user
# - then all enabled core components as define in the default order (see below)
#
# Components not contained within the default order (e.g. from plugins) will be either
# prepended or appended to that result, depending on component type.
#
# Note that a component is not included in the order as defined by the user will still
# be put into the container, according to the default order. To fully disable a
# component, you'll need to add it to the container's disabled list further below.
order:
# order of navbar items
navbar:
- settings
- systemmenu
- login
# order of sidebar items
sidebar:
- connection
- state
- files
# order of tab items
tab:
- temperature
- control
- gcodeviewer
- terminal
- timelapse
# order of settings, if settings plugins are registered gets extended internally by
# section_plugins and all settings plugins
settings
- section_printer
- serial
- printerprofiles
- temperatures
- terminalfilters
- gcodescripts
- section_features
- features
- webcam
- accesscontrol
- api
- section_octoprint
- folders
- appearance
- logs
# order of user settings
usersettings:
- access
- interface
# order of generic templates
generic: []
# Disabled components per container. If a component is included here it will not
# be included in OctoPrint's UI at all. Note that this might mean that critical
# functionality will not be available if no replacement is registered.
disabled:
navbar: [],
sidebar: [],
tab: [],
settings: [],
usersettings: [],
generic: []
.. note::
By modifying the ``components`` > ``order`` lists you may reorder OctoPrint's UI components as you like. You can also
inject Plugins at another than their default location in their respective container by adding the entry
``plugin_<plugin identifier>`` where you want them to appear.
Example: If you want the tab of the :ref:`Hello World Plugin <sec-plugins-gettingstarted>` to appear as the first tab
in OctoPrint, you'd need to redefine ``components`` > ``order`` > ``tab`` by including something like this in your
``config.yaml``:
.. code-block:: yaml
appearance:
components:
order:
tab:
- plugin_helloworld
OctoPrint will then turn this into the order ``plugin_helloworld``, ``temperature``, ``control``, ``gcodeviewer``,
``terminal``, ``timelapse`` plus any other plugins.
.. _sec-configuration-config_yaml-controls:
Controls
--------
@ -249,6 +370,8 @@ OctoPrint.
type: command
command: M107
.. _sec-configuration-config_yaml-system:
System
------
@ -269,6 +392,8 @@ OctoPrint is running is allowed to do this without password entry:
command: sudo shutdown -h now
confirm: You are about to shutdown the system.
.. _sec-configuration-config_yaml-accesscontrol:
Access Control
--------------
@ -305,6 +430,8 @@ Use the following settings to enable access control:
- 127.0.0.0/8
- 192.168.1.0/24
.. _sec-configuration-config_yaml-events:
Events
------
@ -326,6 +453,8 @@ Use the following settings to add shell/gcode commands to be executed on certain
type: gcode
enabled: False
.. _sec-configuration-config_yaml-terminalfilters:
Terminal Filters
----------------
@ -343,6 +472,8 @@ Use `Javascript regular expressions <https://developer.mozilla.org/en/docs/Web/J
- name: Suppress M27 requests/responses
regex: '(Send: M27)|(Recv: SD printing byte)'
.. _sec-configuration-config_yaml-api:
API
---
@ -357,6 +488,8 @@ Settings for the REST API:
# current API key needed for accessing the API
apikey: ...
.. _sec-configuration-config_yaml-devel:
Development settings
--------------------

View file

@ -155,7 +155,7 @@ of information now defined twice:
The nice thing about our plugin now being a proper python package is that OctoPrint can and will access the metadata defined
within ``setup.py``! So, we don't really need to define all this data twice. Remove ``__plugin_name__``, ``__plugin_version__``
and ``__plugin_description__``:
and ``__plugin_description__`` from ``__init__.py``:
.. code-block:: python
:linenos:

View file

@ -1,8 +1,98 @@
.. _sec-plugins-templates:
Templates
=========
Component Templates
===================
.. todo::
OctoPrint allows plugins to extend the UI of OctoPrint through the use of the :class:`~octoprint.plugin.TemplatePlugin`
mixin. By implementing this mixing and providing templates and their configuration through it, Plugins may currently
create one or more of navbar, sidebar, tabs, settings and generic components.
Needs to be written.
.. figure:: ../images/template-plugin-types-main.png
:align: center
:alt: Template injection types in the main part of the interface
Template injection types in the main part of the interface
.. figure:: ../images/template-plugin-types-settings.png
:align: center
:alt: Template injection types in the settings
Template injection types in the settings
You can find an example for a simple plugin which injects navbar, sidebar, tab and settings content into the interface in
`the "helloworld" plugin in OctoPrint's collection of plugin examples <https://github.com/OctoPrint/Plugin-Examples/tree/master/helloworld>`_.
.. _sec-plugins-templates-navbar:
Navbar
------
The right part of the navigation bar located at the top of the UI can be enriched with additional links. Note that
with the current implementation, plugins will always be located *to the left* of the existing links.
The included template must be called ``<pluginname>_navbar.jinja2`` (e.g. ``myplugin_navbar.jinja2``) unless
overridden by the configuration supplied through :func:`get_template_configs`.
The template will be already wrapped into the necessary structure, plugins just need to supply the pure content. The
wrapper structure will have all additional classes and styles applied as specified via the configuration supplied
through :func:`get_template_configs`.
.. _sec-plugins-templates-sidebar:
Sidebar
-------
The left side bar containing Connection, State and Files sections can be enriched with additional sections. Note
that with the current implementations, plugins will always be located *beneath* the existing sections.
The included template must be called ``<pluginname>_sidebar.jinja2`` (e.g. ``myplugin_sidebar.jinja2``) unless
overridden by the configuration supplied through :func:`get_template_configs`.
The template will be already wrapped into the necessary structure, plugins just need to supply the pure content. The
wrapper divs for both the whole box as well as the content pane will have all additional classes and styles applied
as specified via the configuration supplied through :func:`get_template_configs`.
.. _sec-plugins-templates-tabs:
Tabs
----
The available tabs of the main part of the interface may be extended with additional tabs originating from within
plugins. Note that with the current implementation, plugins will always be located *to the right* of the existing
tabs.
The included template must be called ``<pluginname>_tab.jinja2`` (e.g. ``myplugin_tab.jinja2``) unless
overridden by the configuration supplied through :func:`get_template_configs`.
The template will be already wrapped into the necessary structure, plugins just need to supply the pure content. The
wrapper div and the link in the navigation will have the additional classes and styles applied as specified via the
configuration supplied through :func:`get_template_configs`.
.. _sec-plugins-templates-settings:
Settings
--------
Plugins may inject a dialog into the existing settings view. Note that with the current implementations, plugins
will always be listed beneath the "Plugins" header in the settings link list, ordered alphabetically after
their displayed name.
The included template must be called ``<pluginname>_settings.jinja2`` (e.g. ``myplugin_settings.jinja2``) unless
overridden by the configuration supplied through :func:`get_template_configs`.
The template will be already wrapped into the necessary structure, plugins just need to supply the pure content. The
wrapper div and the link in the navigation will have the additional classes and styles applied as defined via the
supplied configuration supplied through :func:`get_template_configs`.
.. _sec-plugins-templates-generic:
Generic
-------
Plugins may also inject arbitrary templates into the page of the web interface itself, e.g. in order to
add overlays or dialogs to be called from within the plugin's javascript code.
.. _sec-plugins-templates-replacement:
Replacing existing components
-----------------------------

View file

@ -232,218 +232,134 @@ class TemplatePlugin(OctoPrintPlugin):
Template injection types in the settings
You can find an example for a simple plugin which injects navbar, sidebar, tab and settings content into the interface in
`the "helloworld" plugin in OctoPrint's collection of plugin examples <https://github.com/OctoPrint/Plugin-Examples/tree/master/helloworld>`_.
You can find an example for a simple plugin which injects navbar, tab and settings content into the interface in
the "helloworld" plugin in OctoPrint's :ref:`Plugin Tutorial <sec-plugins-gettingstarted>`.
Plugins may replace existing components, see the ``replaces`` keyword in the template configurations returned by
:meth:`.get_template_configs` below. Note that if a plugin replaces a core component, it is the plugin's
responsibility to ensure that all core functionality is still maintained.
"""
def get_template_configs(self):
"""
Allows configuration of injected navbar, sidebar, tab and settings templates. Should be a list containing one
configuration object per template to inject. Each configuration object is represented by a dictionary with a mandatory key
``type`` encoding the template type the configuration is targeting. Possible values here are ``navbar``, ``sidebar``,
``tab``, ``settings`` and ``generic``.
configuration object per template to inject. Each configuration object is represented by a dictionary which
may contain the following keys:
.. list-table::
:widths: 5 95
* - type
- The template type the configuration is targeting. Possible values here are ``navbar``, ``sidebar``,
``tab``, ``settings`` and ``generic``. Mandatory.
* - name
- The name of the component, if not set the name of the plugin will be used. The name will be visible at
a location depending on the ``type``:
* ``navbar``: unused
* ``sidebar``: sidebar heading
* ``tab``: tab heading
* ``settings``: settings link
* ``generic``: unused
* - template
- Name of the template to inject, default value depends on the ``type``:
* ``navbar``: ``<pluginname>_navbar.jinja2``
* ``sidebar``: ``<pluginname>_sidebar.jinja2``
* ``tab``: ``<pluginname>_tab.jinja2``
* ``settings``: ``<pluginname>_settings.jinja2``
* ``generic``: ``<pluginname>.jinja2``
* - suffix
- Suffix to attach to the component identifier and the div identifier of the injected template. Will be
``_<index>`` 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.
Example: If your plugin with identifier ``myplugin`` defines two tab components like this:
.. code-block:: python
return [
dict(type="tab", template="myplugin_first_tab.jinja2"),
dict(type="tab", template="myplugin_second_tab.jinja2")
]
then the first tab will have the component identifier ``plugin_myplugin`` and the second one will have
the component identifier ``plugin_myplugin_2`` (the generated divs will be ``tab_plugin_myplugin`` and
``tab_plugin_myplugin_2`` accordingly). Notice that the first tab is *not* called ``plugin_myplugin_1`` --
as stated above while the ``index`` used as default suffix starts counting at 1, it will not be applied
for the first component of a given type.
If on the other hand your plugin's definition looks like this:
.. code-block:: python
return [
dict(type="tab", template="myplugin_first_tab_jinja2", suffix="_1st"),
dict(type="tab", template="myplugin_second_tab_jinja2", suffix="_2nd")
]
then the generated component identifier will be ``plugin_myplugin_1st`` and ``plugin_myplugin_2nd``
(and the divs will be ``tab_plugin_myplugin_1st`` and ``tab_plugin_myplugin_2nd``).
* - div
- Id for the div containing the component. If not provided, defaults to ``<type>_plugin_<pluginname>`` plus
the ``suffix`` if provided or required.
* - replaces
- Id of the component this one replaces, might be either one of the core components or a component
provided by another plugin. A list of the core component identifiers can be found
:ref:`in the configuration documentation <sec-configuration-config_yaml-appearance>`. The identifiers of
other plugin components always follow the format described above.
* - custom_bindings
- A boolean value indicating whether the default view model should be bound to the component (``false``)
or if a custom binding will be used by the plugin (``true``, default).
* - data_bind
- Additional knockout data bindings to apply to the component, can be used to add further behaviour to
the container based on internal state if necessary.
* - classes
- Additional classes to apply to the component, 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 component, 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.
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
Structure of navbar plugins
Configures a navbar component to inject. The following keys are supported:
.. list-table::
:widths: 5 95
* - template
- Name of the template to inject, defaults to ``<pluginname>_navbar.jinja2``.
* - suffix
- Suffix to attach to the element ID of the injected template, will be ``_<index>`` 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.
* - div
- Id for the div containing the component. If not provided, defaults to ``plugin_<pluginname>`` plus
the suffix if provided or required.
* - replaces
- Id of navbar component this one replaces, might be either one of the core components or a component
provided by another plugin. See :ref:`this section <sec-plugins-templates>` for more on replacing template components.
* - 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
Structure of sidebar plugins
Configures a sidebar component to inject. The following keys are supported:
.. 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 ``<pluginname>_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 ``_<index>`` 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.
* - div
- Id for the div containing the component. If not provided, defaults to ``plugin_<pluginname>`` plus
the suffix if provided or required.
* - replaces
- Id of sidebar component this one replaces, might be either one of the core components or a component
provided by another plugin. See :ref:`this section <sec-plugins-templates>` for more on replacing template components.
* - 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
Structure of tab plugins
Configures a tab component to inject. The value must be a dictionary, supported values are the following:
``tab`` type and ``settings`` type
.. 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 ``<pluginname>_tab.jinja2``.
* - suffix
- Suffix to attach to the element ID of the injected template, will be ``_<index>`` 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.
* - div
- Id for the div containing the component. If not provided, defaults to ``plugin_<pluginname>`` plus
the suffix if provided or required.
* - replaces
- Id of tab component this one replaces, might be either one of the core components or a component
provided by another plugin. See :ref:`this section <sec-plugins-templates>` for more on replacing template components.
* - 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
Structure of settings plugins
Configures a settings component to inject. The value must be a dictionary, supported values are the following:
.. 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 ``<pluginname>_settings.jinja2``.
* - suffix
- Suffix to attach to the element ID of the injected template, will be ``_<index>`` 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.
* - div
- Id for the div containing the component. If not provided, defaults to ``plugin_<pluginname>`` plus
the suffix if provided or required.
* - replaces
- Id of settings component this one replaces, might be either one of the core components or a component
provided by another plugin. See :ref:`this section <sec-plugins-templates>` for more on replacing template components.
* - 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:
.. list-table::
:widths: 5 95
* - template
- Name of the template to inject, defaults to ``<pluginname>.jinja2``.
.. note::
As already outlined above, each template type has a default template name (i.e. the default navbar template
@ -452,6 +368,28 @@ class TemplatePlugin(OctoPrintPlugin):
those, since the implicit default template will only be included automatically if no other templates of that
type are defined.
Example: If you have a plugin that injects two tab components, one defined in the template file
``myplugin_tab.jinja2`` (the default template) and one in the template ``myplugin_othertab.jinja2``, you
might be tempted to just return the following configuration since one your templates is named by the default
template name:
.. code-block:: python
return [
dict(type="tab", template="myplugin_othertab.jinja2")
]
This will only include the tab defined in ``myplugin_othertab.jinja2`` though, ``myplugin_tab.jinja2`` will
not be included automatically since the presence of a defintion for the ``tab`` type overrides the automatic
injection of the default template. You'll have to include it explicitely:
.. code-block:: python
return [
dict(type="tab", template="myplugin_tab.jinja2"),
dict(type="tab", template="myplugin_othertab.jinja2")
]
:return list: a list containing the configuration options for the plugin's injected templates
"""
return []