Add menu block module functionality to custom breadcrumbs module or join forces
| Project: | Custom Breadcrumbs |
| Version: | 6.x-2.x-dev |
| Component: | custom_breadcrumbs |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Jump to:
I asked a question about disappearing menu blocks on some pages, which have a custom breadcrumb here
http://drupal.org/node/334324#comment-2131950
Now I want to duplicate it in this topic with explanation how I solved this problem and with feature request.
So, here is the problem:
===========
I use current dev-6.x version of the Custom breadcrumb module.
My menu structure:
primary_menu
--News
----Culture news
----Sciense news
1) I have a node (type=page) called "news" and it is in the primary_menu as item "News".
2) I have a node type "news" and node "new-number-1" of this type
3) I set path to my page "news" as a breadcrumb for all my nodes of the type news
4) I "Forced the active trail" on the custom breadcrumb settings page
5) I have some items under my "News" item in primary menu, such as "culture news", "sciense news"
6) I have a menu_block with 2-nd level of menu in left sidebar, when I go to page "News" it appears.
7) I have a breadcrumb like "main > News" on my news nodes such as "new-number-1"
8) BUT when I go to my "new-number-1" - there is no menu block in left sidebar, it is lost, though item "News" in primary menu has class "active-trail".
There can be a lot of news and the number of them will be increased, so it is not acceptable to have all them in menu. But I need to imitate that I am in the news subdirectory when I go to any node of this type. And don't want to loose navigation block.
Is it possible to not to loose navigation blocks using current version of the module?
========
After some time of watching into code I've figured out that it is not possible to do with this module itself.
First, I tried to add my custom code to the function function custom_breadcrumbs_set_breadcrumb() of this module like this:
<?php
if (variable_get('custom_breadcrumbs_force_active_trail', FALSE)) {
menu_set_active_trail($location);
$my_add = array_pop($location); //my additions to display menu block
$my_add = $my_add['href']; //my additions to display menu block
menu_set_active_item($my_add); //my additions to display menu block
}
?>And after this my blocks with menu appeared but local tasks were broken.
Now I want to mention that all my menu block I create with the menu_block module. It's very handful when you want to output not whole menu but some part of it.
And I made durty but working decision to hack both - the custom breadcrumb and menu block modules.
Again, in custom breadcrumb in function custom_breadcrumbs_set_breadcrumb() I put my additions, but set my variable global:
<?php
if (variable_get('custom_breadcrumbs_force_active_trail', FALSE)) {
menu_set_active_trail($location);
global $my_add; //my additions to display menu block
$my_add = array_pop($location); //my additions to display menu block
$my_add = $my_add['href']; //my additions to display menu block
//menu_set_active_item($my_add); //my additions to display menu block
}
?>And now in the function _menu_block_block_view($delta) from menu_block module, which is responsible for the output of all blocks of this module I use it:
<?php
function _menu_block_block_view($delta) {
$data = array();
// ====================================
// ------------------My additions ------------------------------
$current_path = $_GET['q'];
global $my_add;
if($my_add) {
menu_set_active_item($my_add);
}
// ----------------- End of my additions ----------------------
// ====================================
// Get the block configuration options.
list($menu_name, $parent_mlid) = split(':', variable_get("menu_block_{$delta}_parent", 'primary-links:0'));
$level = variable_get("menu_block_{$delta}_level", 1);
$follow = variable_get("menu_block_{$delta}_follow", 0);
$depth = variable_get("menu_block_{$delta}_depth", 0);
$expanded = variable_get("menu_block_{$delta}_expanded", 0);
$sort = variable_get("menu_block_{$delta}_sort", 0);
$context = array(
'delta' => $delta,
'menu_name' => $menu_name,
'parent_mlid' => $parent_mlid,
'level' => $level,
'follow' => $follow,
'depth' => $depth,
'expanded' => $expanded,
'sort' => $sort,
);
// Get the default block name
$menu_names = menu_block_get_all_menus();
menu_block_set_title(t($menu_names[$menu_name]), $delta);
if ($expanded || $parent_mlid) {
// Get the full, un-pruned tree.
$tree = menu_tree_all_data($menu_name);
// And add the active trail data back to the full tree.
menu_tree_add_active_path($tree);
}
else {
// Get the tree pruned for just the active trail.
$tree = menu_tree_page_data($menu_name);
}
// Allow other modules to alter the tree before we begin operations on it.
drupal_alter('menu_block_tree', $tree, $context);
// Localize the tree.
if (module_exists('i18nmenu')) {
i18nmenu_localize_tree($tree);
}
// Prune the tree along the active trail to the specified level.
if ($level > 1 || $parent_mlid) {
if ($parent_mlid) {
$parent_item = menu_link_load($parent_mlid);
menu_block_set_title($parent_item);
menu_tree_prune_tree($tree, $level, $parent_item);
}
else {
menu_tree_prune_tree($tree, $level);
}
}
// Prune the tree to the active menu item.
if ($follow) {
menu_tree_prune_active_tree($tree, $follow);
}
// If the menu-item-based tree is not "expanded", trim the tree to the active path.
if ($parent_mlid && !$expanded) {
menu_tree_trim_active_path($tree);
}
// Trim the branches that extend beyond the specified depth.
if ($depth > 0) {
menu_tree_depth_trim($tree, $depth);
}
// Sort the active path to the top of the tree.
if ($sort) {
menu_tree_sort_active_path($tree);
}
// Render the tree.
$data['subject'] = menu_block_get_title();
$data['content'] = menu_block_tree_output($tree);
if ($data['content']) {
$data['content'] = theme('menu_block_wrapper', $data['content'], $context, $delta);
}
// ====================================
// ------------------My additions ------------------------------
if($my_add) {
menu_set_active_item($current_path);
}
// ----------------- End of my additions ----------------------
// ====================================
return $data;
}
?>So inside of the menu blocks The $_GET['q'] is changed and outside it is returned it's natural value.
Now I'd like to do all it without hacking and may be it's possible to have all the fitures in one module?
(Sorry, I know my english is bad)

#1
(Thanks for opening this new issue - you can ignore my request on #334324: Menu active trail query.)
I haven't thought about this much, but on first glance it seems that this request is much too specific to your particular implementation. I am not sure I see a reason why these different modules should combine forces - they provide two distinct non-overlapping features. I am also not sure that I can see how others would benefit from this feature request.
I will look further into the source of the conflict so that I might be able to improve the "force the active trail" option.
Perhaps there is another way to accomplish what you are trying to do without hacking the two modules. I am not sure, but perhaps others will have some suggestions.
#2
Thanks, MGN, for your attention.
I don't think that my problem is specific. If I want to have a correct path from my node to the main page, I also want to have menu blocks, related to that location displayed. But menu blocks are generated by different modules and it's not possible(may be I'm wrong) to correct their output - there is no such hook. But it is possible to add functionality to this module, which will provide menu blocks, tightly connected to breadcrumb settings.
#3
I agree that Custom Breadcrumbs and Menu Block serve very distinct purposes and ought to be kept separate, however it would be nice if they were a little more aware of each other, namely if Custom Breadcrumbs placed a node properly in the menu tree such that Menu Block knew what to display on a node view. Menu Trails accomplishes this nicely. netbear, it might be a good alternative for you.