4

I have content type with entity reference to node of same content type. And I would like to show the nested references in the node view. Sort of a tree view.

How could I accomplish that?

I guess I need a view and a view field? But even not yet sure how to create a view which does recursive relationship...

It is for managing software dependencies and releases, there are libraries (=content type) dependent on 1:n libraries.

1 Answer 1

4

That can be accomplished with a custom module (great question by the way)...

First define a function to handle the whole process:

function make_tree() {

  // This is the nid of the root of our tree - could be passed in as an argument
  // instead of being static.
  $root_nid = 110;

  // First build an array with 3 fields - id, parent_id, title.
  $data = array();

  // We call add row once and then it's called resursivly to fetch each child.
  add_row($root_nid, null, $data);

  // Here we can inspect our data in it's flat form.
  //dpm($data);

  // Now turn the flat data into a multi-dimensional array.
  $tree = build_tree($data);

  // And inspect our tree.
  dpm($tree);

  // Could return the tree here or do anything we want with it...

}

Then define the function to build the flat array of data:

function add_row($nid, $parent_nid, &$data) {

  $node = node_load($nid);

  $data[$node->nid] = array(
    'id' => $node->nid,
    'parent_id' => $parent_nid,
    'title' => $node->title,
  );

  if(isset($node->field_dependent[LANGUAGE_NONE])) {
    // Now loop childeren to add rows for them too.
    // My entity relationship field is called dependent but rename here as
    // necesary.
    foreach($node->field_dependent[LANGUAGE_NONE] as $child) {
      add_row($child['target_id'], $node->nid, $data);
    }
  }

}

Once this step has been completed the $data array will look like this.

And then finally the function to turn the flat array into a multi-dimensional one (credit to this answer for this step):

function build_tree(array $elements, $parentId = 0) {
    $branch = array();
    foreach ($elements as $element) {
        if ($element['parent_id'] == $parentId) {
            $children = build_tree($elements, $element['id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[] = $element;
        }
    }
    return $branch;
}

I've just tested this and my final array looks like this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.