Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Relations and embeds

For CMS developers, how objects refer to each other. It covers relation attributes, embeds and links in rich text, the four relation types, reading relations and reverse relations in templates and PHP, and what happens…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/cms-developers/relations-and-embeds.md

On this page

Relations and embeds

This page is for developers who model content that refers to other content: an event and its speakers, an article and its images, a product and its downloads. Exponential records every such reference as a relation between objects, so you can follow it in both directions and know what breaks before something is removed.

Contents

  1. Three ways to refer to content
  2. Relation attributes
  3. Embeds and links in rich text
  4. The relation types
  5. Relations in templates
  6. Reverse relations
  7. Relations in PHP
  8. Removing related content

Three ways to refer to content

WayUse it whenExample
A relation attribute (ezobjectrelationlist)the reference is structured data the template placesan event's speakers, an article's related_articles
An embed in rich textan editor places an object at a point in the textan image or a video in the middle of an article
A link in rich texttext points to another page"read our [privacy notice]"

A fourth option, a second location, puts the same object in two places of the tree. It is not a relation: use it only when the object truly belongs in both places (Objects, nodes and locations).

Relation attributes

ezobjectrelationlist (Object relations) holds an ordered list of objects. In the class editor you set, per attribute (kernel/classes/datatypes/ezobjectrelationlist/ezobjectrelationlisttype.php):

SettingEffect
Selection methodbrowse (pick in the tree), or a list of candidates in the edit form
Allowed classes (class_constraint_list)only objects of these classes can be chosen, for example exp_speaker
Default location (default_placement)where browsing starts, and where objects created from the edit form go

One edit form or browse takes at most 1000 related objects for one attribute (MAX_RELATIONS). ezobjectrelation holds a single object with fewer options; prefer the list datatype even for one target (Choosing datatypes).

In ezxmltext, an embed is <embed object_id="..." view="embed"/> (or node_id), and an inline embed is <embed-inline>. Links to content use <link object_id="..."> or node_id, and external links point to an entry of the link list. Each embed is drawn with the embed view mode of the embedded object's class, so the article template never needs to know what was embedded. Which view modes and classes editors can choose for embeds is set in content.ini [embed] and [embed-inline] (AvailableViewModes[], AvailableClasses[]). Templates: Embed view and Embed-inline view.

The relation types

Every relation is a row in ezcontentobject_link with a type, constants of eZContentObject:

ConstantValueMade by
RELATION_COMMON1the Relations of an object, added by editors on its related objects list
RELATION_EMBED2an embed in rich text
RELATION_LINK4a link to content in rich text
RELATION_ATTRIBUTE8a relation attribute (ezobjectrelation, ezobjectrelationlist)

The relations are stored per version, so an old version keeps the relations it had.

Relations in templates

The relation attribute's content is an array with the key relation_list; each item has contentobject_id and node_id. The simplest output is attribute_view_gui, which draws each target with its embed view. For your own markup:

{def $speakers = $node.data_map.speakers}
{if $speakers.has_content}
<ul class="exp-speakers">
    {foreach $speakers.content.relation_list as $item}
        {def $speaker = fetch( 'content', 'object', hash( 'object_id', $item.contentobject_id ) )}
        {if and( $speaker, $speaker.can_read )}
            <li>{content_view_gui view='line' content_object=$speaker}</li>
        {/if}
        {undef $speaker}
    {/foreach}
</ul>
{/if}

Check can_read: a relation does not grant access to its target. The shipped view template of the datatype (design/standard/templates/content/datatype/view/ezobjectrelationlist.tpl) also skips targets in the trash and hidden targets; the datatype is documented in ezobjectrelationlist.

The fetch related_objects returns the targets of an object directly, filtered by attribute if you like:

{def $related = fetch( 'content', 'related_objects', hash(
        'object_id', $node.contentobject_id,
        'attribute_identifier', 'exp_event/speakers' ) )}

Reverse relations

reverse_related_objects answers the opposite question: "which objects point at this one?" On a speaker's page it lists the speaker's events without a field on the speaker:

{def $events = fetch( 'content', 'reverse_related_objects', hash(
        'object_id', $node.contentobject_id,
        'all_relations', true() ) )}

This is why you store a reference on one side only: the other side is a fetch away. Counting variants exist for both (related_objects_count, reverse_related_objects_count).

Relations in PHP

<?php
$object = eZContentObject::fetchByRemoteID( 'exp-event-2026-opening' );
$speakers = $object->relatedObjects( false, false, 0, false,
    array( 'AllRelations' => eZContentObject::RELATION_ATTRIBUTE ) );
$pointingHere = $object->reverseRelatedObjectList( false, 0, false,
    array( 'AllRelations' => true ) );

Read the signatures in kernel/classes/ezcontentobject.php before you rely on a parameter; the book's reference has the common calls (eZContentObject). To set a relation attribute from an import, pass the target object IDs in the attribute's fromString() format (Content from PHP).

Removing or hiding an object that others point at leaves gaps. With content.ini [RemoveSettings] ReverseRelationCheck=warn (and the same key in [HideSettings]), the shipped default, the administration lists the objects that refer to it, including Layouts blocks, before it removes or hides anything (Reverse relation check). Templates should still expect a target to be missing, hidden or unreadable, as the example above does.

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x