Cách xuất liên kết con dựa trên trang hiện tại


10

Khi hạ cánh trên một trang có mục menu là cha mẹ của các mục menu khác, tôi muốn có thể hiển thị danh sách các mục menu con đó. Tôi đang sử dụng mã sau đây.

$trail = menu_get_active_trail();
menu_build_tree('main-menu', array(
  'expanded' => array($trail[1]['mlid'])
));

Tuy nhiên, mảng trả về trông như thế này (với rất nhiều loại bỏ không cần thiết).

array
'49950 PKY Truck Beauty 312' => 
array
  'link' => &
    array
      'menu_name' => string 'main-menu' (length=9)
      'mlid' => string '312' (length=3)
      'plid' => string '311' (length=3)
  'below' => 
    array
      '49952 Seminars 314' => 
        array
          'link' => &
            array
              'menu_name' => string 'main-menu' (length=9)
              'mlid' => string '314' (length=3)
              'plid' => string '311' (length=3)
      '50000 HDMA Breakfast 316' => 
        array
          'link' => &
            array
              'menu_name' => string 'main-menu' (length=9)
              'mlid' => string '316' (length=3)
              'plid' => string '311' (length=3)
      '50000 MATS Concert 315' => 
        array
          'link' => &
            array
              'menu_name' => string 'main-menu' (length=9)
              'mlid' => string '315' (length=3)
              'plid' => string '311' (length=3)

Lưu ý cách 314, 315 và 316 là 'dưới' 312? Họ là anh em ruột trong cấu trúc thực đơn của tôi và điều đó dường như được xác minh bởi mỗi người có cùng giá trị cho plid(311). Rõ ràng tôi có thể khắc phục điều này bằng cách chuyển mảng qua chức năng khác, nhưng tôi không thể không nghĩ rằng mình chỉ thiếu một cái gì đó.


Vì lợi ích của thời gian, tôi đang khắc phục sự cố với CSS, mặc dù tôi không hài lòng với nó. $tree = menu_build_tree('main-menu', array( 'expanded' => array($trail[1]['mlid']) )); drupal_render(menu_tree_output($tree))Sau đó, sử dụng CSS, tôi có thể tạo kiểu cho các liên kết để loại bỏ phần ulđệm, làm cho chúng xuất hiện tất cả chúng ở cùng một cấp độ. Không lý tưởng, nhưng hiệu quả. EDIT: xin lỗi, tôi không thể tìm ra cách để ngắt dòng hoạt động.
Chris Rockwell

bạn không thể đăng một ảnh chụp màn hình mẫu về những gì bạn muốn đạt được? Thành thật mà nói, tôi thấy câu hỏi hơi lộn xộn (tôi dám nói điều đó vì chưa có câu trả lời nào được viết). Nơi nào bạn muốn có thể hiển thị các mặt hàng trẻ em? Tại sao các mô-đun liên quan đến menu không thỏa mãn? Hãy làm rõ câu hỏi thêm một chút nữa, và có lẽ chúng ta có thể tìm ra một giải pháp tốt.
Sk8erPeter

@ Sk8erPeter, tôi xin lỗi nếu nó lộn xộn. Giải pháp tôi đã sử dụng (được tham khảo trong bình luận của tôi) đang được sử dụng ở đây: link . Câu hỏi chính là: tại sao menu_build_tree () trả về một mảng lồng nhau có các mức không mong muốn (tất cả các liên kết nên giống nhau)? Để xem nơi tôi đang hiển thị các mục con, hãy sử dụng liên kết tôi đưa vào và nhấp vào bất kỳ liên kết nào trong thanh điều hướng chính (css được sử dụng để tạo ảo giác mà chúng không thể nhấp được).
Chris Rockwell

Về các mô-đun, một cái nhìn lướt qua không bật lên bất cứ điều gì sẽ đủ. Điều đó có thể là do tôi không quan tâm đến việc cài đặt một mô-đun khác cho một giải pháp nên được thực hiện trong 4 hoặc 5 dòng mã. Tôi đã có một mô-đun 'bao gồm' tùy chỉnh mà tôi sử dụng cho những thứ như thế này. Bây giờ, từ bất cứ đâu, tôi gọi get_sub_menu_based_on_active_page()và tôi đã sẵn sàng. Tôi đã phải chuyển từ cố gắng tìm ra vấn đề lồng nhau vì css làm cho người dùng không khôn ngoan hơn.
Chris Rockwell

1
Tôi đã đăng một câu trả lời với một cách tiếp cận khác, tôi nghĩ đó là một trong những giải pháp dễ nhất. Và nó hoạt động chính xác. Các mô-đun đề xuất là thực sự phổ biến trong số người dùng Drupal.
Sk8erPeter

Câu trả lời:


8

Chỉ muốn theo dõi. Tôi đã quay lại câu hỏi này và tìm thấy như sau: /programming/2716787/how-to-get-all-the-menu-items-below-a-certain-parent-in-drupal đó là chính xác những gì tôi cần

Mã, được sao chép từ liên kết đã đề cập ở trên và được sửa đổi để phù hợp với nhu cầu của tôi (chủ yếu là sử dụng đường dẫn hiện tại để xây dựng cây menu từ đó, thay vì sử dụng giá trị được mã hóa cứng:

$parent = menu_link_get_preferred($_GET['q']);
$parameters = array(
  'active_trail' => array($parent['plid']),
  'only_active_trail' => FALSE,
  'min_depth' => $parent['depth']+1,
  'max_depth' => $parent['depth']+1,
  'conditions' => array('plid' => $parent['mlid']),
);

$children = menu_build_tree($parent['menu_name'], $parameters);

return '<div class="content-sub-menu content-padder">' . drupal_render(menu_tree_output($children)) . '</div>';

1
Điều này hoạt động tốt, nhưng bạn nên sử dụng current_path()thay vì $_GET['q']. $_GET['q']sẽ trả về bí danh đường dẫn, nơi current_path()sẽ lấy nút / id.
mediaashley

6

Nó có thể dễ dàng được thực hiện bằng cách sử dụng mô-đun khối Menu (mất khoảng 5 phút để cấu hình nó).

Ảnh chụp màn hình khối menu

Tât cả nhưng điêu bạn phải lam la

  1. Kích hoạt mô-đun
  2. Sẽ admin/structure/block
  3. Nhấp vào "Thêm khối menu"
  4. Đặt "Cấp độ bắt đầu" thành "Cấp độ 2 (Trung học)" và đặt khu vực nơi nó sẽ được hiển thị trong "Chỉ định chủ đề và khu vực mà khối này được hiển thị."

  5. Ảnh chụp màn hình:

    • Đây là cách trang cấu hình trông như thế nào

      ảnh chụp màn hình

    • trang quản trị / cấu trúc / khối với các khối mô-đun khối Menu được bật

      ảnh chụp màn hình

    • Tôi đã tạo một số nội dung "Trang cơ bản" với mô-đun Devel và cung cấp một số liên kết menu cho chúng và tạo một hệ thống phân cấp menu lồng nhau

      • Đây là trang trước mặc định không có menu con (Không thể nhìn thấy khối "Menu chính - cấp 2" ở thanh bên trái, vì nó không có bất kỳ mục con cấp hai nào)

      ảnh chụp màn hình

      • Đây là menu thứ hai, với một số thành phần con, bạn đã có thể thấy "Menu chính - cấp 2" ở thanh bên trái, nhưng chỉ có thể nhìn thấy các yếu tố con cấp 2

        ảnh chụp màn hình

        mục cấp hai

      • Bây giờ đi sâu hơn:

        Yếu tố con cấp ba cũng có thể được nhìn thấy

Tôi nghĩ rằng sử dụng mô-đun khối Menu cho nhiệm vụ này là một trong những giải pháp dễ nhất và nhanh nhất.


Tôi sẽ thực sự tò mò tại sao tôi có một downvote cho bài viết này. Các mô-đun được đề xuất thực hiện công việc, và tôi đã viết một hướng dẫn từng bước. Tại sao downvoter không đăng bình luận về lý do? (Có lẽ nó sẽ hữu ích (có thể không), ít nhất là tôi có thể phản ứng.)
Sk8erPeter

0

Như đã lưu ý trong các nhận xét, tôi đã kết thúc bằng cách sử dụng chức năng API và sau đó tạo kiểu bằng CSS:

/* --------------- *\
    Sub-menus
    used on main pages
\* --------------- */
.content-sub-menu ul.menu {
  list-style: none;
  padding: 0;
  margin: 0;
}
.content-sub-menu > ul.menu {
  margin-bottom: 25px;
}
.content-sub-menu ul.menu a {
  font-size: 1.5em;
  padding: 10px;
  margin-top: 5px;
  display: inline-block;
  min-width: 33%;
}

0

Chức năng này hoạt động chính xác để có menu phụ của trang hiện tại:

function build_left_menu()
{
    global $language_url;
    static $use_theme = NULL;
// Get the entire main menu tree
    $left_menu_tree = menu_tree_all_data('main-menu'); // Your main menu
$left_menu_tree_values = array_values($left_menu_tree); //get value only
    $html = "<div id=\"sidemenu\"><ul id=\"side-nav\" class=\"side-nav-content\"><h3>In this section:</h3>";
foreach ($left_menu_tree_values as $index => $item) {
        $link = $item["link"];
        if ($index === 0) {
            $item_class = "first-item panel side-menu ";
        } else {
            $item_class = "panel side-menu ";
        }
        $options_anchor = array();
        if ($item["below"]) {
            $options_anchor = array("attributes" => array('class' => array('dropdown-toggle'),
                'data-toggle' => 'dropdown',
                'data-delay' => 1000,
                'data-close-others' => "false",
                'data-hover' => "dropdown",
            )
            );
        }
        // Merge in defaults.
        $options_anchor += array(
            'attributes' => array(),
            'html' => FALSE,
        );

        //Default needed class
        $options['attributes']['class'][] = 'subpage-link collapsed';
        // Append active class.
        if (($link['link_path'] == $_GET['q'] || ($link['link_path'] == '<front>' && drupal_is_front_page())) &&
            (empty($options_anchor['language']) || $options_anchor['language']->language == $language_url->language)) {
            if ($item["below"]) {
                foreach ($item["below"] as $item_below) {
                    $link_below = $item_below["link"];
                    $options_anchor = array();
                    $html .= "<li class='" . $item_class . "'>";
                    $html .= override_left_l($link_below['link_title'], $link_below['link_path'], $options_anchor).'</li>';
                }
            }
        }
    }
    $html .= "</ul></div>";
    return $html;
}

Hy vọng điều này giúp đỡ!


Hàm của bạn gọi một hàm không xác định (override_left_l)!
DrCord

0

@Chris Rockwell và @ Mario Awad

Tôi là người mới ở Drupal nên thật khó hiểu cho tôi khi thêm chức năng này .. Tôi xin lỗi vì điều đó. Nhưng, các bạn có thể vui lòng đề cập rằng trong tập tin nào, chúng ta có nên thêm chức năng này không?

Tôi đang cố gắng tạo điều hướng thanh bên sẽ chỉ hiển thị các phần tử con trên mỗi trang. Làm cách nào để tạo menu điều hướng trên thanh bên với các liên kết điều hướng khác nhau được hiển thị trên các trang khác nhau?

Tôi đánh giá cao!

Cảm ơn!


0

Tôi vừa đăng xong một chức năng nhận các mục menu con được cung cấp đường dẫn của một nút. Bạn có thể kiểm tra nó ở đây: http://softkube.com/blog/getting-child-menu-items-drupal-menu-tree

Tôi bao gồm liên kết đến bằng chứng trong tương lai câu trả lời trong trường hợp bài đăng được cập nhật và tôi cũng sẽ sao chép / dán mã đầy đủ vào cuối.

Trong trường hợp của bạn, bạn chỉ cần chạy một cái gì đó như thế này trong chủ đề của mình để liệt kê tất cả các mục menu con. Sửa đổi các echotuyên bố và chủ đề theo ý thích của bạn.

$path = current_path();
$nids = skl_get_all_menu_node_children_ids($path);
$children = node_load_multiple($nids);
foreach($children as $c) {
    echo $c->title . ': ' . url('node/' $c->nid) . '<br />';
}

Và đây là mã đầy đủ của chức năng. Kiểm tra các liên kết để cập nhật trong tương lai có thể.

Chúc may mắn.

/**
 * Returns node ids of all the child items, including children of children
 * on all depth levels, of the given node path. Returns an empty array
 * if any error occurs.
 * 
 * @param string $node_path
 * @return array
 */
function skl_get_all_menu_node_children_ids($node_path) {
    //Stop and return an empty array if node path is empty
    if(empty($node_path)) {
        return array();
    }

    //Init empty array to hold the results
    $nids = array();

    //Init parent keys. Check 'foreach' loop on parent keys for more info.
    $parent_keys = array('plid', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9');

    //Collect menu item corresponding to this path to begin updates.
    //Reference: http://stackoverflow.com/a/11615338/136696
    //Note: we couldn't find a way to get the sub-tree starting from this item
    //only and hence we had to get the whole menu tree built and then loop on
    //the current item part only. Not so bad considering that Drupal will
    //most probably have the whole menu cached anyway.
    $parent_menu_item = menu_link_get_preferred($node_path);

    //Stop and return empty array if a proper current menu item couldn't be found
    if(empty($parent_menu_item['menu_name']) || empty($parent_menu_item['mlid'])) {
        return array();
    }

    //Init parent item mlid for easier usage since now we know it's not empty
    $parent_menu_item_mlid = $parent_menu_item['mlid'];

    //Build whole menu based on the preferred menu_name gotten from this item
    $menu = menu_build_tree($parent_menu_item['menu_name']);

    //Reset menu cache since 'menu_build_tree' will cause trouble later on after 
    //you call pathauto to update paths as it can only be called once. 
    //Check: https://www.drupal.org/node/1697570
    menu_reset_static_cache();

    //Init processing array. This will hold menu items as we process them.
    $menu_items_to_process = array();

    //First run to fill up the processing array with the top level items
    foreach($menu as $top_level_menu_item) {
        $menu_items_to_process[] = $top_level_menu_item;
    }

    //While the processing array is not empty, keep looping into lower
    //menu items levels until all are processed.
    while(count($menu_items_to_process) > 0) {
        //Pop the top item from the processing array
        $mi = array_pop($menu_items_to_process);

        //Get its node id and add it to $nids if it's a current item child
        //Note that $parent_keys contains all keys that drupal uses to
        //set a menu item inside a tree up to 9 levels.
        foreach($parent_keys as $parent_key) {
            //First, ensure the current parent key is set and also mlid is set
            if(!empty($mi['link']['mlid']) && !empty($mi['link'][$parent_key])) {
                //If the link we're at is the parent one, don't add it to $nids
                //We need this check cause Drupal sets p1 to p9 in a way you
                //can easily use to generate breadcrumbs which means we will
                //also match the current parent, but here we only want children
                if($mi['link']['mlid'] != $parent_menu_item_mlid) {
                    //Try to match the link to the parent menu item
                    if($mi['link'][$parent_key] == $parent_menu_item_mlid) {
                        //It's a child, add it to $nids and stop foreach loop.
                        //Link_path has the path to the node. Example: node/63.
                        if(!empty($mi['link']['link_path'])) {
                            $nids[] = str_replace('node/', '', 
                                      $mi['link']['link_path']);
                            break;
                        }
                    }
                }
            }
        }

        //Add its child items, if any, to the processing array
        if(!empty($mi['below']) && is_array($mi['below'])) {
            foreach($mi['below'] as $child_menu_item) {
                //Add child item at the beginning of the array so that when
                //we get the list of node ids it's sorted by level with
                //the top level elements first; which is easy to attain
                //and also useful for some applications; why not do it.
                array_unshift($menu_items_to_process, $child_menu_item);
            }
        }
    }

    //Return
    return $nids;
}

Cảm ơn Mario. Bạn có thể nhận xét về lý do tại sao bạn chọn điều này hơn sử dụng $parameterstrong menu_build_tree?
Chris Rockwell

Cảm ơn vì bạn đã phản hồi. Tôi không thể có được thông tin cần thiết cho dù $parameterstôi đã sử dụng những gì , và tin tôi rằng tôi đã nhìn rất nhiều. Tất cả những gì tôi muốn là, được đưa ra một con đường, có được tất cả các mục menu con ở tất cả các cấp độ và tôi chỉ đơn giản là không thể tìm thấy một cách. Nếu có một xin vui lòng thông báo cho tôi, tôi sẽ vui mừng tìm hiểu và cập nhật câu trả lời và bài đăng trên blog của tôi. Chúc mừng.
Mario Awad
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.