ชุดเมนูขั้นสูงใน Drupal 7


15

ฉันได้ทำการท่องเว็บแล้วและมันก็ไม่ชัดเจนว่าจะสร้างธีมเมนูที่กำหนดเองได้อย่างไร ฉันค้นหาเป็นเวลาหลายชั่วโมงและไม่พบโพสต์เดียวที่แสดงกระบวนการตั้งแต่ต้นจนจบการสร้างเมนูและปรับแต่งผลลัพธ์ของมัน ดูเหมือนว่านี่เป็นกระบวนการหลายขั้นตอน:

  1. สร้างเมนูผ่านอินเทอร์เฟซ Drupal
  2. สร้างฟังก์ชั่นชุดรูปแบบในtemplate.phpไฟล์ของคุณเพื่อจัดรูปแบบผลลัพธ์
  3. แสดงเมนูนี้เป็นไฟล์เทมเพลต (อย่างใด) โดยเพิ่มเป็นตัวแปร
  4. เรียกใช้themeฟังก์ชันบนเมนูในไฟล์เทมเพลต

1 ก็พอง่ายที่จะทำปัญหาที่ผมวิ่งเข้ามาอยู่กับ 2, 3, และ 4 $main_menuมองไปที่แม่แบบหน้าเริ่มต้นผมเห็นว่ามันเสี่ยงเมนูหลักในตัวแปร หลังจากนั้นหน้าคุณสามารถเห็นฟังก์ชั่นtheme('links__system_main_menu', array('links' => $main_menu...ซึ่งหมายความว่ามันกำลังมองหาฟังก์ชั่นชุดรูปแบบที่มีชื่ออย่างเหมาะสมบางแห่งและใช้มันเพื่อสร้างผลลัพธ์

ฉันรู้ว่าถ้าผมวางfunction theme_links__system_main_menu(&$variables) {...}ในแฟ้มของฉัน template.php Drupal function theme_menu_links(&$variables) {...}จะใช้ฟังก์ชั่นที่ตรงข้ามกับ

สิ่งที่ฉันไม่รู้คือวิธีที่ Drupal เชื่อมโยงเมนูที่กำหนดเองที่ฉันสร้างขึ้นด้วยฟังก์ชันนั้น พูด Let 's My Menuเช่นที่ฉันสร้างเมนูที่เรียกว่า ฉันสามารถสร้างฟังก์ชั่นต่อไปนี้ในtemplate.phpไฟล์ของฉันและจัดรูปแบบผลลัพธ์ของเมนูนั้นได้หรือไม่?function theme_links__system_my_menu(&$variables) {...}

นอกจากนี้วิธีที่ทำให้เมนูกำหนดเองนั้นพร้อมใช้งานสำหรับไฟล์เทมเพลต Drupal เปิดเผย$main_menuตัวแปรให้กับ page.tpl.php อย่างไร

ฉันคิดว่ากุญแจที่ฉันหายไปที่นี่คือวิธีฝังตัวแปรที่แสดงเมนูที่กำหนดเองลงในหน้าเทมเพลต ส่วนใหญ่แม้ว่าฉันจะสูญเสียอย่างสมบูรณ์กับสิ่งที่ต้องทำหลังจากสร้างเมนู

ขอบคุณสำหรับความช่วยเหลือ

แก้ไข:อาจจะโพสต์สิ่งที่ฉันทำ ตามความคิดเห็นของฉันไปยัง BetaRide ด้านล่างฉันต้องฉีด HTML ที่กำหนดเองลงใน<li>องค์ประกอบของรายการเมนู โดยเฉพาะฉันเพิ่มไอคอน Twitter Bootstrap

คำตอบ:


13

การใช้งานเมนูของ Drupal นั้นค่อนข้างพิเศษมันไม่ได้ทำงานอย่างที่ควรจะเป็น

คุณสามารถดูการใช้งานหลักของtemplate_preprocess_page ()เพื่อเพิ่มลิงค์เมนูหลักเป็นตัวแปรให้กับเทมเพลตหน้า คุณต้องเจาะลึกลงไปในเอกสาร API แต่ฟังก์ชันที่คุณต้องการเรียกใช้ในการใช้งาน theme_preprocess_page () คือmenu_navigation_links ()ซึ่งจะส่งกลับอาร์เรย์ของลิงก์ในเมนู

เมื่อดูที่บรรทัด 106 ของไฟล์page.tpl.phpของ Drupal คุณสามารถดูว่าลิงก์เมนูหลักมีธีมอย่างไรในเทมเพลตโดยเรียกใช้ฟังก์ชันtheme ( ) พร้อมกับตะขอของ 'links__system_main_menu'

ในทางทฤษฎีการใช้งานนี้ควรจะสามารถทำซ้ำกับเมนูที่กำหนดเองโดยทำตามอนุสัญญาการตั้งชื่อมาตรฐาน ดังนั้นใน template.php คุณสามารถมี:

function THEMENAME_preprocess_page(&$variables){
  $variables['custom_menu'] = menu_navigation_links('menu-custom-menu');
}

function THEMENAME_links__menu_custom_menu(&$variables){
 //custom theme function here
}

และใน page.tpl.php คุณจะเพิ่มสิ่งนี้:

<?php print theme('links__menu_custom_menu', array('links' => $custom_menu, 'attributes' => array('id' => 'custom-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Custom menu'))); ?>

อย่างไรก็ตามการเพิ่มเมนูกำหนดเองเป็นตัวแปรในเทมเพลตหน้าของคุณไม่จำเป็น คุณสามารถวางบล็อกของเมนูที่กำหนดเองลงในพื้นที่ที่ต้องการได้อย่างง่ายดายผ่านอินเทอร์เฟซผู้ดูแลระบบ Drupal นอกจากนี้คุณสามารถเปลี่ยนการตั้งค่าไซต์สำหรับแหล่งเมนูหลักได้อย่างมีประสิทธิภาพแทนที่ตัวแปร $ main_menu เริ่มต้นใน page.tpl.php ด้วยเมนูที่กำหนดเองของคุณ

แก้ไข:ฉันเพิ่งเห็นการเพิ่มของคุณเกี่ยวกับเป้าหมายสุดท้ายของคุณเพียงแค่เพิ่ม html ที่กำหนดเองลงในรายการเมนูสำหรับไอคอน ขึ้นอยู่กับวิธีเพิ่มไอคอนเหล่านี้มีตัวเลือกโมดูล Drupal ที่แตกต่างกันสองตัว

ไอคอนเมนู - ช่วยให้คุณสามารถอัปโหลดภาพผ่านการตั้งค่าของรายการเมนูและสร้าง CSS (ปรับแต่งได้โดยเทมเพลต) ที่เพิ่มรูปภาพเป็นพื้นหลังของรายการเมนู

คุณสมบัติของเมนู - อนุญาตให้คุณเพิ่มคลาสที่กำหนดเองให้กับแต่ละรายการเมนูผ่านการตั้งค่าใน admin เมื่อมีการเพิ่มคลาสที่ไม่ซ้ำกันในแต่ละรายการเมนูคุณสามารถใช้ CSS เพื่อเพิ่มไอคอนลงในรายการเมนูหรือใช้จาวาสคริปต์เพื่อเพิ่ม HTML เพิ่มเติมลงในรายการเมนู


ดูเหมือนว่าจะตอบคำถามของฉันทั้งหมดอย่างสมบูรณ์ นี่คือคำตอบที่ดี ฉันจะลองทันที
Lester Peabody

1
มันใช้งานได้ แต่ฉันเอาความเห็นเป็นเอกฉันท์ของทุกคนมาไว้ในใจและฉันก็ไม่ได้ใช้วิธีนี้ ฉันใช้โมดูลแอตทริบิวต์ของเมนูที่คุณแนะนำและกำหนด ID เฉพาะให้กับรายการเมนูที่เฉพาะเจาะจงจากนั้นใช้ jQuery เพื่อฉีด HTML โดยตรงที่ฉันต้องการให้เป็น ขอบคุณสำหรับเคล็ดลับ +1
Lester Peabody

"คุณสามารถวางบล็อกของเมนูที่กำหนดเองลงในภูมิภาคที่ต้องการได้อย่างง่ายดายผ่านอินเทอร์เฟซผู้ดูแลระบบ Drupal" ++ ฉันพบว่าวิธีนี้ง่ายกว่ามาก
cdmo

1

คุณอาจต้องการค้นหาโมดูลNice Menus นี่คือคำพูดเกี่ยวกับมัน (จากหน้าโครงการของโมดูล):

... เปิดใช้งานเมนูที่ขยายได้แบบเลื่อนลง / ขวา / ซ้าย มันใช้ CSS เท่านั้นสำหรับเบราว์เซอร์ส่วนใหญ่ที่มี Javascript ขั้นต่ำสำหรับ IE6 (เวอร์ชัน 2 ใช้ปลั๊กอิน Superfish jQuery สำหรับเบราว์เซอร์ทั้งหมดพร้อมตัวเลือกในการปิดใช้งาน JS และกลับไปที่ CSS-only สำหรับเบราว์เซอร์ที่สามารถจัดการได้)

ปัจจุบันสามารถใช้สไตล์ / ประเภทของเมนูได้สามแบบ: แนวนอน, เมนูเลื่อนลง; แนวตั้ง, เมนูบินไปทางซ้าย; เมนูแนวตั้งบินไปทางขวา มีหน้าคู่มือที่ให้เป็นรายการของเว็บไซต์ที่ใช้เมนูนีซ

Nice Menus สร้างบล็อกที่อาจเกี่ยวข้องกับเมนูไซต์ใด ๆ ที่มีอยู่ซึ่งสามารถวางได้ทุกที่ที่บล็อกปกติสามารถวางในธีมได้ สำหรับผู้ใช้สามารถกำหนดธีมเมนูเป็น Nice Menu ได้โดยตรงโดยใช้ฟังก์ชั่นชุดรูปแบบที่จัดไว้ให้ดังนั้นบล็อกจึงไม่จำเป็น มีฟังก์ชั่นชุดรูปแบบเฉพาะสำหรับเมนูลิงค์หลัก ฟังก์ชั่นรูปแบบยังช่วยให้นักพัฒนาที่จะผ่านในต้นไม้เมนูที่กำหนดเองของการทำของพวกเขา (คือไม่ได้ใช้เมนู Drupal.) มีข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้ฟังก์ชั่นรูปแบบในเอกสาร

โมดูลมาพร้อมกับโครงร่างสีทั่วไปที่สามารถแทนที่ได้อย่างสมบูรณ์โดยการเพิ่ม CSS แทนที่ลงในสไตล์ชีทปกติของธีมหรือโดยการสร้างไฟล์ Nice Menus CSS และบอก Nice Menus ให้ใช้สิ่งนั้น การกำหนดค่าธีม ตัวอย่าง CSS แทนที่หลายมีไว้ในไฟล์ readme.txt รวมและในหนังสือคู่มือ


ฉันไม่เห็นว่าทำไมมีคนโหวตคำตอบนี้ลง ด้วย Nice Menus คุณสามารถกำหนดเป้าหมายรายการเมนูแต่ละรายการเนื่องจากมีคลาสเป็นของตัวเอง จากนั้นคุณสามารถใช้กราฟิกเป็นพื้นหลังสำหรับแต่ละชั้นเรียน ฉันเคยทำมาแล้วในสองสามโครงการสำคัญ
Stan Ascher

2
ฉันไม่ได้ลงคะแนน แต่ฉันจะบอกว่านี่ไม่ได้ตอบคำถามที่ฉันถามซึ่งเป็นวิธีขุดลงในแกนหลักของ Drupal สำหรับรายการเมนู นี่คือเหตุผลที่คำถามเหล่านี้ไม่ได้รับคำตอบอย่างเต็มที่เพราะมีบางโมดูลที่บางคนชื่อลดลง ฉันไม่สนใจเกี่ยวกับโมดูลฉันต้องการทำการเขียนโค้ดแม่แบบ
Lester Peabody

1
ฉันไม่ได้ลงคะแนนอย่างใดอย่างหนึ่ง แต่ต้องการเพิ่มในสิ่งที่เลสเตอร์พูด เมื่อคุณแนะนำโมดูลในคำตอบของคุณคุณควรอธิบายว่าทำไมคุณถึงแนะนำโมดูลนั้นและมันจะถูกใช้เพื่อแก้ไขปัญหาของ OP ได้อย่างไร หากไม่มีรายละเอียดเหล่านี้คำตอบของคุณจะถูกมองว่าไม่เป็นประโยชน์และอาจลงคะแนนได้ ฉันทำผิดพลาดกับคำตอบแรก ๆ ของฉันที่นี่เช่นกัน
sheena_d

0

ขึ้นอยู่กับสิ่งที่คุณต้องการกำหนดวิธีการของคุณเป็นเรื่องที่หนักหนาสาหัส ฉันมักจะสร้างเมนูผ่านทางส่วนต่อประสาน Drupal เมื่อคุณ sugested ฉันใช้โมดูลผู้พัฒนาธีมและFirebugเพื่อค้นหาเทมเพลตตะขอและ CSS ที่ต้องเขียนทับเพื่อปรับแต่งตามความต้องการของฉัน

มันคุ้มค่าที่จะพิจารณาสร้างธีมย่อยของธีมพื้นฐานที่คุณใช้ก่อนที่จะเริ่มปรับแต่ง สิ่งนี้ทำให้การอัพเดทธีมพื้นฐานของคุณง่ายขึ้นมาก


ฉันต้องการฉีด HTML ที่กำหนดเองลงในองค์ประกอบ <li> ของรายการเมนู โดยเฉพาะฉันเพิ่มไอคอน Twitter Bootstrap
Lester Peabody

0

นี่คือรหัสอัจฉริยะที่สามารถเข้าถึงรายการเมนูทั้งหมดสำหรับระดับ 2 หรือ 3 หรือมากกว่านั้น

วางรหัสนี้ไว้ในไฟล์ tpl ของคุณอย่าลืมเรียก Boostrap js และ css เวอร์ชันล่าสุด:

<!-- menu -->  

        <?php 

          # get menu with all levels 
          menu_tree_all_data('main-menu');
          $menu = menu_build_tree('main-menu');


          # help function for listing submenus for each link     
          function sub_menu_links($var){
           $submenu ='<ul class="dropdown-menu">';

              foreach ($var as $sub) {

                $path = str_replace("<front>",'' ,$sub["link"]["link_path"]);

                 if(count($sub["below"]) > 0 ){
                      $submenu .= '<li class="dropdown-submenu" ><a href="javascript:void(0);" >'.$sub["link"]["link_title"].'</a>';
                      $submenu .=  sub_menu_links($sub["below"]);
                      $submenu .= '</li>'; 
                  }else{
                      $submenu .= '<li><a href="'.$path.'">'.$sub["link"]["link_title"].'</a>'; 
                      $submenu .= '</li>'; 
                   }

              }
            $submenu .= ' </ul>';

            return $submenu;

          }


          # help function for more than 2 levels
          function menu_links($menu){

             $links = '<ul class="nav navbar-nav">';
             foreach ($menu as $link) {

              if(count($link["below"]) > 0 ){ 

                $path = str_replace("<front>",'' ,$link["link"]["link_path"]);

                $links .=  '<li class="dropdown ">';
                $links .= '<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown">'.$link["link"]["link_title"].'</a>';
                      /* print "<pre>";
                      var_dump( $link["below"]);
                       print "</pre>";*/
                $links .= sub_menu_links($link["below"]); 


                $links .= '</li>' ;

              }else{
                  $links .= '<li>';
                  $links .= '<a href="'.$path.'">'.$link["link"]["link_title"].'</a>'; 
                  $links .= '</li>' ;
              }



              } 
              $links .= '</ul>';
              return  $links ;
          } 


          print menu_links($menu);


           ?>

รหัสนี้จะส่งคืนเมนูสำหรับคลาส css ที่คุณสามารถใช้ i'm ของคุณเองโดยใช้ bootstrap กับ css ที่กำหนดเอง

รหัสนี้หลังจากทำงานหนักมันสามารถประหยัดเวลาของคุณและมันได้รับการทดสอบใน drupal 7.x และใช้งานได้ดีสำหรับเมนูหลักคุณสามารถเปลี่ยนเมนูตามที่คุณต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.