hierarchical_term_formatter.module in Hierarchical Term Formatter 7
Same filename and directory in other branches
Provides hierarchical term formatters for taxonomy reference fields.
File
hierarchical_term_formatter.moduleView source
<?php
/**
* @file
* Provides hierarchical term formatters for taxonomy reference fields.
*/
/**
* Implements hook_field_formatter_info().
*/
function hierarchical_term_formatter_field_formatter_info() {
return array(
'hierarchical_term_formatter' => array(
'label' => t('Hierarchical terms'),
'field types' => array(
'taxonomy_term_reference',
),
'settings' => array(
'display' => 'all',
'link' => '',
'reverse' => '',
'wrap' => 'none',
'separator' => ' » ',
),
),
);
}
/**
* Implements hook_field_formatter_settings_form().
*/
function hierarchical_term_formatter_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
$element['display'] = array(
'#title' => t('Terms to display'),
'#description' => t('Choose what terms to display.'),
'#type' => 'select',
'#options' => _hierarchical_term_formatter_display_options(),
'#default_value' => $settings['display'],
'#required' => FALSE,
);
$element['link'] = array(
'#title' => t('Link each term'),
'#description' => t('If checked, the terms will link to their corresponding term pages.'),
'#type' => 'checkbox',
'#default_value' => $settings['link'],
);
$element['reverse'] = array(
'#title' => t('Reverse order'),
'#description' => t('If checked, children display first, parents last.'),
'#type' => 'checkbox',
'#default_value' => $settings['reverse'],
);
$element['wrap'] = array(
'#title' => t('Wrap each term'),
'#description' => t('Choose what type of html elements you would like to wrap the terms in, if any.'),
'#type' => 'select',
'#options' => _hierarchical_term_formatter_wrap_options(),
'#default_value' => $settings['wrap'],
'#required' => FALSE,
);
$element['separator'] = array(
'#title' => t('Separator'),
'#description' => t('Enter some text or markup that will separate each term in the hierarchy. Leave blank for no separator. Example: <em>»</em>'),
'#type' => 'textfield',
'#size' => 20,
'#default_value' => $settings['separator'],
'#required' => FALSE,
);
return $element;
}
/**
* Implements hook_field_formatter_settings_summary().
*/
function hierarchical_term_formatter_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$display_options = _hierarchical_term_formatter_display_options();
$wrap_options = _hierarchical_term_formatter_wrap_options();
$format = $settings['link'] ? t('Links') : t('Plain text');
$order = $settings['reverse'] ? t('Reverse') : t('Natural');
$summary[] = t('Display: %display as %format', array(
'%display' => $display_options[$settings['display']],
'%format' => $format,
));
if ($settings['wrap'] != 'none') {
$summary[] = t('Wrapper: @wrap', array(
'@wrap' => $wrap_options[$settings['wrap']],
));
}
$summary[] = t('Order: %order', array(
'%order' => $order,
));
if ($settings['separator']) {
$summary[] = t('Separator: "%separator"', array(
'%separator' => filter_xss_admin($settings['separator']),
));
}
return implode('<br />', $summary);
}
/**
* Implements hook_field_formatter_prepare_view().
*/
function hierarchical_term_formatter_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
// Pass on responsibility for loading terms to Taxonomy.module.
taxonomy_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, $items, $displays);
}
/**
* Implements hook_field_formatter_view().
*/
function hierarchical_term_formatter_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = $used = array();
$settings = $display['settings'];
foreach ($items as $delta => $item) {
// Terms whose tid is 'autocreate' do not exist
// yet and $item['taxonomy_term'] is not set. Theme such terms as
// just their name.
if ($item['tid'] == 'autocreate') {
$terms = array(
'tid' => 'none',
'content' => check_plain($item['name']),
);
}
else {
// Build an array representing the term hierarchy.
switch ($settings['display']) {
case 'leaf':
$term_tree = array(
$item['taxonomy_term'],
);
break;
case 'root':
$parents = taxonomy_get_parents_all($item['taxonomy_term']->tid);
$term_tree = array(
array_pop($parents),
);
// Root is the last array item.
// Keep track of which root terms have been added to avoid duplicates.
if (isset($used[$term_tree[0]->tid])) {
$term_tree = array();
break;
}
$used[$term_tree[0]->tid] = TRUE;
break;
case 'parents':
$term_tree = array_reverse(taxonomy_get_parents_all($item['taxonomy_term']->tid));
array_pop($term_tree);
// Get rid of the leaf (last array item).
break;
case 'nonroot':
$term_tree = array();
$parents = taxonomy_get_parents_all($item['taxonomy_term']->tid);
// If there are 2 or more terms in the parents array keep [0] because
// it's not a root term.
if (count($parents) > 1) {
$term_tree = array_reverse($parents);
// This gets rid of the first topmost term.
array_shift($term_tree);
// Terms can have multiple parents. Now remove any remaining topmost
// terms.
foreach ($term_tree as $key => $term) {
$has_parents = taxonomy_get_parents($term->tid);
// This has no parents and is topmost.
if (empty($has_parents)) {
unset($term_tree[$key]);
}
}
}
break;
default:
// 'all'
$term_tree = array_reverse(taxonomy_get_parents_all($item['taxonomy_term']->tid));
break;
}
// Change output order if Reverse order is checked and $term_tree array contains more then 1 element
if ($settings['reverse'] && count($term_tree) > 1) {
$term_tree = array_reverse($term_tree);
}
// Remove empty elements caused by discarded items.
$term_tree = array_filter($term_tree);
$terms = array();
foreach ($term_tree as $term) {
if ($settings['link']) {
$uri = entity_uri('taxonomy_term', $term);
$link = array(
'#type' => 'link',
'#title' => $term->name,
'#href' => $uri['path'],
'#options' => $uri['options'],
);
$terms[] = array(
'tid' => $term->tid,
'content' => drupal_render($link),
);
}
else {
$terms[] = array(
'tid' => $term->tid,
'content' => check_plain($term->name),
);
}
}
}
// Make sure there are terms before adding to $element.
if (count($terms)) {
// Prepare theme variables.
$variables = array(
'terms' => $terms,
'separator' => $settings['separator'],
);
if ($settings['wrap'] == 'none') {
$variables['wrapper'] = $variables['item_wrapper'] = '';
}
else {
if (in_array($settings['wrap'], array(
'ol',
'ul',
))) {
$variables['wrapper'] = $settings['wrap'];
$variables['item_wrapper'] = 'li';
}
else {
$variables['wrapper'] = '';
$variables['item_wrapper'] = $settings['wrap'];
}
}
$element[$delta] = array(
'#markup' => theme('hierarchical_term_formatter', $variables),
);
}
}
return $element;
}
/**
* Implements hook_theme().
*/
function hierarchical_term_formatter_theme($existing, $type, $theme, $path) {
return array(
'hierarchical_term_formatter' => array(
'variables' => array(
'terms' => array(),
'wrapper' => '',
'item_wrapper' => '',
'separator' => '',
),
),
);
}
/**
* Theme the term hierarchy.
*/
function theme_hierarchical_term_formatter($variables) {
$items = array();
$separator = filter_xss_admin($variables['separator']);
$count = 0;
foreach ($variables['terms'] as $item) {
$count++;
if ($variables['item_wrapper']) {
$items[] = sprintf('<%s class="taxonomy-term count-%s tid-%s">%s</%s>', $variables['item_wrapper'], $count, $item['tid'], $item['content'], $variables['item_wrapper']);
}
else {
$items[] = $item['content'];
}
}
if ($variables['wrapper']) {
return sprintf('<%s class="terms-hierarchy">%s</%s>', $variables['wrapper'], join($separator, $items), $variables['wrapper']);
}
else {
return join($separator, $items);
}
}
function _hierarchical_term_formatter_wrap_options() {
return array(
'none' => t('None'),
'span' => t('<span> elements'),
'div' => t('<div> elements'),
'ul' => t('<li> elements surrounded by a <ul>'),
'ol' => t('<li> elements surrounded by a <ol>'),
);
}
function _hierarchical_term_formatter_display_options() {
return array(
'all' => t('The selected term and all of its parents'),
'parents' => t('Just the parent terms'),
'root' => t('Just the topmost/root term'),
'nonroot' => t('Any non-topmost/root terms'),
'leaf' => t('Just the selected term'),
);
}