Skip to main content

Create an editor


This section describes how to create a single editor for a 'simple' type app. Possible app types can be found in the app-types section.

To create an editor, we first need to define an entity type by creating its controller in

The controller class

To create an entity-type's controller class, define a class that inherits from ViktorController in The name of the class is the name of the entity type. The label attribute is obligatory and defines the name of the entity type as shown in the interface:

from viktor import ViktorController

class ExampleType(ViktorController): # defines entity type 'ExampleType'
label = "Example Type" # label to be shown in the interface

Next, we will define the editor's parametrization.

Click to see all available controller members

New in v13.7.0

Set viktor_enforce_field_constraints = True to simulate the future behavior of U83.

The controller class has the following members:

  • label (obligatory): name of the entity type as shown in the interface.
  • parametrization: defines the editor's parametrization.
  • summary: to show a summary.
  • children: (tree-type app only) define this entity-type's children. Not providing the key is equal to having no children.
  • show_children_as: (tree-type app only) defines how to visualize the children ('Table' | 'Cards').
  • methods for views.
  • methods for action buttons.
  • method for processing of a file upload.
  • any other methods you'd like to create yourself.

Defining a parametrization

To create the editor's parametrization, define a class that inherits from ViktorParametrization in and assign it to the controller class using the parametrization attribute.

The name of the parametrization class is arbitrary. Input fields and action buttons can be added to the editor by adding them as attributes on the parametrization class. For example:

from viktor import ViktorController
from viktor.parametrization import ViktorParametrization, TextField, NumberField

class Parametrization(ViktorParametrization):
input_1 = TextField('This is a text field') # add a field for textual input
input_2 = NumberField('This is a number field') # add a field for numeric input

class ExampleType(ViktorController):
parametrization = Parametrization # assign the parametrization class to the controller class

The above editor's parametrization will look as follows in the interface:

Example parametrization

Defining a view

Views can be added to the editor by defining a view method on the controller class and decorate it with one of the available view classes. The label argument is obligatory and defines the name of the view as shown in the interface, as well as the duration_guess argument, which tells the platform to render the view instantly or not.

The view method should return the view result that corresponds to the chosen view type (e.g. GeometryResult for a GeometryView). User input is passed to a view method by means of the params argument in the method's signature:

class ExampleType(ViktorController):

@GeometryView("Geometry view", duration_guess=1, x_axis_to_right=True) # decorate the view method with one of the available view classes
def my_geometry_view(self, params, **kwargs): # create a view method
geometries = ... # params can be used to create results based on the user input
return GeometryResult(geometries) # return the view result that corresponds to the view class
Click to see all available view arguments

Every view class has the following arguments:

  • label (obligatory): name of the view as shown in the interface.
  • duration_guess (obligatory): tells the platform whether the view should be rendered as a quick or slow visualization:
    • <= 3: Quick visualization, which updates with every change in the editor.
    • > 3: Slow visualization, which can be refreshed manually by means of an update button.
  • description: provide more information to the user through a tooltip (supports Markdown).
  • update_label: change the default text presented on the update button.


The following example controller implements 2 numeric input fields, a download button, and 2 views (geometry and data):

from viktor import ViktorController
from viktor.geometry import Point, Sphere
from viktor.parametrization import ViktorParametrization, NumberField, DownloadButton
from viktor.result import DownloadResult
from viktor.views import GeometryView, GeometryResult, DataView, DataResult, DataGroup, DataItem

class Parametrization(ViktorParametrization):
x = NumberField('X')
y = NumberField('Y')
download = DownloadButton("Download file", method='download_file')

class ModelController(ViktorController):
label = 'Model'
parametrization = Parametrization

@GeometryView('3D Geometry', duration_guess=1, x_axis_to_right=True)
def get_3d_view(self, params, **kwargs):
geometry = Sphere(Point(0, 0, 0), radius=10)
return GeometryResult(geometry)

@DataView('Data', duration_guess=1)
def get_data_view(self, params, **kwargs):
addition = params.x + params.y
multiplication = params.x * params.y

main_data_group = DataGroup(
DataItem('Data item 1', addition),
DataItem('Data item 2', multiplication),
return DataResult(main_data_group)

def download_file(self, params, **kwargs):
return DownloadResult('file content', 'file name')