= definition()
:description: Loads and parses the ECM server's object definition (dms.GetObjDef, UTF-16 XML). Returns an ECMDefinition with cabinets, object types, and field definitions.
:keywords: definition, dms.GetObjDef, ECMDefinition, asobjdef, cabinets, object types, field definitions, UTF-16
:page-tags: api, system

Returns the complete object definition of the connected ECM server as a typed
`ECMDefinition` object. The definition is fetched once via `dms.GetObjDef` and then
cached on the `ecm.system` namespace. Subsequent calls return the same instance.

== Signature

[tabs]
====
Sync::
+
[source,python]
----
ecm.system.definition(*, force_reload: bool = False) -> ECMDefinition
----

Async::
+
[source,python]
----
await ecm.system.definition(*, force_reload: bool = False) -> ECMDefinition
----
====

== Parameters

[cols="1,1,1,3"]
|===
|Parameter |Type |Default |Description

|`force_reload`
|`bool`
|`False`
|When `True`, the cached instance is discarded and the definition is fetched from the server again.
|===

== Return value

An `ECMDefinition` instance. All parsing happens eagerly during construction.

=== ECMDefinition

[cols="1,1,3"]
|===
|Property |Type |Description

|`primary_language`
|`ECMLanguageDefinition`
|The system primary language.

|`available_languages`
|`dict[str, ECMLanguageDefinition]`
|All active languages keyed by ISO locale code (e.g. `"de_DE"`).

|`all_languages`
|`dict[str, ECMLanguageDefinition]`
|All languages keyed by ISO locale code, including inactive ones.

|`cabinets`
|`dict[str, ECMCabinetDefinition]`
|All cabinet definitions keyed by internal name.

|`created`
|`datetime`
|Timestamp when the definition was generated on the server.

|`version`
|`str`
|Server version string (e.g. `"5.20"`).

|`limited_objects`
|`bool`
|`True` if the definition contains only a limited subset of object types.

|`definition["InternalName"]`
|`ECMObjectDefinition`
|Lookup by internal name across all cabinets. Raises `KeyError` if not found.

|`definition[type_id]`
|`ECMObjectDefinition`
|Lookup by composite type ID (`(maintype << 16) \| cotype`). Raises `KeyError` if not found.
|===

=== ECMLanguageDefinition

[cols="1,1,3"]
|===
|Field |Type |Description

|`lang_id`
|`int`
|Numeric language identifier used throughout the definition XML.

|`name`
|`str`
|Human-readable language name (e.g. `"German"`).

|`iso_code`
|`str`
|ISO locale code (e.g. `"de_DE"`).

|`is_active`
|`bool`
|`True` if the language is active on the server.

|`is_primary`
|`bool`
|`True` if this is the primary language.
|===

=== ECMCabinetDefinition

[cols="1,1,3"]
|===
|Property / Method |Type |Description

|`internal_name`
|`str`
|Internal name of the cabinet.

|`name`
|`str`
|Display name of the cabinet.

|`cotype`
|`int`
|Numeric cabinet type ID.

|`objects`
|`dict[str, ECMObjectDefinition]`
|All object types in this cabinet keyed by internal name.

|`folders`
|`dict[str, ECMFolderDefinition]`
|Filtered view — folder types only.

|`registers`
|`dict[str, ECMRegisterDefinition]`
|Filtered view — register types only.

|`documents`
|`dict[str, ECMDocumentDefinition]`
|Filtered view — document types only.

|`cabinet["InternalName"]`
|`ECMObjectDefinition`
|Direct access by internal name. Raises `KeyError` if not found.

|`"InternalName" in cabinet`
|`bool`
|Membership test by internal name.
|===

=== ECMObjectDefinition

Common base for `ECMFolderDefinition`, `ECMRegisterDefinition`, and `ECMDocumentDefinition`.

[cols="1,1,3"]
|===
|Property |Type |Description

|`internal_name`
|`str`
|Internal (programmatic) name of the object type.

|`maintype`
|`ECMMainType`
|Main type enum member (e.g. `FOLDER`, `REGISTER`, `DOC_WINDOWS`).

|`cotype`
|`int`
|Numeric object type ID.

|`type_id`
|`int`
|Composite type identifier: `(maintype.value << 16) \| cotype`.

|`os_guid`
|`str`
|Server-side GUID identifying this object type.

|`tablename`
|`str`
|Primary database table name.

|`description`
|`ECMDescriptionEntry \| None`
|Name entry for the primary language, or `None` if not available.

|`descriptions`
|`dict[str, ECMDescriptionEntry]`
|All language-specific name entries, keyed by ISO locale code.

|`fields`
|`dict[str, ECMFieldDefinition]`
|Top-level fields only. Does not include fields nested inside PageControl pages.

|`all_fields`
|`dict[str, ECMFieldDefinition]`
|All fields flattened recursively across all PageControl pages.

|`obj["InternalName"]`
|`ECMFieldDefinition`
|Shortcut for `obj.all_fields["InternalName"]`. Raises `KeyError` if not found.

|`fulltext`
|`ECMFulltextMode`
|Full-text indexing mode: `DISABLED`, `AUTOMATIC`, or `MANUAL`.

|`history_flags`
|`ECMHistoryFlags`
|Decoded history tracking flags (index history, document history, versions).

|`compression_flags`
|`ECMCompressionMode`
|File compression mode: `DISABLED`, `MERGE_ONLY`, or `MERGE_AND_COMPRESS`.

|`limited_objects`
|`list[ECMLimitedObjectEntry]`
|Allowed child object types and their maximum counts.
|===

`ECMDocumentDefinition` adds one additional field:

[cols="1,1,3"]
|===
|Field |Type |Description

|`cross_module_document_type`
|`bool`
|`True` if this document type spans multiple modules.
|===

==== ECMMainType enum

[cols="1,1"]
|===
|Member |Description

|`FOLDER`
|Folder object type.

|`REGISTER`
|Register object type.

|`DOC_GRAYSCALE`
|Grayscale image document.

|`DOC_BW`
|Black-and-white image document.

|`DOC_COLOR`
|Colour image document.

|`DOC_WINDOWS`
|Windows application document.

|`DOC_MULTIMEDIA`
|Multimedia document.

|`DOC_MAIL`
|E-mail document.

|`DOC_XML`
|XML document.

|`DOC_CONTAINER`
|Container document.
|===

=== ECMDescriptionEntry

Holds the language-specific label of an object type, field, or tab.

[cols="1,1,3"]
|===
|Field |Type |Description

|`name`
|`str`
|Display name.

|`tooltip`
|`str`
|Tooltip text shown in the UI.

|`image_id`
|`str`
|Icon image identifier.

|`default_url`
|`str`
|URL used for the default view.

|`new_url`
|`str`
|URL used when creating a new object.

|`update_url`
|`str`
|URL used when updating an object.

|`request_url`
|`str`
|URL used for checkout / request.

|`readonly_url`
|`str`
|URL used for the read-only view.
|===

=== ECMFieldDefinition

Represents a single field of an object type.

[cols="1,1,3"]
|===
|Property |Type |Description

|`internal_name`
|`str`
|Internal (programmatic) name of the field.

|`field_name`
|`str`
|Database column name (e.g. `"feld001"`). Empty for static UI elements.

|`data_type`
|`ECMFieldDataType \| None`
|Logical data type. `None` for static UI elements (groups, labels, etc.).

|`control`
|`ECMControlType`
|UI control type (textfield, checkbox, table, page control, etc.).

|`catalog`
|`ECMCatalogType \| None`
|Catalog type, or `None` if the field has no catalog.

|`description`
|`ECMDescriptionEntry`
|Label for the primary language.

|`descriptions`
|`dict[str, ECMDescriptionEntry]`
|Labels for all languages, keyed by ISO locale code.

|`required`
|`bool`
|`True` if the field is mandatory.

|`readonly`
|`bool`
|`True` if the field is always read-only.

|`readonly_after_archiving`
|`bool`
|`True` if the field becomes read-only after archiving.

|`key_field`
|`bool`
|`True` if this is a key field.

|`supervisor`
|`bool`
|`True` if only supervisors can edit this field.

|`multiline`
|`bool`
|`True` if the field accepts multiline text input.

|`input_length`
|`int \| None`
|Maximum input length, or `None` if not specified.

|`regular_expression`
|`str`
|Validation regular expression, empty if none.

|`init`
|`str`
|Default / initialisation value expression, empty if none.

|`is_static`
|`bool`
|`True` for pure UI elements (groups, labels, page controls) without a database column.

|`pages`
|`dict[str, ECMPageDefinition]`
|Tabs of a PageControl field (`control == PAGE_CONTROL`). Empty for all other types.

|`columns`
|`dict[str, ECMTableColumnDefinition]`
|Column definitions of a TableField (`control == TABLEFIELD`). Empty for all other types.

|`list_values`
|`ECMFieldList \| None`
|Inline catalog values embedded in the definition, or `None` for database / add-on catalogs.
|===

==== ECMFieldDataType enum

[cols="1,1"]
|===
|Member |Description

|`STRING`
|Text field (`field_name` starts with `feld`).

|`INTEGER`
|Whole-number field.

|`BOOLEAN`
|Boolean / checkbox field.

|`DOUBLE`
|Decimal number field.

|`DATE`
|Date field.

|`TIME`
|Time field.

|`DATE_TIME`
|Combined date and time field.
|===

==== ECMControlType enum

[cols="1,1"]
|===
|Member |Description

|`TEXTFIELD`
|Standard text, date, or number input.

|`TABLEFIELD`
|Multi-row table / grid control.

|`RADIOBUTTON`
|Radio button.

|`CHECKBOX`
|Checkbox.

|`PICTURE`
|Image control.

|`GROUP`
|Group box (visual grouping, no database column).

|`PAGE_CONTROL`
|Tab / page control (contains `pages`).

|`WEBCONTROL`
|Embedded web control.

|`BUTTON`
|Push button.

|`LABEL`
|Static label (no database column).
|===

==== ECMCatalogType enum

[cols="1,1"]
|===
|Member |Description

|`DATABASE`
|Database catalog.

|`ADDON`
|Add-on (DLL) catalog.

|`LIST`
|Flat inline list.

|`TREE`
|Tree catalog.

|`HIERARCHY_TREE`
|Hierarchy tree catalog.

|`STRUCTURE_TREE`
|Structure tree catalog.
|===

=== ECMPageDefinition

Represents a single tab inside a PageControl field.

[cols="1,1,3"]
|===
|Field |Type |Description

|`internal_name`
|`str`
|Internal name of the page.

|`position`
|`int`
|Zero-based display order within the PageControl.

|`description`
|`ECMDescriptionEntry \| None`
|Label for the primary language, or `None` if not set.

|`descriptions`
|`dict[str, ECMDescriptionEntry]`
|Labels for all languages, keyed by ISO locale code.

|`fields`
|`dict[str, ECMFieldDefinition]`
|Fields on this page, keyed by internal name.
|===

=== ECMTableColumnDefinition

Represents a single column of a TableField.

[cols="1,1,3"]
|===
|Field |Type |Description

|`internal_name`
|`str`
|Internal name of the column.

|`field_name`
|`str`
|Database column name.

|`data_type`
|`ECMFieldDataType \| None`
|Logical data type of the column.

|`readonly`
|`bool`
|`True` if the column is read-only.

|`col_pos`
|`int`
|Zero-based display order of the column in the grid.

|`col_width`
|`int`
|Display width in grid units (`0` = auto).

|`description`
|`ECMDescriptionEntry \| None`
|Label for the primary language.

|`descriptions`
|`dict[str, ECMDescriptionEntry]`
|Labels for all languages, keyed by ISO locale code.
|===

== Examples

=== Read primary language and server version

[tabs]
====
Sync::
+
[source,python]
----
definition = ecm.system.definition()
print(definition.version)                       # e.g. "5.20"
print(definition.primary_language.iso_code)     # e.g. "de_DE"
print(definition.created)
----

Async::
+
[source,python]
----
definition = await ecm.system.definition()
print(definition.version)
print(definition.primary_language.iso_code)
print(definition.created)
----
====

=== List all object types in all cabinets

[tabs]
====
Sync::
+
[source,python]
----
definition = ecm.system.definition()
for cabinet in definition.cabinets.values():
    print(f"Cabinet: {cabinet.name}")
    for folder in cabinet.folders.values():
        label = folder.description.name if folder.description else folder.internal_name
        print(f"  Folder: {folder.internal_name} ({label})")
    for doc in cabinet.documents.values():
        label = doc.description.name if doc.description else doc.internal_name
        print(f"  Document: {doc.internal_name} ({label})")
----

Async::
+
[source,python]
----
definition = await ecm.system.definition()
for cabinet in definition.cabinets.values():
    print(f"Cabinet: {cabinet.name}")
    for folder in cabinet.folders.values():
        label = folder.description.name if folder.description else folder.internal_name
        print(f"  Folder: {folder.internal_name} ({label})")
    for doc in cabinet.documents.values():
        label = doc.description.name if doc.description else doc.internal_name
        print(f"  Document: {doc.internal_name} ({label})")
----
====

=== Inspect fields of an object type

[tabs]
====
Sync::
+
[source,python]
----
definition = ecm.system.definition()
obj = definition["InvoiceFolder"]

for field in obj.all_fields.values():
    if field.is_static:
        continue
    print(
        field.internal_name,
        field.data_type,
        "required" if field.required else "",
        "readonly" if field.readonly else "",
    )
----

Async::
+
[source,python]
----
definition = await ecm.system.definition()
obj = definition["InvoiceFolder"]

for field in obj.all_fields.values():
    if field.is_static:
        continue
    print(
        field.internal_name,
        field.data_type,
        "required" if field.required else "",
        "readonly" if field.readonly else "",
    )
----
====

=== Access fields with catalog values

[tabs]
====
Sync::
+
[source,python]
----
definition = ecm.system.definition()
obj = definition["InvoiceFolder"]

for field in obj.all_fields.values():
    if field.catalog is None:
        continue
    print(f"{field.internal_name}: catalog={field.catalog}")
    if field.list_values:
        for row in field.list_values.rows:
            print(f"  [{row.index}] {row.value}")
----

Async::
+
[source,python]
----
definition = await ecm.system.definition()
obj = definition["InvoiceFolder"]

for field in obj.all_fields.values():
    if field.catalog is None:
        continue
    print(f"{field.internal_name}: catalog={field.catalog}")
    if field.list_values:
        for row in field.list_values.rows:
            print(f"  [{row.index}] {row.value}")
----
====

=== Inspect PageControl tabs and their fields

[tabs]
====
Sync::
+
[source,python]
----
definition = ecm.system.definition()
obj = definition["InvoiceFolder"]

for field in obj.fields.values():
    if field.control.value != "page_control":
        continue
    for page in field.pages.values():
        label = page.description.name if page.description else page.internal_name
        print(f"Tab: {label}")
        for page_field in page.fields.values():
            if not page_field.is_static:
                print(f"  {page_field.internal_name} ({page_field.data_type})")
----

Async::
+
[source,python]
----
definition = await ecm.system.definition()
obj = definition["InvoiceFolder"]

for field in obj.fields.values():
    if field.control.value != "page_control":
        continue
    for page in field.pages.values():
        label = page.description.name if page.description else page.internal_name
        print(f"Tab: {label}")
        for page_field in page.fields.values():
            if not page_field.is_static:
                print(f"  {page_field.internal_name} ({page_field.data_type})")
----
====

=== Inspect table field columns

[tabs]
====
Sync::
+
[source,python]
----
definition = ecm.system.definition()
obj = definition["InvoiceFolder"]

for field in obj.all_fields.values():
    if field.control.value != "tablefield":
        continue
    print(f"Table: {field.internal_name}")
    for col in field.columns.values():
        print(f"  {col.internal_name} ({col.data_type})")
----

Async::
+
[source,python]
----
definition = await ecm.system.definition()
obj = definition["InvoiceFolder"]

for field in obj.all_fields.values():
    if field.control.value != "tablefield":
        continue
    print(f"Table: {field.internal_name}")
    for col in field.columns.values():
        print(f"  {col.internal_name} ({col.data_type})")
----
====

=== Force reload after a server change

[tabs]
====
Sync::
+
[source,python]
----
definition = ecm.system.definition(force_reload=True)
----

Async::
+
[source,python]
----
definition = await ecm.system.definition(force_reload=True)
----
====

== See also

* xref:api/system/index.adoc[ecm.system] — Namespace overview
