'admin/settings/category_breadcrumb', 'title' => t('Category Breadcrumb'), 'description' => t('Configure breadcrumb-navigation for category-assigned nodes.'), 'callback' => 'drupal_get_form', 'callback arguments' => array('category_breadcrumb_admin_settings'), 'access' => user_access('administer site configuration'), 'type' => MENU_NORMAL_ITEM, ); return $items; } /** * The admin settings form */ function category_breadcrumb_admin_settings() { $form['category_breadcrumb_amount'] = array( '#type' => 'radios', '#title' => t('For category-assigned nodes'), '#default_value' => variable_get('category_breadcrumb_amount', 1), '#options' => array( '0' => t("Do nothing (use system's breadcrumb)"), '1' => t('Show just one breadcrumb (default)'), '2' => t('Show multiple breadcrumbs'), ), '#description' => t("One breadcrumb is exactly like system breadcrumbs, but if there are more categories assigned to the node, it shows only just one of the possible paths, confusing the user if he came from another. Multiple breadcrumbs shows the paths for all assigned categories, but may be incompatible with some themes.") ); $form['category_breadcrumb_catpages'] = array( '#type' => 'radios', '#title' => t('For category and container pages'), '#default_value' => variable_get('category_breadcrumb_catpages', 1), '#options' => array( '0' => t("Do nothing (use system's menu-based breadcrumb)"), '1' => t('Show breadcrumb (default)'), ), '#description' => t("While enabled, this feature replaces any existing (menu-based) breadcrumbs on category- and container-pages.") ); $form['category_breadcrumb_exclude'] = array( '#type' => 'textfield', '#title' => t('Do not create breadcrumbs for'), '#default_value' => variable_get('category_breadcrumb_exclude', 'forum,blog'), '#size' => 60, '#maxlength' => 200, '#description' => t("Enter comma-separated list of node-types to exclude from breadcrumb processing. 'forum' and 'blog' are recommended to avoid common problems. (More node types may be easily observed in HTML source of your pages as class names near top of the content.)") ); $form['category_breadcrumb_title'] = array( '#type' => 'radios', '#title' => t('Add actual node-title to the breadcrumb'), '#default_value' => variable_get('category_breadcrumb_title', 0), '#options' => array( '0' => t('No title, show just path (default)'), '1' => t('Title as plain text'), '2' => t('Title as link'), ), '#description' => t("Drupal defines the breadcrumb with no title in it, so usually it's up to theme to add the currently viewed page's title (or not), and this option should be disabled. But however, while using the Multiple breadcrumbs option, it might be better to enable the title here - and remove from your theme in turn - to have the title on each of the multiple breadcrumbs. You can add title even if no breadcrumb chosen above (i.e. adding to the system's breadcrumb), but this doesn't work for any pages other than nodes.") ); return system_settings_form($form); } /** * Implementation of hook_nodeapi() - the main part of this module */ function category_breadcrumb_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) { if ($op == 'view' && $page && !drupal_is_front_page()) { $add_title = variable_get('category_breadcrumb_title', 0); // Viewing a node as page, not front: Check for existing breadcrumbs & excluded node-types if (!drupal_set_breadcrumb() && !in_array($node->type, explode(',', variable_get('category_breadcrumb_exclude', 'forum,blog')))) { // Handle category/container pages if ($node->type == 'category_cat' or $node->type == 'category_cont') { if (variable_get('category_breadcrumb_catpages', 1)) { $crumbs[] = _category_breadcrumb_build($node, $add_title); } } // All other node-types: One breadcrumb per category assigned else { $amount = variable_get('category_breadcrumb_amount', 1); if ($node->category && $amount) { foreach ($node->category as $category) { $crumbs[] = _category_breadcrumb_build($node, $add_title, $category); if ($amount < 2) break; // If no multiple breadcrumbs, stop after the first } } } } // Set breadcrumb, if we've created one if ($crumbs) { // Drupal doesn't support multiple breadcrumbs, but as the default theming merely adds separators // between strings, we're able to pass our data through by splitting the wanted final output on // all occurences of the separator, then allow Drupal to re-unite it with any separator wanted. // Multiple breadcrumbs as item-list, otherwise no change $output = (count($crumbs) > 1) ? '' : $crumbs[0]; drupal_set_breadcrumb(explode('»', $output)); } // Even if no breadcrumb created, we may still want to append node-title for theming consistency elseif ($add_title) { $crumbs = drupal_get_breadcrumb(); $crumbs[] = ($add_title < 2) ? check_plain($node->title) : l($node->title, 'node/'.$node->nid); drupal_set_breadcrumb($crumbs); } } } /** * Build one breadcrumb-path * $node = node currently viewed * $add_title = flag from admin settings * $category = start-category for the path IF different from the node */ function _category_breadcrumb_build($node, $add_title, $category = NULL) { // Add node-title if ($add_title) { $crumb[] = ($add_title < 2) ? check_plain($node->title) : l($node->title, 'node/'.$node->nid); } // Add starting-category, if different; else we're starting from node itself if ($category) { $cid = $category->cid; $crumb[] = l($category->title, 'node/'.$cid); } else { $cid = $node->nid; } // Add further parents, until no more left while ($parents = category_get_parents($cid, 'cid', FALSE)) { $cid = $parents[0]->cid; if(!$parents[0]->hidden_cont) { $crumb[] = l($parents[0]->title, 'node/'.$cid); } } // Add 'Home' and join into string $crumb[] = l(t('Home'), variable_get('site_frontpage', 'node')); return implode('»', array_reverse($crumb)); }