web-dev-qa-db-ja.com

URIを使用してメニュー項目を強調表示する

  • サイトに「記事」というコンテンツタイプがあります。
  • このコンテンツタイプのノードを一覧表示するビューを作成しました。パスは "/ articles"です
  • そのビューでは、メインメニューの「記事」にメニュー項目を作成しました。
  • このコンテンツタイプのすべてのノードにpathautoモジュールを使用して、パスを_articles/[node:title]_にしました

私の質問はユーザーが単一の記事ノードを表示している場合、またはユーザーがビューを表示している場合、メニュー項目を強調表示したままにしたいです。

私のテーマ(以下のコード)のtemplate.phpファイルでtheme_menu_link()関数を使用して問題を解決しました。 Drupal APIの初心者ですが、これを行うためのより良い方法はありますか?

私がしたこと:

_function mytheme_menu_link(array $variables) {

  //Some variables, we're using
  $element = $variables['element'];
  $sub_menu = '';

  //#href is an element inside the item
  $the_path = drupal_lookup_path('alias', $element['#href']) ?: $element['#href'];

  //Compare the path to the actual URI (using sub-function), and if they match, then add a new CSS class
  //either: 'uri-active' or 'uri-active-trail'
  switch(mytheme__menu_detect_uri($the_path)) {
    case 1:  $element['#attributes']['class'][] = 'path-active'; break;
    case -1: $element['#attributes']['class'][] = 'path-active-trail'; break;
  }

  //If there are sub-menu items under this, render those too
  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  }

  //Return the output
  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}

/**
 * Detect if a given path matches the current URI, as detected
 * from reading the current_path() alias from Drupal
 *
 * @param string $path_to_check  The path to check
 * @param string $check_against  The path to check against (leave blank for current path)
 * @reutrn int   1 = Matches, 0 = No Match, -1 = In Active Path
 */
function mytheme__menu_detect_uri($menu_item_path, $actual_path = NULL)
{
  if (is_null($actual_path))
    $actual_path = drupal_lookup_path('alias', current_path()) ?: current_path();

  //Compare em
  if (strcasecmp($menu_item_path, $actual_path) == 0)
   return 1;
  elseif (strlen($actual_path) > strlen($menu_item_path) && strcasecmp(substr($actual_path, 0, strlen($menu_item_path)), $menu_item_path) == 0)
    return -1;
  else
    return 0;
}
_
4
caseyamcl

context モジュールを使用すると、特定の条件(パスなど)が満たされた場合にメニュー項目を強調表示できます。

2
uwe
/**
 * Implements hook_node_view().
 */
function MY_MODULE_node_view($node, $view_mode) {

  // Just make a blog menu item active during viewing blog post detailed page.
  if ($view_mode == 'full' && !empty($node->type) && $node->type == 'blog_post') {
    menu_tree_set_path('main-menu', 'blog');
  }
}
2
skorzh

これがWebサイトでのユーザーエクスペリエンスの唯一の目的である場合、私の知る限り、CSSを介してこれを実行する可能性があります。 メニュー属性 モジュールを使用して、その特定のリスト項目にクラスを追加できます。次に、すべてのビューページにbody要素のクラスが必要です。単一の記事のスタイル形式の属性と同じように、ビューに適切なクラスをスタイルできます。 CSSを介して1行または2行に囲まれた一連のPHPコードを記述する必要はありません。

1
user16460

コンテキストは機能しますが、メニュー項目を強調表示するだけの場合は少々やりすぎです。 パスごとのメニュートレイル モジュールは、パスエイリアスに従ってこれを自動的に行います。さらにいくつかの機能と設定を提供する Menu Position モジュールもあります。

1
pfrenssen

特定のコンテンツタイプでメニューをアクティブにするには、 menu_set_active_item($ path) 関数を使用します。

/**
 * Implements hook_node_view().
 */
function hook_node_view($node, $view_mode) {

  if ($view_mode == 'full' && !empty($node->type) && $node->type == 'article') {
    menu_set_active_item('[MENU_PATH]');
  }
}
0
Shrikant D