Basics
EditorModelExtensions
EditorModelExtensions are the core mechanism for extending the functionality of the editor through plugins. They allow you to customize how your model is represented, displayed, and interacted with within the editor.
Extensions are defined in XML files located within the model/extensions/ directory of your plugin. Each extension is declared in its own XML file, like so:
model/
plugin.xml
extensions/
elements.xml
application-project.xml
prime-diagrams.xml
Each extension file starts with the <editorModelExtension> root element and specifies a unique name:
<editorModelExtension xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>elements</name>
</editorModelExtension>
ElementTreeNode: Building the Model's Tree View
ElementTreeNode Components are responsible for defining how elements in your model are represented within the editor's tree view. They dictate the structure and content of the tree, allowing users to navigate and understand the model's hierarchy.
You define these components within the <elementTreeNodes> section of your extension:
<editorModelExtension xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>elements</name>
<elementTreeNodes>
<elementTreeNode>
<name>Component</name>
<!-- ElementClass this node represents -->
<elementClass>elements::Component</elementClass>
<children>
<!-- nested nodes -->
<elementTreeList>
<!-- label for the nested elements -->
<name>dataElements</name>
<!-- ElementTreeNode used for the nested elements -->
<childNodeType>elements::DataElement</childNodeType>
<!-- Reference used as data source -->
<compositionReference>elements::Component::dataElements</compositionReference>
</elementTreeList>
</children>
<options>
<!-- Define an icon for this tree node to represent the target ElementClass -->
<mrp.material.symbols.icon>graph_2</mrp.material.symbols.icon>
</options>
</elementTreeNode>
<elementTreeNode>
<name>DataElement</name>
<elementClass>elements::DataElement</elementClass>
<!-- ... -->
<options>
<mrp.material.symbols.icon>data_table</mrp.material.symbols.icon>
</options>
</elementTreeNode>
</elementTreeNodes>
</editorModelExtension>
In this example:
- The
Componenttree node represents elements ofelements::Componentclass. - It can have child nodes, specifically a list named
dataElements. - This
dataElementslist will display children of typeelements::DataElement, sourced from theelements::Component::dataElementscomposition reference.
ElementDetailComponent: Displaying and Modifying Element Details
ElementDetailComponents define the user interface for displaying and modifying the properties of a selected model element. This is where users interact with the specific attributes and relationships of an element.
Configure these components within the <elementDetailComponents> section of your extension:
<editorModelExtension xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>elements</name>
<elementDetailComponents>
<elementDetailComponent>
<name>Component</name>
<!-- Set autogenerate to `false` to completely customize the detail view. -->
<autogenerate>true</autogenerate>
<elementClass>elements::Component</elementClass>
<options>
<!-- Add the color option to link a specific color hue to elements of this type. -->
<color.lch.hue>270</color.lch.hue>
</options>
</elementDetailComponent>
<elementDetailComponent>
<name>DataElement</name>
<autogenerate>true</autogenerate>
<elementClass>elements::DataElement</elementClass>
<options>
<color.lch.hue>270</color.lch.hue>
</options>
</elementDetailComponent>
</elementDetailComponents>
</editorModelExtension>
Here:
- An ElementDetailComponent named
Componentis defined for theelements::Componentclass. - When
autogenerateis set totrue(as shown), the editor automatically generates a default detail view based on the element's schema. - Setting
autogeneratetofalseallows you to provide a custom UI for the detail view, offering complete control over its appearance and functionality.
Actions: Enabling model interactions
Actions allow you to define operations that users can perform on model elements, such as creating and deleting elements. These actions are defined once in your extension and then linked to specific tree nodes or lists where they should be available.
Defining actions
Actions are defined within the <actions> section of your editorModelExtension:
<editorModelExtension
xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<name>elements</name>
<actions>
<editorAction type="editorElements::CreateAction" xsi:type="createAction">
<!-- Unique identifier -->
<name>createComponentDataElements</name>
<!-- Detail Component used to edit the new instance -->
<elementDetailComponent>elements::DataElement</elementDetailComponent>
<!-- Composition reference to which to add the new instance. -->
<reference>elements::Component::dataElements</reference>
</editorAction>
<editorAction type="editorElements::DeleteAction" xsi:type="deleteAction">
<name>deleteDataElement</name>
<elementClass>elements::DataElement</elementClass>
</editorAction>
</actions>
</editorModelExtension>
In this example:
createComponentDataElementsis aCreateActionthat creates a new DataElement and adds it to thedataElementsreference of a Component. Theelements::DataElementdetail component will be used for editing the new instance.deleteDataElementis aDeleteActionspecifically forelements::DataElementinstances.
Assigning Actions to Tree Nodes and Lists
Once defined, actions are linked to elementTreeNode or elementTreeList entries within the <actions> tag:
<editorModelExtension
xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<name>elements</name>
<actions>
<!-- ... -->
</actions>
<elementTreeNodes>
<elementTreeNode>
<name>Component</name>
<elementClass>elements::Component</elementClass>
<actions>
<editorAction>elements::createComponentDataElements</editorAction>
</actions>
<children>
<elementTreeList>
<name>dataElements</name>
<actions>
<editorAction>elements::createComponentDataElements</editorAction>
</actions>
<childNodeType>elements::DataElement</childNodeType>
<compositionReference>elements::Component::dataElements</compositionReference>
</elementTreeList>
</children>
</elementTreeNode>
<elementTreeNode>
<name>DataElement</name>
<elementClass>elements::DataElement</elementClass>
<actions>
<editorAction>elements::deleteDataElement</editorAction>
</actions>
</elementTreeNode>
</elementTreeNodes>
</editorModelExtension>
Activation condition: Controlling Plugin Availability
You can control when an editorModelExtension (and thus its associated plugin functionality) becomes active within the
editor. This is achieved by adding an <activation> element to your extension.
- Activate when an Ontology is loaded.
- Activate when an instance of an ElementType is detected.
To activate an extension only when a specific ontology is present in the dataRegistry,
use the ActivateIfOntologyPresent type:
<editorModelExtension
xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<name>prime-diagrams</name>
<activation type="editorElements::ActivateIfOntologyPresent" xsi:type="activateIfOntologyPresent">
<ontology>elements</ontology>
</activation>
</editorModelExtension>
This configuration ensures that the prime-diagrams extension will only be active if the elements ontology
is supported by the expansion-resources defined by the project.
To activate an extension when an instance of a particular ElementClass is detected in the model,
use the ActivateIfElementTypePresent type:
<editorModelExtension
xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<name>application-project</name>
<activation type="editorElements::ActivateIfElementTypePresent" xsi:type="activateIfElementTypePresent">
<elementType>elements::Application</elementType>
</activation>
</editorModelExtension>
This means the application-project extension will become active only if an instance of elements::Application
exists within the model being edited.