> [VOCABULARY] >> TERM >> [TERM] ... * * - The HOME breadcrumb (if present) links to the home page. The text * displayed for HOME is administrator configurable on the custom_breadcrumbs * settings page. * - The VOCABULARY breadcrumb (if present) will link to an administrator * defined page. If the VOCABULARY does not have an administrator * defined page, it will not appear in the breadcrumb trail. * - Each TERM breadcrumb will link to either * (1) taxonomy/term/tid by default, or * (2) an administrator defined page if one is defined for the term. * * Examples: * home >> term >> term * mysite >> term >> term * home >> vocabulary >> term >> term * vocabulary >> term >> term * * If 'Use taxonomy hierarchy' is not checked, then the titles and paths used to * construct the breadcrumb should be defined at the custom_breadcrumbs administration * page in the same as other custom breadcrumbs. For a node containing multiple terms * and vocabularies, the lightest term with a visible, matching custom breadcrumb is * selected. If a taxonomy_term custom breadcrumb is not found, then taxonomy_vocabulary * custom breadcrumbs are matched against the node's vocabularies. */ module_load_include('inc', 'custom_breadcrumbs', 'custom_breadcrumbs.admin'); module_load_include('inc', 'custom_breadcrumbs', 'custom_breadcrumbs_common'); // Default value for Advanced Settings, Node Types. define('CUSTOM_BREADCRUMBS_TAXONOMY_NODE_TYPES_DEFAULT', 'book'); /** * Implements hook_cb_breadcrumb_info(). * * @return an array with elements * 'table' indicating the db_table to load the breadcrumb from, * 'field' a field of the database table used to identify the breadcrumb, * 'type' a string used for indicating the breadcrumb type on the admin list, * 'name_constructor' a function which generates the breadcrumb name from the breadcrumb. */ function custom_breadcrumbs_taxonomy_cb_breadcrumb_info() { $breadcrumb_type_info = array(); $breadcrumb_type_info['taxonomy_vocabulary'] = array( 'table' => 'custom_breadcrumbs_taxonomy_vocabulary', 'field' => 'vid', 'type' => 'taxonomy_vocabulary', 'name_constructor' => '_custom_breadcrumbs_taxonomy_vocabulary_breadcrumb_name' ); $breadcrumb_type_info['taxonomy_term'] = array( 'table' => 'custom_breadcrumbs_taxonomy_term', 'field' => 'tid', 'type' => 'taxonomy_term', 'name_constructor' => '_custom_breadcrumbs_taxonomy_term_breadcrumb_name' ); return $breadcrumb_type_info; } /** * Constructs a name to display in the admin screen from the taxonomy term. * * @param $breadcrumb * The breadcrumb object. * * @return * A text string that will be used as the breadcrumb name. */ function _custom_breadcrumbs_taxonomy_term_breadcrumb_name($breadcrumb) { $names = array(); $parents = taxonomy_get_parents_all($breadcrumb->tid); while ($parent = array_shift($parents)) { $names[] = $parent->name; } $term = taxonomy_get_term($breadcrumb->tid); $vocabulary = taxonomy_vocabulary_load($term->vid); $names[] = $vocabulary->name; $names = array_reverse($names); $output = implode('>', $names); return $output; } /** * Constructs a name to display in the admin screen from the taxonomy vocabulary. * * @param $breadcrumb * The breadcrumb object. * * @return * A text string that will be used as the breadcrumb name. */ function _custom_breadcrumbs_taxonomy_vocabulary_breadcrumb_name($breadcrumb) { $vocabulary = taxonomy_vocabulary_load($breadcrumb->vid); return $vocabulary->name; } /** * Implements hook_menu(). */ function custom_breadcrumbs_taxonomy_menu() { $items = array(); $items['admin/build/custom_breadcrumbs/taxonomy_term/add'] = array( 'title' => 'Term', 'page callback' => 'drupal_get_form', 'page arguments' => array('custom_breadcrumbs_taxonomy_term_form', 'taxonomy_term'), 'access arguments' => array('administer custom breadcrumbs'), 'file' => 'custom_breadcrumbs_taxonomy.admin.inc', 'type' => MENU_LOCAL_TASK, 'weight' => 5, ); $items['admin/build/custom_breadcrumbs/taxonomy_term/edit'] = array( 'title' => 'Edit custom breadcrumb for taxonomy term', 'page callback' => 'drupal_get_form', 'page arguments' => array('custom_breadcrumbs_taxonomy_term_form', 'taxonomy_term'), 'file' => 'custom_breadcrumbs_taxonomy.admin.inc', 'access arguments' => array('administer custom breadcrumbs'), 'type' => MENU_CALLBACK, ); $items['admin/build/custom_breadcrumbs/taxonomy_vocabulary/add'] = array( 'title' => 'Vocabulary', 'page callback' => 'drupal_get_form', 'page arguments' => array('custom_breadcrumbs_taxonomy_vocabulary_form', 'taxonomy_vocabulary'), 'access arguments' => array('administer custom breadcrumbs'), 'file' => 'custom_breadcrumbs_taxonomy.admin.inc', 'type' => MENU_LOCAL_TASK, 'weight' => 5, ); $items['admin/build/custom_breadcrumbs/taxonomy_vocabulary/edit'] = array( 'title' => 'Edit custom breadcrumb for taxonomy vobaculary', 'page callback' => 'drupal_get_form', 'page arguments' => array('custom_breadcrumbs_taxonomy_vocabulary_form', 'taxonomy_vocabulary'), 'access arguments' => array('administer custom breadcrumbs'), 'file' => 'custom_breadcrumbs_taxonomy.admin.inc', 'type' => MENU_CALLBACK, ); return $items; } /** * Implements hook_nodeapi(). */ function custom_breadcrumbs_taxonomy_nodeapi($node, $op, $teaser, $page) { if ($op == 'alter' && empty($teaser) && !empty($page)) { if (_custom_breadcrumbs_taxonomy_allowed_node_type($node->type)) { module_load_include('inc', 'custom_breadcrumbs_taxonomy'); // Extract the most recently viewed term or the lightest term from lightest vocabulary assosciated with node. $term = custom_breadcrumbs_taxonomy_node_get_term($node); if ($term) { $terms = taxonomy_node_get_terms($node); _custom_breadcrumbs_taxonomy_set_breadcrumb($term->tid, $term->vid, FALSE, array('node' => $node), $terms); } } } } /** * Implements hook_menu_alter(). */ function custom_breadcrumbs_taxonomy_menu_alter(&$callbacks) { // This will not work if views or panels has overriden taxonomy/term/% if (isset($callbacks['taxonomy/term/%']) && ($callbacks['taxonomy/term/%']['page callback'] != 'views_page')) { $term_callback = &$callbacks['taxonomy/term/%']; $callback = $term_callback['page callback']; $arguments = $term_callback['page arguments']; $file = $term_callback['file']; $filepath = isset($term_callback['file path']) ? $term_callback['file path'] : drupal_get_path('module', $term_callback['module']); $term_callback['page callback'] = 'custom_breadcrumbs_taxonomy_term_page'; $term_callback['page arguments'] = array_merge(array(2, $callback, $file, $filepath), $arguments); $term_callback['file'] = 'custom_breadcrumbs_taxonomy.inc'; $term_callback['file path'] = drupal_get_path('module', 'custom_breadcrumbs_taxonomy'); } } /** * Implements hook_views_pre_render(). */ function custom_breadcrumbs_taxonomy_views_pre_render(&$view) { if (variable_get('custom_breadcrumbs_taxonomy_views', FALSE)) { // Set the taxonomy breadcrumb for the view. if (isset($view->display) && !empty($view->display)) { $curpath = drupal_get_normal_path($_GET['q']); // A taxonomy term page is any page with path a component 'taxonomy' followed by 'term'. $arg_values = arg(NULL, $curpath); $is_term_page = FALSE; if (($key = array_search('taxonomy', $arg_values)) !== FALSE) { $is_term_page = (isset($arg_values[$key + 1]) && $arg_values[$key + 1] == 'term'); } foreach ($view->display as $id => $display) { // Identify allowed displays for breadcrumb replacement. if (!_custom_breadcrumbs_allowed_display($display)) continue; $viewpath = _custom_breadcrumbs_construct_view_path($display); // Verify the view path matches the current path. if (_custom_breadcrumbs_match_path($curpath, $viewpath)) { // Select matching display with the greatest number of explicit arguments. $num = substr_count($display->display_options['path'], '%'); if (!isset($max) || (isset($max) && ($num > $max))) { $max = $num; $max_id = $id; } } } if (isset($max_id)) { $display = $view->display[$max_id]; $arguments = _custom_breadcrumbs_views_display_arguments($display); if (isset($arguments) && !empty($arguments)) { $viewargs = (isset($display->handler->view->args) && is_array($display->handler->view->args)) ? $display->handler->view->args : array(); $arg_values = _custom_breadcrumbs_views_parse_args($arguments, $viewargs); foreach ($arg_values['types'] as $key => $type) { $tid = NULL; $vid = NULL; switch ($type) { case 'tid': $tid = $arg_values['values'][$key]; break; case 'vid': $vid = $arg_values['values'][$key]; break; } if (!is_null($tid) || !is_null($vid)) { $terms = array(); if (!is_null($tid)) { $term = taxonomy_get_term($tid); $vid = $term->vid; if ($term) { $terms[$term->tid] = $term; } } module_load_include('inc', 'custom_breadcrumbs_taxonomy'); _custom_breadcrumbs_taxonomy_set_breadcrumb($tid, $vid, $is_term_page, array('view' => $view), $terms); if (!is_null($tid)) { _custom_breadcrumbs_taxonomy_recent_term($tid); } return; } } } // Otherwise, optionally use the first result node that is of an allowed node type to generate the breadcrumb. if (variable_get('custom_breadcrumbs_taxonomy_result_nodes', FALSE) && _custom_breadcrumbs_allowed_display($display) && !empty($view->result)) { foreach ($view->result as $result) { if (isset($result->nid)) { $node = node_load(array('nid' => $result->nid)); if (_custom_breadcrumbs_taxonomy_allowed_node_type($node->type)) { module_load_include('inc', 'custom_breadcrumbs_taxonomy'); $term = custom_breadcrumbs_taxonomy_node_get_term($node); if ($term) { $terms = taxonomy_node_get_terms($node); _custom_breadcrumbs_taxonomy_set_breadcrumb($term->tid, $term->vid, $is_term_page, array('node' => $node), $terms); _custom_breadcrumbs_taxonomy_recent_term($term->tid); return; } } } } } } } } } /** * Implements hook_help(). */ function custom_breadcrumbs_taxonomy_help($path, $arg) { switch ($path) { case 'admin/help#custom_breadcrumbs_taxonomy': $output = '
' . t('The custom_breadcrumbs_taxonomy module generates taxonomy-based breadcrumbs on node pages and taxonomy/term pages. The breadcrumb trail takes on the form:') . '
'; $output .= '' . t('[HOME] >> [VOCABULARY] >> TERM >> [TERM] ...') . '
'; $output .= '' . t('Custom breadcrumbs have been created for this vocabulary. Use the !link to add additional breadcrumbs. Or follow the links in the table below to edit or delete existing custom breadcrumbs.', array('!link' => l('Custom Breadcrumbs Administration Page', 'admin/build/custom_breadcrumbs'))) . '
'; } // Show a table of custom breadcrumbs with links to the edit form. $output .= custom_breadcrumbs_simple_breadcrumb_table($breadcrumbs); $form['custom_breadcrumbs_taxonomy_vocabulary'] = array( '#type' => 'fieldset', '#title' => t('Custom Breadcrumbs for Taxonomy'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#weight' => -50, ); $form['custom_breadcrumbs_taxonomy_vocabulary']['breadcrumb_table'] = array('#value' => $output, ); } /** * Implements hook_form_FORM_ID_alter(). */ function custom_breadcrumbs_taxonomy_form_taxonomy_form_term_alter(&$form, &$form_state) { if (!(isset($_POST['op']) && $_POST['op'] == t('Delete')) || isset($_POST['confirm'])) { // Load all custom breadcrumbs for this tid. $breadcrumbs = custom_breadcrumbs_load_breadcrumbs('custom_breadcrumbs_taxonomy', 'custom_breadcrumbs_taxonomy_term', array('tid' => $form['tid']['#value'])); $output = NULL; if (count($breadcrumbs) > 0) { $output = '' . t('Custom breadcrumbs have been created for this term. Use the Custom Breadcrumbs Administration Page to add additional breadcrumbs. Or follow the links in the table below to edit or delete existing custom breadcrumbs.', array('@link' => url('admin/build/custom_breadcrumbs'))) . '
'; } // Show a table of custom breadcrumbs with links to the edit form. $output .= custom_breadcrumbs_simple_breadcrumb_table($breadcrumbs); $form['custom_breadcrumbs_taxonomy_term'] = array( '#type' => 'fieldset', '#title' => t('Custom Breadcrumbs for Taxonomy'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#weight' => -50, ); $form['custom_breadcrumbs_taxonomy_term']['breadcrumb_table'] = array('#value' => $output, ); } } /** * Implements hook_cb_node_form_table. * * @param $node * The node object being edited * * @return $breadcrumbs * an array of breadcrumb objects for taxonomy terms and vocabs matching the node * to be used in the custom_breadcrumbs fieldset on the node edit page */ function custom_breadcrumbs_taxonomy_cb_node_form_table($node) { $breadcrumbs = array(); if (_custom_breadcrumbs_taxonomy_allowed_node_type($node->type)) { if (!variable_get('custom_breadcrumbs_taxonomy_use_hierarchy', TRUE)) { // Check each term to see if it has a custom breadcrumb. $terms = taxonomy_node_get_terms($node); foreach ($terms as $term) { $more = custom_breadcrumbs_load_breadcrumbs('custom_breadcrumbs_taxonomy', 'custom_breadcrumbs_taxonomy_term', array('tid' => $term->tid)); if (!empty($more)) { $breadcrumbs = array_merge($breadcrumbs, $more); } } // Also look for a match on the taxonomy vocabulary. $vocabularies = taxonomy_get_vocabularies($node->type); foreach ($vocabularies as $vocabulary) { $more = custom_breadcrumbs_load_breadcrumbs('custom_breadcrumbs_taxonomy', 'custom_breadcrumbs_taxonomy_vocabulary', array('vid' => $vocabulary->vid)); if (!empty($more)) { $breadcrumbs = array_merge($breadcrumbs, $more); } } } } return $breadcrumbs; } /** * Determines if the current node is one of the types listed on the advanced settings page. * * @param $nodetype * The node type being considered for a custom breadcrumb. * * @return * TRUE if the node type is selected for a custom breadcrumbs taxonomy breadcrumb, * FALSE otherwise. */ function _custom_breadcrumbs_taxonomy_allowed_node_type($nodetype) { // If the node type IS IN the node types list and the list IS inclusive OR // If the node type IS NOT IN the node types list and the list IS NOT inclusive (e.g. exclusive) // THEN modify the breadcrumb trail. $array_of_types = array_filter((array)variable_get('custom_breadcrumbs_taxonomy_node_types', CUSTOM_BREADCRUMBS_TAXONOMY_NODE_TYPES_DEFAULT)); $in_list = in_array($nodetype, $array_of_types); $allowed = ($in_list == variable_get('custom_breadcrumbs_taxonomy_include_nodes', 0)); return $allowed; } /** * Implements hook_enable(). */ function custom_breadcrumbs_taxonomy_enable() { // Sets weight of custom_breadcrumbs_taxonomy to be greater than taxonomy, views, and custom_breadcrumbs. $max_weight = custom_breadcrumbs_taxonomy_minimum_module_weight(); $current_weight = _custom_breadcrumbs_get_module_weight(array('custom_breadcrumbs_taxonomy')); if ($current_weight < $max_weight) { drupal_set_message(t('Increasing the weight of custom_breadcrumbs_taxonomy for use with other modules.')); db_query("UPDATE {system} SET weight = %d WHERE name = 'custom_breadcrumbs_taxonomy'", $max_weight); variable_set('menu_rebuild_needed', TRUE); } } /** * Implements hook_minimum_module_weight(). * * @see custom_breadcrumbs_admin_settings_submit(). */ function custom_breadcrumbs_taxonomy_minimum_module_weight() { $modules = array('taxonomy', 'views', 'page_manager', 'custom_breadcrumbs', 'i18ntaxonomy'); $weights = _custom_breadcrumbs_get_module_weight($modules); $max_weight = array_pop($weights); return $max_weight + 1; }