Hi there, we had a particular use case, and I chose this module as a basis to implement that. We have a rather large vocabulary where the root terms behave as a grouping mechanism, and the users would only be able to select the child terms underneath. On display, to cut down on the clutter, we have opted to display only the root term once if any of its child terms were selected. Below you'll find the snippets that I used to put it together, hope that you maybe interested integrating it into the module itself.

/**
 * Display suite field settings.
 */
function ds_term_with_parents_ds_fields_info($entity_type) {
  $fields = array();

  if ($entity_type == 'node') {
    foreach (node_type_get_types() as $type) {
      $bundle = field_extract_bundle($entity_type, $type);
      $instances = field_info_instances('node', $bundle);
      foreach ($instances as $name => $instance) {
        $field = field_info_field($instance['field_name']);
        if (isset($field['type']) && $field['type'] === 'taxonomy_term_reference') {
          if (is_array($fields['node']['ds_term_with_parents_' . $name])) {
            $fields['node']['ds_term_with_parents_' . $name]['ui_limit'][] = $type->type . '|*';
          }
          else {
            $fields['node']['ds_term_with_parents_' . $name] = array(
              'title' => t('Term with parents: ' . $instance['label']),
              'field_type' => DS_FIELD_TYPE_FUNCTION,
              'function' => '_ds_term_with_parents_term_with_parents',
              'ui_limit' => array($type->type . '|*'),
              'entity_render_key' => 'name',
              'properties' => array(
                'bundle' => $bundle,
                'field_name' => $field['field_name'],
                'formatters' => array(
                  'term_with_parents_parent_only' => t('Parent only'),
                  'term_with_parents_parent' => t('Parent first'),
                  'term_with_parents_child' => t('Child first'),
                ),
                'settings' => array(
                  'link' => array('type' => 'select', 'options' => array('no', 'yes')),
                  'separator' => array('type' => 'textfield', 'description' => t('Separator for terms')),
                  'class' => array('type' => 'textfield', 'description' => t('Put a class on the wrapper. Eg: block-title')),
                ),
                'default' => array('link' => 1, 'separator' => ' ', 'class' => ''),
              ),
            );
          }
        }
      }
    }
  }
  
  return $fields;
}
/**
 * Output term and/or parents.
 */
function _ds_term_with_parents_term_with_parents($ds_field) {
  $terms = array();
  $field_items = field_get_items($ds_field['entity_type'], $ds_field['entity'], $ds_field['properties']['field_name']);
  
  // Enable a cache for the parent terms to avoid duplicate output.
  if ($ds_field['formatter'] === 'term_with_parents_parent_only') {
    $cache = array();
  }
  
  foreach ($field_items as $field) {
    $parents = taxonomy_get_parents($field['tid']);
    
    foreach ($parents as $parent) {
      if ($ds_field['formatter'] === 'term_with_parents_parent_only') {
        // Make sure to display the parent only once for a set of children terms.
        if (!isset($cache[$parent->tid])) {
          $cache[$parent->tid] = array();
        }
        
        $info = entity_get_info($ds_field['entity_type']);
        
        if (!isset($cache[$parent->tid][$ds_field['entity_type']])) {
          $cache[$parent->tid][$ds_field['entity_type']] = array();
        }
        
        if (!in_array($ds_field['entity']->{$info['entity keys']['id']}, $cache[$parent->tid][$ds_field['entity_type']])) {
          $cache[$parent->tid][$ds_field['entity_type']][] = $ds_field['entity']->{$info['entity keys']['id']};
          $terms[] = $parent;
        }
      }
      else {
        $terms[] = $parent;
      }
    }
    if ($ds_field['formatter'] !== 'term_with_parents_parent_only') {
      if (!isset($field['taxonomy_term'])) {
        $field['taxonomy_term'] = taxonomy_term_load($field['tid']);
      }
      $terms[] = $field['taxonomy_term'];
    }
  }
  
  // Option child first ==> reverse array
  if ($ds_field['formatter'] === 'term_with_parents_child') {
    $terms = array_reverse($terms);
  }

  if ($terms && is_array($terms)) {
    $output = array();
    foreach ($terms as $term) {
      if ($ds_field['formatter_settings']['link']) {
        $uri = entity_uri('taxonomy_term', $term);
        $uri['options']['absolute'] = TRUE;
        $output[] = l($term->name, url($uri['path'], $uri['options'])) . ' ';
      }
      else {
        $output[] = check_plain($term->name);
      }
    }

    $output = implode($ds_field['formatter_settings']['separator'], $output);
    if (isset($ds_field['formatter_settings']['class'])) {
      $output = '<div class="' . check_plain($ds_field['formatter_settings']['class']) . '">' . $output . '</div>';
    }

    return $output;
  }
  else {
    return '';
  }
}
CommentFileSizeAuthor
#2 display_only_parents-1886306-1.patch5.65 KBhazah

Comments

attiks’s picture

Can you provide a patch so I can merge it?

hazah’s picture

Status: Active » Needs review
StatusFileSize
new5.65 KB
attiks’s picture

Assigned: Unassigned » jelle_s
jelle_s’s picture

Status: Needs review » Fixed

Patch applies and works as described. Committed to latest dev. Thanks for the patch!

hazah’s picture

My pleasure :).

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

hazah’s picture

Status: Closed (fixed) » Needs work

Hey, I've encountered a couple of places where I'm getting notices for non-existent indexes. I haven't had time to do a solid review, but a couple of calls to isset should probably be added.