# PID Tree Layout Configuration
A PID (parent ID) tree is a hierarchical tree structure. It visualizes the objects of a module and the relationships between them. A PID tree also allows to include a self-reference in the database's module table.
In the default, DAM module "Folder" is displayed as a tree structure in the sidebar of module "Files":
A PID tree structure can be configured for each module. The prerequisite for the creation and display of a tree structure is to enable the PID tree functionality in a module's module configurations. After that, the tree structure of a module can be added to a layout. Here you can also make further configurations, like adding actions or enabling a drag and drop functionality.
# Activate PID for a Module
To activate the PID tree functionality for a module, just follow these steps:
- Go to admin snap-in
Module configurations/{module}/Module definition
. - Set field "Enable hierarchical tree structure" (
enable_tree_structure
) totrue
. - Save your setting and reload/restart the system.
After reload/restart, new fields pid
and pid_path
are automatically created in the module table of the database. As soon as they are part of a module table, default system hooks that consider these fields will apply for this module, too.
In addition to the field itself, a non-unique index is created on field pid
.
You can now configure your layout to display the tree structure.
# Display and Configure Tree Structure
To display a module's tree structure in the GUI, you need to make a layout change in your target layout and add the pid_tree layout.
Optionally, you can configure the tree structure as a search filter and/or enable dropping objects from other modules in the same change.
As an example, we want to display module category
(Product Categories) as a tree structure in module product
(Products), and also enable the search filter and the external drag and drop functionalities:
- Add pid_tree layout
- Add search filter actors
- Configure drag and drop
- Shortcut: For a full PID tree layout that works out of the box, refer here.
# Add pid_tree Layout
First you need to add the pid_layout to your target layout. The default pid_layout is stored in folder global/defaults/layouts/pid_tree
and needs to be imported via a layout change. This change will add the tree structure of the defined module and in it, all actions that are enabled/visible for view "pid_tree" (action details).
In our example, we add the pid_layout to the main layout of module product
:
<change xpath="//component[@id='leftBar']/children" type="add">
<import_layout layout_id="pid_tree" module="category">
<parameter>
<entry class="string" key="displayField">name</entry>
</parameter>
</import_layout>
</change>
As a result, the sidebar of module "Products" will look like this:
# Customize Default Layout
If required, you can customize the settings of default layout pid_tree
. From it, you may change the following:
- the given parameters from tag
<consts>
- the involved actors' parameters
- parameter
minLiveSearchLength
to change the minimum number of characters required to start the live search (default: 3)
Remove Search Bar
If you want to remove the default search bar completely, you can only do so by changing the layout:
<change xpath="//component[@id='treeSearch']" type="remove"/>
Further Documentation: Layout changes
# PID Tree Specific Actions
For the tree structure objects, several actions are available. Some actions are pid_tree specific and can only be performed in a tree (e.g. "Create parent object").
Apart from that, each action will appear in the "More" button menu next to an object, as soon as it is set to visible=true for view pid_tree
:
<views>
<view visible="true">pid_tree</view>
</views>
Default Core Engine pid_tree actions are:
Name | Enabled/Visible in Menu | Description |
---|---|---|
pid_tree-create_parent | enabled by default visible * | allows users to create a parent object for the selected object |
pid_tree-create_child | enabled by default visible * | allows users to create a child object for the selected object |
pid_tree-rename | enabled by default visible * | allows to rename the selected object (field name ) |
pid_tree-delete_recursively | enabled by default visible | allows users to delete a complete branch (including all its child elements) |
pid_tree-link_internal | enabled by default not visible | allows to drop elements from the tree on other objects of the tree |
pid_tree-link_external | disabled by default not visible | allows to drop elements from other modules on objects of the tree |
* This action is only available, if displayField
is set to name
or another field but friendlyname
. For friendlyname
, this action does not work and will not be available in the tree.
# Configure Tree Structure as Search Filter
With the following change, you can add the actors required to display the contents of selected PID objects as a search result in the main view.
In our example, we want to display only products that are within the selected categories. The required search field is thus category
:
<change xpath="//actors" type="add">
<actor id="CategoryTreeRelatedSelectionSearchActor" type="RelatedPidSelectionSearchActor">
<parameter>
<entry class="string" key="pidSearchField">category</entry>
<entry class="string" key="pidPathSearchField">category.pid_path</entry>
<entry class="actor" key="searchActor">mainSearchActor</entry>
<entry class="actor" key="selectionActor">CategoryTreeSelectionActor</entry>
</parameter>
</actor>
<actor id="CategoryTreeSelectionActor" type="SelectionActor">
<parameter>
<entry class="boolean" key="multiple">true</entry>
<entry class="boolean" key="markable">true</entry>
</parameter>
</actor>
</change>
Additionally, both selectionActor
and pidSelectionSearchActor
need to be defined in the import_layout change:
<import_layout layout_id="pid_tree" module="category">
<parameter>
<entry class="actor" key="selectionActor">CategoryTreeSelectionActor</entry>
<entry class="actor" key="pidSelectionSearchActor">CategoryTreeRelatedSelectionSearchActor</entry>
<entry class="string" key="displayField">name</entry>
</parameter>
</import_layout>
# Configure Drag and Drop
For each PID tree in a layout, the drag and drop functionality can be enabled. With it, you can drop objects into the tree's objects. A distinction is made between internal and external dropping:
- With internal dropping you can move and drop elements within the tree. This function is controlled via action
pid_tree-link_internal
and is enabled by default. - With external dropping you can drop elements from outside the tree (i.e., another module) and thus create a relation. This function is controlled via action
pid_tree-link_external
and requires extra configuration.
To enable and configure drag and drop, further layout changes in the target layout are required. The following changes bring the following functionalities:
- First change:
- enable dragging objects of the tree (first map: "drag")
- enable internal dropping of categories in the "Category" tree (second map: "drop", first value)
- enable external dropping of products in the "Category" tree using field "category" from module "Products" (second map: "drop", second value)
- Second change:
- enable dragging objects from module "Products"
- Third change:
- apply drag options to all item renderer factories in search result (one for each view type: "tile", "grid", "list")
Please note: Dragging as well as internal dropping are modifications of default layout pid_tree
. Only the external dropping is not part of the default layout and must always be added.
<change xpath="//actors" type="add">
<!-- Enable dragging -->
<actor id="CategoryTreeDragAndDropOptions" type="DragAndDropOptions">
<parameter>
<entry class="map" key="drag">
<entry class="boolean" key="enabled">true</entry>
<entry class="boolean" key="showObjectImage">false</entry>
<entry class="boolean" key="showLabel">true</entry>
</entry>
<!-- Internal dropping -->
<entry class="array" key="drop">
<value class="map">
<entry class="string" key="moduleName">category</entry>
<entry class="boolean" key="preventSelf">true</entry>
<entry class="boolean" key="preventCircularReference">true</entry>
<entry class="string" key="actionName">pid_tree-link_internal</entry>
<entry class="string" key="modifier">NONE</entry>
</value>
<!-- External dropping from another module -->
<value class="map">
<entry class="string" key="moduleName">product</entry>
<entry class="string" key="relationFieldName">category</entry>
<entry class="boolean" key="isFieldInTarget">false</entry>
<entry class="string" key="actionName">pid_tree-link_external</entry>
<entry class="string" key="modifier">NONE</entry>
</value>
</entry>
</parameter>
</actor>
</change>
<change xpath="//actors" type="add">
<actor id="ProductsDragAndDropOptions" type="DragAndDropOptions">
<parameter>
<entry class="map" key="drag">
<entry class="boolean" key="enabled">true</entry>
<entry class="boolean" key="showObjectImage">false</entry>
<entry class="boolean" key="showLabel">true</entry>
</entry>
</parameter>
</actor>
</change>
<change xpath="//actor[@type='SearchFactory']/parameter" type="add">
<entry class="map" key="itemRendererProperties">
<entry class="actor" key="dragAndDropOptions">ProductsDragAndDropOptions</entry>
</entry>
</change>
Further Documentation
# Full Layout Example
In the XML example, all configurations described above apply. If you want to add this to a layout, make sure to replace the target/source module names and field names as well as the actor IDs.
This layout change should work out of the box in any standard main view.
<changes>
<!-- Import pid_tree layout -->
<change xpath="//component[@id='leftBar']/children" type="add">
<import_layout layout_id="pid_tree" module="category">
<parameter>
<entry class="actor" key="selectionActor">CategoryTreeSelectionActor</entry>
<entry class="actor" key="pidSelectionSearchActor">CategoryTreeRelatedSelectionSearchActor</entry>
<entry class="string" key="displayField">name</entry>
<entry class="actor" key="dragAndDropOptions">CategoryTreeDragAndDropOptions</entry>
</parameter>
</import_layout>
</change>
<!-- Search Filter -->
<change xpath="//actors" type="add">
<actor id="CategoryTreeRelatedSelectionSearchActor" type="RelatedPidSelectionSearchActor">
<parameter>
<entry class="string" key="pidSearchField">category</entry>
<entry class="string" key="pidPathSearchField">category.pid_path</entry>
<entry class="actor" key="searchActor">mainSearchActor</entry>
<entry class="actor" key="selectionActor">CategoryTreeSelectionActor</entry>
</parameter>
</actor>
<actor id="CategoryTreeSelectionActor" type="SelectionActor">
<parameter>
<entry class="boolean" key="multiple">true</entry>
<entry class="boolean" key="markable">true</entry>
</parameter>
</actor>
</change>
<!-- Drag and Drop -->
<change xpath="//actors" type="add">
<actor id="CategoryTreeDragAndDropOptions" type="DragAndDropOptions">
<parameter>
<entry class="map" key="drag">
<entry class="boolean" key="enabled">true</entry>
<entry class="boolean" key="showObjectImage">false</entry>
<entry class="boolean" key="showLabel">true</entry>
</entry>
<entry class="array" key="drop">
<value class="map">
<entry class="string" key="moduleName">category</entry>
<entry class="boolean" key="preventSelf">true</entry>
<entry class="boolean" key="preventCircularReference">true</entry>
<entry class="string" key="actionName">pid_tree-link_internal</entry>
<entry class="string" key="modifier">NONE</entry>
</value>
<value class="map">
<entry class="string" key="moduleName">product</entry>
<entry class="string" key="relationFieldName">category</entry>
<entry class="boolean" key="isFieldInTarget">false</entry>
<entry class="string" key="actionName">pid_tree-link_external</entry>
<entry class="string" key="modifier">NONE</entry>
</value>
</entry>
</parameter>
</actor>
</change>
<change xpath="//actors" type="add">
<actor id="ProductsDragAndDropOptions" type="DragAndDropOptions">
<parameter>
<entry class="map" key="drag">
<entry class="boolean" key="enabled">true</entry>
<entry class="boolean" key="showObjectImage">false</entry>
<entry class="boolean" key="showLabel">true</entry>
</entry>
</parameter>
</actor>
</change>
<change xpath="//actor[@type='SearchFactory']/parameter" type="add">
<entry class="map" key="itemRendererProperties">
<entry class="actor" key="dragAndDropOptions">ProductsDragAndDropOptions</entry>
</entry>
</change>
</changes>