NodeType References

Neos 9

This page is for Neos 9.0 with the new Event Sourced Content Repository.

Why we introduce a new concept

Up until Neos 8, references are basically just properties of type Node (reference) or array of Nodes (references), meaning that accessing the nodes property "someReferenceProperty" you'd get the referenced node(s).

This comes with one major drawback: reference properties cannot be resolved in inverse direction. To find out the reverse direction in a performant way, you need additional tooling like Elasticsearch to find out which other nodes reference a given node. This changes fundamentally with the Content Repository rewrite in Neos 9.

#References as first class citizens

While there were only nodes before, the new Content Repository comes with a new concept: references. These are modeled as edges connecting the two nodes in the content graph, allowing traversal in both directions.

source node
source node
target node
target node
reference
reference
Text is not SVG - cannot display

References are also represented by their own PHP read model class, consisting of

  • the target node
  • a name (the property name declared in the source node's NodeType)
  • (optional) properties of the reference

#Declaring references

Reference property declaration has changed in only one aspect: It is now possible to really restrict references to certain node types, not just the UI editor:

This will effectively prevent referencing anything other than nodes of type Acme.Site:ReferenceableNodefor this property on CR level, not just in the Neos UI.

yaml
'Acme.Site:DemoNode':
  references: 
    restrictedReferenceProperty: 
      constraints: 
        nodeTypes: 
          '*': false
          'Acme.Site:ReferenceableNode': true

#Properties on references

Another new feature is that references - now that they are objects themselves - can have their own properties. This comes in really handy if you want to further describe the relation between the two nodes, as in "Node B is related to node A in that...". Properties work on references basically the same way they do on nodes, with the exception that reference properties cannot be of type reference(s)themselves. They can be declared in the node type configuration as follows:

yaml
'Acme.Site:DemoNode':
  references:
    referencePropertyWithProperties:
      constraints:
        maxItems: 1
      properties:
        text:
          type: string
        postalAddress:
          type: 'Acme\Site\Domain\PostalAddress'
  multipleReferencesPropertyWithProperties:
    properties:
      text:
        type: string
    postalAddress:
      type: 'Acme\Site\Domain\PostalAddress'

Limitations in the Neos UI

Properties on references can currently only be set using the CR's command API, the Neos UI does not support editing them yet.

#Reading references in Fusion

The FlowQuery property operation has been adjusted to also work with references, so you can still call

Property operation on a node property of type reference
q(node).property('someSingleReferenceProperty')

to fetch the referenced node(s).

In addition, there are two new dedicated FlowQuery operations available.

references works like property, but returns the reference records (including their own properties if available) instead of the resolved nodes:

ReferencingNodes operation
q(node).references()
q(node).references('someReferenceProperty')

to access properties of the reference, the referenceProperty operation can be used:

References operation
q(node).references().referenceProperty('referenceProperty')

And finally, the nodes operation can be used to retrieve the referenced nodes:

Property operation on references
q(node).references().nodes()

backReferences works in the opposite direction as references , returning a FlowQuery containing all references to the given node.

Referencing operation
q(node).backReferences()
q(node).backReferences('someReferenceProperty')
q(node).backReferences().referenceProperty('somePropertyOnTheReference')
q(node).backReferences().nodes()