Hook menu to unset a link with conditions - drupal

I'm stuck with an issue on Drupal 7.
I have my main menu containing multiple links.
With the module menu_fields, I added a taxonomy to the menu links, and I want to alter this menu display based on the chosen one.
Problem is I do not know how to write my development.
I tested hook_menu(), hook_menu_alter(), hook_menu_alter_link() in my module but the dpm() I wrote in it never appears.
What I hope for is a hook with a param containing an array of the menu items.
Do you have an idea ?
Progress:
I manage to display something with hook_menu_alter() -I had to empty cache- but I can't find the main menu in the $items var.

Problem solved using mymodule_translated_menu_link_alter(&$item, $map).
You just have to do a if ($item['menu_name'] == 'main-menu') {} statement and add your code in it.

The best solution I can think of is to collect menu tree with menu_tree_all_data() function:
https://api.drupal.org/api/drupal/includes%21menu.inc/function/menu_tree_all_data/7.x
and then to crawl tree structure (recursevly) and manually generate menu html.

Related

Remove sub menus from the admin view for a plugin that registers a custom post type

I know there are 357,982 other posts about this BUT they all kinda lack something ie. an actual example that works for those of us who don't write 4,594,334 line of code every day.
SO - As it stands the scenerio is:
A plugin that registers a custom post type
A sub-menu you want to hide
What next?
The best solution I have found is actually pretty easy and requires a bit of inspection of the source and a good understanding of what to look for.
In this example woocommerce is registering the custom post type 'product' with a sub-menu that appears as 'Product Options'. We want to hide this for non-admin users.
Doing an inspection of the menu items we find that the hyperlink for the parent menu is 'edit.php?post_type=event_ticket' - looking a little further we see that the hyperlink for the sub-menu is 'https://websitename.com/wp-admin/edit.php?post_type=product&page=product_attributes'
We will use the 'add_action' hook as shown below. Please note that we are using the url for the parent menu however we are ONLY using the page parameter for the child.
add_action('admin_menu', 'remove_menu_pages', 999);
function remove_menu_pages()
{
if (current_user_can('manage_options') == false)
{
//1st parameter is parent URL | second is the 'page' parameter from the child url
remove_submenu_page('edit.php?post_type=product', 'product_attributes');
}
}
Add this to your functions.php and then login as a non-admin user and the submenu should now be hidden.

Wordpress show sub menu items on index page

I am using wordpress and on the page "sidebar.php" I have the following code:
<?php wp_list_pages('post_type=wiki&depth=1'); ?>
It works great but what I need to do it that what I click on a Menu item on the sidebar I need the sub items to display on the main page.
UPDATE:
What I basically need to do is to have the first level items on the left (As it currently is), and when those links are clicked then the sub items of those items will be listed on the index.php (main page).
I am using the wp-wiki plugin to display the pages as wiki pages but the actual but the list is the same, just showing as a different type:
post_type=wiki
Can anyone help please?
Thanks
<?php
wp_list_pages('sort_column=menu_order&title_li=&child_of='.$post->ID.'&depth=0');
?>
There's several ways you can accomplish this. WordPress actually has an example of exactly what you're looking to do in the Codex. (link - the last example in that section, right above the "List subpages even if on a subpage" heading)
There's several ways to do this though - that's just one example. But that code above, you just pop into your sidebar.php file. You can also create a widget out of it. And as someone else mentioned, you can use the new menu system for WordPress (but you can indeed, make it dynamic.) But the above example in the Codex is the simplest method.
Actually, an easier method would be just to list all subpages and use CSS to hide and show the child items based on what page you're on. The classes are already set up for you. Just view your source code and you can see it. So you'd do something like:
`li ul.children {display:none; }
li.current_page ul.children { display:block; }`
and variations thereof.
What about using the new menu function in wp 3?
That way you could include your type with any sub page you want (won't be dynamic though) and then add your favorite javascript or good css to show those sub-pages.

Add HTML to node title in Drupal module, not in theme layer

I want to add some functionality to my Drupal 6 module: I want to insert an image next to certain node titles (it involves a span and an img tag). I thought I could do this by just implementing mymodule_preprocess_node() and modifying the title. However, Drupal strips out all tags to avoid XSS attacks.
I've seen many solutions that involve the theme layer (most commonly http://drupal.org/node/28537), but I want to do this in my module, not in the theme. I don't want to modify any .tpl.php files or template.php. Can anyone give me tips on how to do this?
You mention that you've tried preprocess_node(), and are correct that, if you are storing the img tag as part of the node title, Drupal will indeed strip that out, as it runs $node->title through check_plain in template_preprocess_node().
My suggestion would be to store the actual image as an image field (using some combination of the imagefield module and imagecache for sizing), set the display of that field to be hidden on the CCK display tab for the given content type, and then attach the image to be part of the $title variable in your module's preprocess function. This solution would also allow you to display that image next to the title in any views you may need to create.
By 'certain node titles' - do you mean all nodes titles from certain node types?
If so, you can likely style the node using only CSS. By default all nodes will have a class that corresponds to the node type. Using CSS background images, you can add an image to the node title.
Your module can call drupal_add_css and add in any required CSS into the page. This way, it is theme independent.
I think the easier way is with javascript / Jquery.
You create a Jquery script which is called only in certain types of nodes and pass the number of views from drupal to the jscript.
You can call drupal_add_js() inside your module_preprocess_node and pass a variable which contains the number of views or the image link to the script. Something like this:
<?php
drupal_add_js("var mymodule_imagelink = " . drupal_to_js($imagelink) . ";", 'inline');
drupal_add_js("my_js_file.js");
?>
then in my_js_file.js just change the text. There are several ways to acomplish this. For instance, you can do a search in the document and change the title to something else or you can use a determined ID, etc...
Find text string using jQuery?
http://api.jquery.com/replaceWith/

Show secondary links in views only

I'm building a site in Drupal and I only want to show the secondary links on the
pages that use the Views I've created. I tried using the $secondary_links variable
in the views-view.tpl.php but the variable is null. How can I achieve this?
The secondary links are as mac correctly writes only available in page.tpl.php, but if I understand you correctly, the best solution is not getting the secondary links into your view.
With your theme, the secondary links, will most likely be printed out where they should, regardless of what is being displayed, be it your views, nodes, the front page etc. Views are displayed and everything else you render, is wrapped in the page template, that controls where menus are located, regions and other fun stuff.
Now, if you don't want to alter this, the location of the menus, their styling and this stuff, you shouldn't be printing the secondary menu in your views template, you shouldn't be doing anything with it at all.
The solution is simple
It's using something that mac mentioned but in a different way: preprocess function. These functions are used to in your template.php file, to add some logic to your variables. You can alter variables or remove them altogether. What I would do, would simply be to remove the primary links, by setting the value of $primary_links to an empty text string.
This would effectively remove the primary links, so only the secondary links are displayed. You could also display the secondary links as the primary, but this might cause confusing to your users. You just need to add some logic to control when this should happen and you are set.
Have you activated the secondary links from the theme settings? That would be:
http://example.com/admin/build/themes/settings/name_of_your_theme
I believe once you have activated the option, the variable will be populated.
EDIT: Thinking a second more, I would also comment that I am not sure if the primary and secondary links are passed to the views templates. I believe those are passed to the page.tpl.php file instead. If I am right, and for some reason you want to add that variable to those passed to the views template, you will have to use a preprocess function, like explained here.
EDIT #2: Indeed if you only need the secondary menu used in a specific views template, another approach would be to simply call menu_secondary_links() from within the template. This is not the most elegant solution ever, as it puts in a theming element something that should belong somewhere else, but it's up to you to make the call whether that menu in the views is a core functionality or a styling element.
HTH!
You can use the following code to show secondary menu on any view
function YourTheme_preprocess_views_view(&$vars)
{
$menu_sec = menu_navigation_links('menu-secondary');
$vars['custom_menu'] = theme('links__menu-secondary', array('links' => $menu_sec));
}
or you can even use other preprocess function depending upon your needs.
Further you can call it on .tpl.php file using:
<?php
$menu_sec = menu_navigation_links('menu-secondary');
print theme('links__menu-secondary',
array(
'links' => $menu_sec,
'attributes'=>array(
'class' => array('nav', 'nav-pills', 'p-f-subfilter'),
)
)
);
?>

Get a node to show up underneath a View's menu item

So I've got a content type of "News" and then a View which shows a list of News nodes as a menu item.
Is there any way to highlight the News View in the menu tree when you're viewing a News node?
I'm sort of aware of why this doesn't work, and why doing this might be hacky, but there's got to be a way to have a "default" menu item or something that a node can show up under.
Actually, I found a module that does basically what the template.php answer above does, by allowing you to assign a default menu item by content type.
It's called Menu Trails. Here is an excerpt from its project page:
... adds some common-sense usability to Drupal's menu system
Menu Trails implements primary/secondary links which keep the current menu trail "active" or highlighted. A handy snippet ready to go into your template.php is included.
The module provides a means of broadly categorizing nodes (by type or taxonomy) as falling "under" a known menu item. These nodes are not added to the menu tree (keeping the menu admin system sane) but they will trigger the functionality above -- preserving navigation state for the user -- when viewed.
New for 6.0: Menu Trails can also set breadcrumbs for nodes, keeping them in sync with the trail.
New for 6.0: Menu Trails is now Organic Groups aware, so nodes can be designated to fall "under" the first group node they belong to.
New for 6.0: A token is exposed to pathauto (and other token-aware modules) allowing for the menu trail to be used in automatic path alias creation.
Assuming the answer to my above comment is "yes," this is something you can accomplish through the template.php file in your theme folder
The final solution will depend on your settings, but generally most of the action will happen inside phptemplate_preprocess_page
// Simplified, and untested in this form
function phptemplate_preprocess_page(&$vars) {
if (isset($vars['node'])) { // if we're looking at a node
$body_classes[] = (($vars['node']->type == 'News') || (arg(0) == 'News')) ? 'news_page' : ''; // Page is news page
}
else if (arg(0) == 'taxonomy') {
// ... Special handling for news taxonomy pages, if you want
} else {
$body_classes[] = "page-type-" . arg(0);
}
$body_classes = array_filter($body_classes); // Out! Out! Damn empty elements!
$vars['body_classes'] = implode(' ', $body_classes);
}
This will give the you the body.news_page style class to work with, and you can combine that with the style of your news menu block to make it appear how you like.
if Menutrails doesn't work (for me it didn't) you can do it yourself by something like:
$somenode = menu_get_item('node/5');
menu_set_item($somenode);
I have found you have more control if you do something like this in hook_nodeapi().
// this code worked for me
$somenode = menu_get_item();
$somenode['href'] = 'node/5';
menu_set_item(NULL, $somenode);
You may need to set the weight of your custom module to be heavier than core modules: at least 1

Resources