1

Let's say that I have two content types:

  • Article

    • title
    • body
    • field_ref_term
  • Page

    • title
    • body
    • field_ref_term

Those two content types are sharing the same field: "field_ref_term" wich is a "Entity reference" field type, to another entity called 'Term' (or something else, it doesn't mind).

What I'm trying to do is, when displaying a particular content of type "Page", I would like to be able to display a list of content in a block who shares the same value for the "field_ref_term" field.

It's a bit like the "Content: Has taxonomy term ID" contextual filter from Views and Taxonomies, where you set the value to "Taxonomy term ID from URL" then check "Load default filter from node page, that's good for related taxonomy blocks".

Do you think this is currently possible with Entity Reference ?

Thanks

2 Answers 2

4

I finally found a way to do it, here are the steps:

  1. Add a relationship: Entity Reference: Referenced Entity, select the right field to match, select "Require this relationship"
  2. Add a relationship: Entity Reference: Referencing Entity, selection the just add relationship in step 2 and check "Require this relationship".
  3. Add a contextual filter: Content:nid, provide default value: Content ID from URL
  4. Add a contextual filter: Content:nid, select the relationship "Content referencing...", provide default value: Content ID from URL, then in the More fieldset, check exclude.
  5. Add a field "Title" and select the relationship "Content Referencing..."

I will close this question, feel free to comment or propose other solutions.

Thanks.

1
  • Nice! Very helpful. Thanks for sharing the answer.
    – gkom
    Oct 23, 2014 at 19:54
1

As opposed to the other answer, if you need it programmatically :

a quite dynamic solution (a bit dirty too but I needed it quickly) so you do not need to hard code the name fo the referencing field and it is automatically handled with new referencing field you will add in the future :

in your custom module :

/**
 * Implement hook_field_create_instance().
 */
function MY_CUSTOM_MODULE_field_create_instance() {
  _MY_CUSTOM_MODULE_set_variable_node_back_references();
}

/**
 * Implement hook_field_delete_field().
 */
function MY_CUSTOM_MODULE_field_delete_field() {
  _MY_CUSTOM_MODULE_set_variable_node_back_references();
}

/**
 * Set Variable node_back_references.
 */
function _MY_CUSTOM_MODULE_set_variable_node_back_references() {
  $field_list = db_select('field_config', 'fc')
    ->fields('fc', array('field_name', 'data'))
    ->condition('fc.data', '%"foreign keys";a:1:{s:4:"node"%', 'like')
    ->condition('fc.deleted', 0);
  $field_list->innerJoin('field_config_instance', 'fci', 'fci.field_name = fc.field_name');
  $field_list->rightJoin('node_type', 'n', 'n.type = fci.bundle');
  $fields = $field_list->execute()->fetchAll();

  $fields_array = array();
  foreach ($fields as $field) {
    $unserialized = unserialize($field->data);
    if (isset($unserialized['settings']['handler_settings']['target_bundles'])) {
      foreach ($unserialized['settings']['handler_settings']['target_bundles'] as $bundle) {
        $fields_array[$bundle][] = $field->field_name;
      }
    }
  }

  variable_set('node_back_references', $fields_array);
}

function _MY_CUSTOM_MODULE_get_referencing_nodes($node) {
  $nids = array();
  $fields = variable_get('node_back_references', array());
  if (isset($fields[$node->type])) {
    foreach ($fields[$node->type] as $field) {
      $query = new \EntityFieldQuery();
      $query->entityCondition('entity_type', 'node');
      $query->propertyCondition('status', 1);
      $query->fieldCondition($field, 'target_id', $node->nid);
      $result = $query->execute();
      $nids = isset($result['node']) ? array_merge(array_keys($result['node']), $nids) : $nids;
    }
    $nodes = (!empty($nids)) ? node_load_multiple($nids) : array();

    return $nodes;
  }

  return $nids;
}

where you need to get the parent nodes given the child node :

$nodes = _MY_CUSTOM_MODULE_get_referencing_nodes($node);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy