Posted by hazah on January 11, 2013 at 4:58pm
5 followers
| Project: | Display suite - Term with parents |
| Version: | 7.x-1.x-dev |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Jelle_S |
| Status: | needs work |
Issue Summary
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.
<?php
/**
* 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;
}
?><?php
/**
* 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 '';
}
}
?>
Comments
#1
Can you provide a patch so I can merge it?
#2
#3
#4
Patch applies and works as described. Committed to latest dev. Thanks for the patch!
#5
My pleasure :).
#6
Automatically closed -- issue fixed for 2 weeks with no activity.
#7
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
issetshould probably be added.