'admin/build/custom_breadcrumbs', 'title' => t('Custom breadcrumbs'), 'description' => t('Add custom breadcrumb trails for content types.'), 'callback' => 'custom_breadcrumbs_page', 'access' => $access ); $items[] = array( 'path' => 'admin/build/custom_breadcrumbs/add', 'title' => t('Add custom breadcrumb'), 'type' => MENU_CALLBACK, 'callback' => 'drupal_get_form', 'callback arguments' => array('custom_breadcrumbs_form'), 'access' => $access ); $items[] = array( 'path' => 'admin/build/custom_breadcrumbs/edit', 'title' => t('Edit custom breadcrumb'), 'type' => MENU_CALLBACK, 'callback' => 'drupal_get_form', 'callback arguments' => array('custom_breadcrumbs_form'), 'access' => $access ); } return $items; } function custom_breadcrumbs_perm() { return array('administer custom breadcrumbs', 'use php in custom breadcrumbs'); } function custom_breadcrumbs_nodeapi($node, $op, $teaser, $page) { if ($op == 'view' && !$teaser && $page) { if ($breadcrumb = _custom_breadcrumbs_load_for_type($node)) { $titles = preg_split("/[\n]+/", $breadcrumb->titles); $paths = preg_split("/[\n]+/", $breadcrumb->paths); $titles = module_exists('token') ? token_replace($titles, 'node', $node) : $titles; $paths = module_exists('token') ? token_replace($paths, 'node', $node) : $paths; $trail = array(l(t('Home'), '')); $location = array(); for ($i = 0; $i < count($titles); $i++) { // Skip empty titles if ($title = trim($titles[$i])) { $title = ($title == '') ? ' ' : decode_entities($title); // Output plaintext instead of a link if there is a title without a path. $path = trim($paths[$i]); if (strlen($path) > 0 && $path != '') { $parsed = parse_url($path); $trail[] = l($title, $parsed['path'], array(), $parsed['query']); } else { $trail[] = check_plain($title); } $location[] = array ('title' => $title, 'path' => drupal_get_normal_path($path)); } } drupal_set_breadcrumb($trail); menu_set_location($location); } } } // Lists all current custom breadcrumbs, and provides a link to the edit page. function custom_breadcrumbs_page() { $breadcrumbs = _custom_breadcrumbs_load_all_breadcrumbs(TRUE); $header = array(t('node type'), ''); $rows = array(); foreach ($breadcrumbs as $breadcrumb) { $row = array(); $row[] = $breadcrumb->node_type . (!empty($breadcrumb->visibility_php) ? t(' with PHP snippet') : ''); $row[] = l(t('edit'), 'admin/build/custom_breadcrumbs/edit/' . $breadcrumb->bid); $rows[] = $row; } if (count($rows) == 0) { $rows[] = array(array('data' => t('No custom breadcrumbs have been defined.'), 'colspan' => 2)); } $rows[] = array(array('data' => l(t('Add a new custom breadcrumb'), 'admin/build/custom_breadcrumbs/add'), 'colspan' => 2)); return theme('table', $header, $rows); } // Displays an edit form for a custom breadcrumb record. function custom_breadcrumbs_form() { $bid = arg(4); if (isset($bid)) { $breadcrumb = _custom_breadcrumbs_load_breadcrumb($bid); $form['bid'] = array( '#type' => 'hidden', '#value' => $bid, ); } $options = array(); foreach (node_get_types('names') as $type => $name) { $options[$type] = $name; } $form['node_type'] = array( '#type' => 'select', '#title' => t('Node type'), '#required' => TRUE, '#options' => $options, '#description' => t('The node type this custom breadcrumb trail will apply to.'), '#default_value' => $bid ? $breadcrumb->node_type : NULL, ); $form['visibility_php'] = array( '#type' => 'textarea', '#title' => t('Breadcrumb visibility'), '#access' => user_access('use php in custom breadcrumbs'), '#description' => t('Determine whether this breadcrumb should be displayed by using a snippet of PHP to return TRUE or FALSE. Note that this code has access to the $node variable, and can check its type or any other property.'), '#default_value' => $bid ? $breadcrumb->visibility_php : '', ); $form['titles'] = array( '#type' => 'textarea', '#title' => t('Titles'), '#required' => TRUE, '#description' => t('A list of titles for the breadcrumb links, one on each line.'), '#default_value' => $bid ? $breadcrumb->titles : NULL ); $form['paths'] = array( '#type' => 'textarea', '#title' => t('Paths'), '#required' => TRUE, '#description' => t('A list of Drupal paths for the breadcrumb links, one on each line.'), '#default_value' => $bid ? $breadcrumb->paths : NULL ); $form['help'] = array( '#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => TRUE, '#title' => t('Placeholder tokens'), '#description' => t("The following placeholder tokens can be used in both paths and titles. When used in a path or title, they will be replaced with the appropriate values."), ); if (module_exists('token')) { $form['help']['tokens'] = array( '#value' => theme('token_help', 'node'), ); } else { $form['help']['#description'] = t("To use dynamic placeholder tokens in your breadcrumb trails (the ID or title of the current node, for example), download and install the Token module from Drupal.org.", array('@token' => 'http://www.drupal.org/project/token')); $form['help']['#collapsible'] = FALSE; $form['help']['#collapsed'] = FALSE; } $form['buttons']['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), ); if ($bid) { $form['buttons']['delete'] = array( '#type' => 'submit', '#value' => t('Delete'), ); } return $form; } function custom_breadcrumbs_form_validate($form_id, $form_values) { $path_count = count(explode("\n", $form_values['paths'])); $title_count = count(explode("\n", $form_values['titles'])); if ($title_count != $path_count) { $error_field = ($title_count > $path_count) ? 'paths' : 'titles'; form_set_error($error_field, t('Every link path must have a matching title. There are !paths paths, and !titles titles.', array('!paths' => $path_count, '!titles' => $title_count))); } } function custom_breadcrumbs_form_submit($form_id, $form_values) { if ($form_values['op'] == t('Delete')) { _custom_breadcrumbs_delete_breadcrumb($form_values['bid']); } else { $breadcrumb = (object)$form_values; custom_breadcrumbs_save_breadcrumb($breadcrumb); } return 'admin/build/custom_breadcrumbs'; } function _custom_breadcrumbs_load_breadcrumb($bid) { $sql = 'SELECT * FROM {custom_breadcrumb} WHERE bid = %d'; $result = db_query($sql, $bid); $breadcrumb = db_fetch_object($result); return $breadcrumb; } function _custom_breadcrumbs_load_for_type($node) { $sql = "SELECT * FROM {custom_breadcrumb} WHERE node_type = '%s'"; $result = db_query($sql, $node->type); while ($breadcrumb = db_fetch_object($result)) { if (!empty($breadcrumb->visibility_php)) { // Use PHP code to check the visibility. ob_start(); $visibility = eval(trim($breadcrumb->visibility_php)); ob_end_clean(); if ($visibility == TRUE) { return $breadcrumb; } } else { return $breadcrumb; } } } function _custom_breadcrumbs_load_all_breadcrumbs($refresh = FALSE) { static $breadcrumbs; if ($refresh || !isset($breadcrumbs)) { $sql = 'SELECT * FROM {custom_breadcrumb} ORDER BY node_type'; $result = db_query($sql); $breadcrumbs = array(); while($breadcrumb = db_fetch_object($result)) { $breadcrumbs[] = $breadcrumb; } } return $breadcrumbs; } function custom_breadcrumbs_save_breadcrumb($breadcrumb = NULL) { if (is_array($breadcrumb->paths)) { $breadcrumb->paths = implode("\n", $breadcrumb->paths); } if (is_array($breadcrumb->titles)) { $breadcrumb->titles = implode("\n", $breadcrumb->titles); } if (isset($breadcrumb->bid)) { $sql = "UPDATE {custom_breadcrumb} SET"; $sql .= " titles = '%s', paths = '%s', visibility_php = '%s', node_type = '%s'"; $sql .= " WHERE bid = %d"; db_query($sql, $breadcrumb->titles, $breadcrumb->paths, $breadcrumb->visibility_php, $breadcrumb->node_type, $breadcrumb->bid); } else { $sql = "INSERT INTO {custom_breadcrumb}"; $sql .= " (titles, paths, visibility_php, node_type)"; $sql .= " VALUES ('%s', '%s', '%s', '%s')"; db_query($sql, $breadcrumb->titles, $breadcrumb->paths, $breadcrumb->visibility_php, $breadcrumb->node_type); } } function _custom_breadcrumbs_delete_breadcrumb($bid) { $sql = 'DELETE FROM {custom_breadcrumb} WHERE bid = %d'; db_query($sql, $bid); }