1

I'm using the Views module (7.x-3.14) and I have a news view which shows all the articles on a page. I also have its Menu settings set to Normal, thus adding News to my navigation.

This works as expected; however, if there are no articles published, I would like the News link not to be added to my navigation. Essentially I would like a No results behavior for the menu.

Is there a way to accomplish this?

EDIT: I'm using Zurb_Foundation as my base theme which uses a custom function to create the menu that is called in preprocess_page. What I was attempting to do remove News from the menu at this point.

function theme_links__topbar_main_menu(&$variables) {
  // We need to fetch the links ourselves because we need the entire tree.
  $links = menu_tree_output(menu_tree_all_data(variable_get('menu_main_links_source',     'main-menu')));
  foreach ($links as $link){
    if(is_array($link) && array_key_exists('#title', $link)) {
      if($link['#title'] == 'News'){
        $view = views_get_view('news');
        echo count($view->result);
        echo $view->total_rows;
      } 
    }
  }
  $output = _zurb_foundation_links($links);
  $variables['attributes']['class'][] = 'right';

  return '<ul' . drupal_attributes($variables['attributes']) . '>' . $output . '</ul>';
}

count($view->results) returns 0 and $view->total_rows returns NULL even though there should be results.

1

There are multiple options do do this, but all seem to require custom coding.

Maybe Hiding tab when view is empty or How to find out programmatically if a view has a result before rendering the whole view? give an idea of how to do that. They are both mainly about Drupal 6, but the same principles apply.

I would probably use some hook_preprocess or theme function, load the view using views_get_view(), execute that with all the necessary arguments if any, then check the result count and if that's empty, remove the menu link from the page. That last part is described in How to hide menu items without relying on permissions [SOLVED] and Customizing menu link output

Update: So in your example you could do:

$view = views_get_view('news');
$view->execute();
$link['#access'] = count($view->result) > 0;
| improve this answer | |
  • I'm having issues with the result count. I'm working inside the preprocess_page function and have no issue getting the correct view but both count($view->result) and $view->total_rows return 0 and NULL respectively even though there should be results to display. Therefore not allowing me to remove the menu at the correct time. – ahill Jun 22 '16 at 15:24
  • Can you edit your question and add the relevant code so we can see what happens? – berliner Jun 22 '16 at 20:28
  • See edit to original question. – ahill Jun 27 '16 at 21:40
  • @ahill See the update in my answer. You were missing the 'execute' step. – berliner Jun 28 '16 at 19:03
1

While the answer above is helpful I didn't find it isn't complete. Personally, rather than tweaking the output I preferred to modify the access of the particular menu items dynamically.

  • Hook_menu_alter - Provides the available modifications to setup new access permissions
  • Access_callback - Is your personal access callback function
  • hook_module_implements_alter - Use this to override the order of modules processing the menu items, placing yours at the bottom after views
    /**
     * Implements hook_menu_alter()
     */
    function yourmodule_menu_alter(&$items) {
      // Modify view access callback functions
      $items['viewpath']['access callback'] = 'yourmodule_access_callback';
    }


    /**
     * Access callback function
     */
    function yourmodule_access_callback($options = array()) {
      // Grab the default access callback function name, prepare the access
      // arguments, then see what the default access call back result is
      // according to views.
      $access_callback = $options[0];
      $access_arguments = $options[1];
      $access = call_user_func_array($access_callback, $access_arguments);

      // If the default access call back was false, then the user is not allowed
      // access.
      if (!$access) {
        return FALSE;
      }

      // So far the user is allowed access from the views' settings, let's now
      // determine if we want to customize the access to the tab.

      // Determine if the view has any result
      $view = views_get_view(yourview);
      $view->set_display(yourdisplay);
      $view->execute();
      return (count($view->result) > 0);
    }

    /**
     * Implements hook_module_implements_alter().
     */
    function yourmodule_module_implements_alter(&$implementations, $hook) {
      // When the implementations of hook_menu_alter are called, we need our module
      // to be called after views, so let's remove it from the implementations then
      // add it to the end.
      if ($hook == 'menu_alter') {
        if (isset($implementations['yourmodule'])) {
          unset($implementations['yourmodule']);
          $implementations['yourmodule'] = FALSE;
        }
      }
    }
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.