> [VOCABULARY] >> TERM >> [TERM] ...
*
* - The HOME breadcrumb (if present) links to the homepage. The text
* displayed for HOME is administrator configurable. If the HOME
* breadcrumb is not defined by the administrator, it will not appear
* in the breadcrumb trail.
* - 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.
* - These administrator defined "breadcrumb links" for VOCABULARIES and TERMS
* are controlled from the add/edit vocabulary and add/edit term
* administrator pages.
*
* Examples:
* home >> term >> term
* mysite >> term >> term
* home >> vocabulary >> term >> term
* vocabulary >> term >> term
*
* Issues:
* - use of db_rewrite_sql?
* - This module is not expected to be compatible with other modules that call
* drupal_set_breadcrumb, such as taxonomy_context.
* - With multi-parent terms, all parent terms seem to show up, look into
* taxonomy_get_parents_all.
*/
// Default value for Advanced Settings, Node Types.
define('TAXONOMY_BREADCRUMB_NODE_TYPES_DEFAULT', 'book');
/**
* Implementation of hook_menu().
*/
function taxonomy_breadcrumb_menu() {
$items['admin/settings/taxonomy-breadcrumb'] = array(
'title' => 'Taxonomy Breadcrumb',
'description' => 'Configure how taxonomy based breadcrumbs are displayed.',
'file' => 'taxonomy_breadcrumb.admin.inc',
'page callback' => 'drupal_get_form',
'page arguments' => array('taxonomy_breadcrumb_admin_settings'),
'access callback' => 'user_access',
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Implementation of hook_nodeapi().
*/
function taxonomy_breadcrumb_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
// If we are on a page view (not just a teaser), set the breadcrumb.
// $a4 contains TRUE if we are on a page view.
if ($op == 'view' && $a4 && !drupal_is_front_page()) {
// Include the .inc file with all helper functions
include_once drupal_get_path('module', 'taxonomy_breadcrumb') .'/taxonomy_breadcrumb.inc';
// See if the node type of the current node is part of the node types listed on the advanced settings page.
$array_of_types = array_filter((array)variable_get('taxonomy_breadcrumb_node_types', TAXONOMY_BREADCRUMB_NODE_TYPES_DEFAULT));
$in_list = in_array($node->type, $array_of_types);
// 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.
if ($in_list == variable_get('taxonomy_breadcrumb_include_nodes', 0) ) {
// Extract lightest term from lightest vocabulary assosciated with node.
$term = _taxonomy_breadcrumb_node_get_lightest_term($node);
$breadcrumb = _taxonomy_breadcrumb_generate_breadcrumb($term->tid);
if (variable_get('taxonomy_breadcrumb_include_node_title', FALSE)) {
$breadcrumb[] = check_plain($node->title);
}
drupal_set_breadcrumb($breadcrumb);
}
}
}
/**
* Implementation of hook_menu_alter().
*/
function taxonomy_breadcrumb_menu_alter(&$items) {
if (isset($items['taxonomy/term/%']['page callback'])) {
$item = &$items['taxonomy/term/%'];
// Store the original configuration, so we can pass it on to our own callback.
$callback = $item['page callback'];
$arguments = $item['page arguments'];
$file = $item['file'];
$filepath = isset($item['file path']) ? $item['file path'] : drupal_get_path('module', $item['module']);
// Alter the original callback.
$item['page callback'] = '_taxonomy_breadcrumb_term_page';
$item['page arguments'] = array_merge(array(2, $callback, $file, $filepath), $arguments);
$item['file'] = 'taxonomy_breadcrumb.inc';
$item['file path'] = drupal_get_path('module', 'taxonomy_breadcrumb');
}
}
/**
* Implementation of hook_help().
*/
function taxonomy_breadcrumb_help($path, $arg) {
switch ($path) {
case 'admin/help#taxonomy_breadcrumb':
return '
'. t('See admin/settings/taxonomy-breadcrumb.', array('@admin' => url('admin/settings/taxonomy-breadcrumb'))) .'
';
case 'admin/settings/taxonomy-breadcrumb':
$output = ''. t('The taxonomy_breadcrumb 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 .= '';
$output .= '- '. t('The text displayed for HOME is configurable below. The HOME breadcrumb (if present) links to the homepage. The text displayed for HOME is configurable by an administrator. If the HOME breadcrumb is not defined by the administrator, it will not appear in the breadcrumb trail.') .'
';
$output .= '- '. t('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. This can be configured on the add/edit vocabulary pages within administer >> categories (taxonomy).', array('@taxonomy' => url('admin/content/taxonomy'))) .'
';
$output .= '- '. t('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. This can be configured on the add/edit term pages within administer >> categories (taxonomy).', array('@taxonomy' => url('admin/content/taxonomy'))) .'
';
$output .= '
';
$output .= ''. t('Examples:') .'
';
$output .= '';
$output .= '- '. t('home >> term >> term') .'
';
$output .= '- '. t('mysite >> term >> term') .'
';
$output .= '- '. t('home >> vocabulary >> term >> term') .'
';
$output .= '- '. t('vocabulary >> term >> term') .'
';
$output .= '
';
return $output;
}
}
/**
* Implementation of hook_form_FORM_ID_alter().
*
* This must be used over hook_taxonomy to
* add the Breadcrumb Path fields to the vocabulary and term forms. The
* hook_taxonomy function does not provide a way to obtain the vid or tid
* of the vocabulary or term.
*/
function taxonomy_breadcrumb_form_taxonomy_form_vocabulary_alter(&$form, &$form_state) {
// Include the .inc file with all helper functions.
include_once drupal_get_path('module', 'taxonomy_breadcrumb') .'/taxonomy_breadcrumb.admin.inc';
include_once drupal_get_path('module', 'taxonomy_breadcrumb') .'/taxonomy_breadcrumb.inc';
$form['taxonomy_breadcrumb_path'] = array(
'#type' => 'textfield',
'#title' => t('Breadcrumb path (taxonomy_breadcrumb)'),
'#default_value' => _taxonomy_breadcrumb_get_vocabulary_path($form['vid']['#value']),
'#maxlength' => 128,
'#description' => t("Specify the path this vocabulary links to as a breadcrumb. If blank, the breadcrumb will not appear. Use a relative path and don't add a trailing slash. For example: node/42 or my/path/alias."),
'#weight' => 0,
);
}
/**
* Implementation of hook_form_FORM_ID_alter().
*
* This must be used over hook_taxonomy to
* add the Breadcrumb Path fields to the vocabulary and term forms. The
* hook_taxonomy function does not provide a way to obtain the vid or tid
* of the vocabulary or term.
*/
function taxonomy_breadcrumb_form_taxonomy_form_term_alter(&$form, &$form_state) {
if (!(isset($_POST['op']) && $_POST['op'] == t('Delete')) || isset($_POST['confirm'])) {
// Include the .inc file with all helper functions.
include_once drupal_get_path('module', 'taxonomy_breadcrumb') .'/taxonomy_breadcrumb.inc';
$form['taxonomy_breadcrumb_path'] = array(
'#type' => 'textfield',
'#title' => t('Breadcrumb path (taxonomy_breadcrumb)'),
'#default_value' => _taxonomy_breadcrumb_get_term_path($form['tid']['#value']),
'#maxlength' => 128,
'#description' => t("Specify the path this term links to as a breadcrumb. If blank, the breadcrumb links to the default taxonomy page. Use a relative path and don't add a trailing slash. For example: node/42 or my/path/alias."),
'#weight' => 0,
);
}
}
/**
* Implementation of hook_taxonomy(). This implementation checks to see if a
* vocabulary or term is being updated and makes the necessary changes in
* the taxonomy_breadcrumb database tables.
*/
function taxonomy_breadcrumb_taxonomy($op, $type, $object = NULL) {
if ($type == 'vocabulary' || $type == 'term') {
// Include the .inc file with all helper functions.
include_once drupal_get_path('module', 'taxonomy_breadcrumb') .'/taxonomy_breadcrumb.inc';
// Set variables to used in SQL query to reflect if vocabulary or term is being updated.
if ($type == 'vocabulary') {
$table = '{taxonomy_breadcrumb_vocabulary}';
$key_type = 'vid';
$old_path = _taxonomy_breadcrumb_get_vocabulary_path($object['vid']);
}
elseif ($type == 'term') {
$table = '{taxonomy_breadcrumb_term}';
$key_type = 'tid';
$old_path = _taxonomy_breadcrumb_get_term_path($object['tid']);
}
$key = isset($object[$key_type]) ? $object[$key_type] : NULL;
switch ($op) {
case 'insert':
case 'update':
// If (after a vocabulary or term is updated)
// called by module_invoke_all('taxonomy', 'update', 'term', $edit) in taxonomy.module.
$new_path = isset($object['taxonomy_breadcrumb_path']) ? $object['taxonomy_breadcrumb_path'] : NULL;
// Only modify database when the object has the 'taxonomy_breadcrumb_path' field
if (!is_null($new_path)) {
// Delete the record from taxonomy_breadcrumb_vocabulary or taxonomy_breadcrumb_term.
if (drupal_strlen($new_path) == 0 && $old_path !== NULL) {
db_query("DELETE FROM $table WHERE $key_type = %d", $key);
}
// Update the existing record in taxonomy_breadcrumb_vocabulary or taxonomy_breadcrumb_term.
elseif (drupal_strlen($new_path) != 0 && $old_path != NULL) {
db_query("UPDATE $table SET path = '%s' WHERE $key_type = %d", $new_path, $key );
}
// Create a new record in taxonomy_breadcrumb_vocabulary or taxonomy_breadcrumb_term.
elseif (drupal_strlen($new_path) != 0 && $old_path == NULL) {
db_query("INSERT INTO $table ($key_type, path) VALUES (%d, '%s')", $key, $new_path);
}
}
break;
case 'delete':
db_query("DELETE FROM $table WHERE $key_type = %d", $key);
break;
}
}
}