สร้างเมนูโดยทางโปรแกรมใน Drupal 7


15

พวกมือใหม่ถามคำถาม

ความคิดใด ๆ ที่ฉันสามารถสร้างเมนูโดยทางโปรแกรม? บอกว่าฉันมี 3 เมนูที่แตกต่างที่ฉันต้องการสร้าง เมนูแรกจะถูกวางไว้ที่ด้านบนซ้ายของส่วนหัว เมนูที่สองจะถูกวางไว้ใต้เมนูแรก เมนูที่สามจะเป็นการนำทางหลัก

เมนูเหล่านี้อยู่ในกลุ่มเดียวกันได้หรือไม่? มันจะเป็นปัญหาในการออกแบบหรือไม่?

ขอบคุณ

คำตอบ:


25

หากคุณพยายามทำสิ่งนี้ในสคริปต์การอัปเดตสิ่งนี้ควรใช้งานได้:

$menus = array(
  array(
    'menu_name' => 'menu_test_one',
    'title' => 'My Menu One',
    'description' => 'Lorem Ipsum',
  ),
  array(
    'menu_name' => 'menu_test_two',
    'title' => 'My Menu Two',
    'description' => 'Lorem Ipsum',
  ),
  array(
    'menu_name' => 'menu_test_three',
    'title' => 'My Menu Three',
    'description' => 'Lorem Ipsum',
  ),
);

$links = array(
  array(
    array(
      'link_title' => 'Link1',
      'link_path' => 'http://yourdomain.com/link1',
      'menu_name' => 'menu_test_one',
      'weight' => 0,
      'expanded' => 0,
    ),
    array(
      'link_title' => 'Link2',
      'link_path' => 'http://yourdomain.com/link2',
      'menu_name' => 'menu_test_one',
      'weight' => 1,
      'expanded' => 0,
    ),
  ),
  array(
    array(
      'link_title' => 'Link3',
      'link_path' => 'http://yourdomain.com/link3',
      'menu_name' => 'menu_test_two',
      'weight' => 0,
      'expanded' => 0,
    ),
    array(
      'link_title' => 'Link4',
      'link_path' => 'http://yourdomain.com/link4',
      'menu_name' => 'menu_test_two',
      'weight' => 1,
      'expanded' => 0,
    ),
  ),
  array(
    array(
      'link_title' => 'Link5',
      'link_path' => 'http://yourdomain.com/link5',
      'menu_name' => 'menu_test_three',
      'weight' => 0,
      'expanded' => 0,
    ),
    array(
      'link_title' => 'Link6',
      'link_path' => 'http://yourdomain.com/link6',
      'menu_name' => 'menu_test_three',
      'weight' => 1,
      'expanded' => 0,
    ),
  ),
);

// Save menu group into menu_custom table
foreach ($menus as $menu) {
  // Look the table first if the data does exist
  $exists = db_query("SELECT title FROM {menu_custom} WHERE menu_name=:menu_name", array(':menu_name' => $menu['menu_name']))->fetchField();
  // Save the record if the data does not exist
  if (!$exists) {
    menu_save($menu);
  }
}

$item = ''; 
foreach ($links as $layer1) {
  foreach ($layer1 as $link) {
    // Build an array of menu link 
    $item = array(
      'link_path' => $link['link_path'],
      'link_title' => $link['link_title'],
      'menu_name' => $link['menu_name'],
      'weight' => $link['weight'],
      'expanded' => $link['expanded'],
    );
    // Look the table first if the data does exist
    $exists = db_query("SELECT mlid from {menu_links} WHERE link_title=:link_title AND link_path=:link_path", array(':link_title' =>  $link['link_title'], ':link_path' => $link['link_path']))->fetchField();
    // Save the record if the data does not exist
    if (!$exists) {  
      menu_link_save($item);
    }
  }
}

ยินดีต้อนรับความคิดเห็นหากวิธีการของฉันไม่ถูกต้อง ขอบคุณ


นี่คือสิ่งที่ฉันต้องการ ให้ฉันลองใช้รหัสของคุณและจะให้ข้อเสนอแนะในภายหลัง ขอบคุณสำหรับการแบ่งปัน
user8012

5
แทนที่จะเรียกใช้การสืบค้น db $ db จะมีหลักฐานเพิ่มเติมในอนาคต (แต่อาจช้ากว่านี้เล็กน้อย) จะใช้ถ้า (! menu_load ($ menu ['menu_name'])) {menu_save ($ menu); }
Bala Clark

เจ๋งสุด ๆ เลย!
Tyler Durden

ข้อเสนอแนะของฉันคือใช้menu_get_menus ()แทนการสืบค้น จากนั้นคุณสามารถบันทึกเมนูลงใน var และเพียงทำif (!array_key_exists($menu, $menus)) {- นอกจากนี้การเพิ่มพารามิเตอร์ FALSE เดียวให้กับ menu_get_menus () จะส่งกลับเมนูที่กำหนดเองเท่านั้น
คริสเตียน

1
นอกจากนี้เมื่อคุณตรวจสอบว่ามีลิงค์เมนูอยู่หรือไม่ // ดูตารางก่อนว่ามีข้อมูลอยู่หรือไม่ $ อยู่ = ... คุณต้องตรวจสอบ menu_name ด้วยการรวมลิงค์เดียวกันอาจอยู่ในเมนูที่แตกต่างกัน
hugronaphor

4

นี่คือวิธีการเติมเมนูจากอาร์เรย์อย่างง่ายดาย:

<?php
function populate_menu($links, $menu_name, $plid = 0) {
  foreach ($links as $link) {
    $ls = array(
      'menu_name' => $menu_name,
      'link_title' => $link['link_title'],
      'link_path' => $link['link_path'],
      'plid' => $plid,
    );
    $newpid = menu_link_save($ls);
    if (!empty($link['childs'])) {
      populate_menu($link['childs'], $menu_name, $newpid);
    }
  }
}


$items = array(
  array(
    'link_title' => 'Menu1',
    'link_path' => '<front>',
    'childs' => array(
      array(
        'link_title' => 'Sub Item 1',
        'link_path' => '<front>',
        'childs' => array(
          array(
            'link_title' => 'Link item 1',
            'link_path' => '<front>',
          ),
          array(
            'link_title' => 'Link item 2',
            'link_path' => '<front>',
          ),
        ),
      ),
      array(
        'link_title' => 'Sub Item 2',
        'link_path' => '<front>',
        'childs' => array(
          array(
            'link_title' => 'Link item',
            'link_path' => '<front>',
          ),
        ),
      ),
    ),
  ),
);
populate_menu($items, 'main-menu');

2

hook_menu()คือทั้งหมดที่คุณต้องนำไปใช้ในโมดูลที่คุณกำหนดเอง สำหรับการสร้างโมดูลที่กำหนดเองอ้างอิงเอกสารนี้

//Define the menus in the function which goes in your MYMODULE.module file  
function MYMODULE_menu() {
  //the menu which will point to http://yoursite/first-menu
  $items['first-menu'] = array(
    'title' => 'First menu',  // will appear as the name of the link
    // Page callback, etc. need to be added here.
  );

  //the menu which will point to http://yoursite/second-menu
  $items['second-menu'] = array(
    'title' => 'Second menu',  // will appear as the name of the link
    // Page callback, etc. need to be added here.
  );

  //the menu which will point to http://yoursite/third-menu
  $items['third-menu'] = array(
    'title' => 'third menu',  // will appear as the name of the link
    // Page callback, etc. need to be added here.
  );

  return $items;
}

คุณสามารถพิมพ์เมนูในภูมิภาคใดก็ได้โดยเพิ่มรหัสต่อไปนี้ลงในpage.tpl.phpไฟล์ของธีมของคุณ

//add this line in <div id="header"></div> to print it in header.
<?php
$menu1 = menu_navigation_links('first-menu');
print theme('links__first_menu', array('links' => $menu1));

//print second menu just below first menu
$menu2 = menu_navigation_links('second-menu');
print theme('links__second_menu', array('links' => $menu1));
?>

คุณไม่จำเป็นต้องพิมพ์third-menuเพราะโดยปกติจะปรากฏที่เมนูนำทาง


หมายเหตุ:นี่ไม่ใช่วิธีปฏิบัติที่ดีที่สุดสำหรับการสร้างเมนูการนำทางและเพิ่มไปยังหน้า hook_menu () ใช้สำหรับสร้างการเรียกกลับหน้าเว็บและไม่ใช่สำหรับการสร้างเมนูการนำทาง โปรดอ่านสิ่งนี้ซึ่งอธิบายความแตกต่าง ฉันตอบคำถามนี้เมื่อฉันเริ่มเรียนรู้ Drupal และฉันไม่แนะนำคำตอบนี้อีกต่อไป


1
นี่ไม่ใช่วิธีปฏิบัติที่ดีที่สุดเลยสำหรับการสร้างเมนูการนำทางและเพิ่มไปยังหน้า hook_menu () ใช้สำหรับสร้างการเรียกกลับหน้าเว็บและไม่ใช่สำหรับการสร้างเมนูการนำทาง โปรดอ่านสิ่งต่อไปนี้ซึ่งอธิบายความแตกต่าง api.drupal.org/api/drupal/includes!menu.inc/group/menu/7
คริสเตียน

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

สวัสดี AjitS ทุกคนดี - ฉันไม่ได้โหวตคำตอบบ่อยๆ ฉันจะเพิ่มการอัปเดตก่อนคำตอบที่บอกว่าคุณไม่แนะนำวิธีการนี้อีกต่อไป ขอบคุณสำหรับการตอบกลับ.
คริสเตียน

ได้ลบ downvote ของฉัน
คริสเตียน

0

คุณสามารถลองใช้โมดูลการนำเข้าเมนู มันยอดเยี่ยมและง่ายสำหรับการปรับใช้เมนู คุณสามารถสร้างเมนูด้วยมือบนเว็บไซต์ของคุณและใช้ JSON ที่สร้างขึ้น นอกจากนี้คุณสามารถสร้างโหนดสำหรับเพจที่ไม่มีอยู่

นี่คือตัวอย่างของสคริปต์การส่งออก:

$menu_name = 'menu-footer-secondary-menu';

// Create menu if doesn't exist.
if (!menu_load($menu_name)) {
  $menu = array(
    'menu_name' => $menu_name,
    'title' => t('Footer secondary menu'),
    'description' => '',
  );
  menu_save($menu);
}

// Import menu links from JSON.
$menu_string = 'Impressum {"url":"node\/1","options":{"attributes":[]}}
Datenschutzbestimmungen {"url":"node\/2","options":{"attributes":[]}}
Nutzungsbedingungen {"url":"node\/3","options":{"attributes":[]}}
';

$options = array(
  //'link_to_content' => TRUE, // Look for existing nodes and link to them.
  'create_content' => TRUE, // Create new content (also if link_to_content not set).
  'remove_menu_items' => TRUE, // Removes current menu items.
  'node_type' => 'page',
  'node_body' => 'Page is in development...',
  'node_author' => 1,
  'node_status' => 1,
);

menu_import_string($menu_string, $menu_name, $options);

คุณสามารถเรียกใช้สคริปต์นี้ด้วยhook_update_N ()หรืออัพเดตตัวประมวลผลสคริปต์


0

สำหรับการสร้างบล็อกเมนูในไฟล์. install ของคุณจะใช้ hook_enable () ประเภท

function mymodule_enable() {
  $t = get_t();
  if (module_exists('menu')) {
    menu_save(array(
      'menu_name' => 'my-new-menu',
      'title' => $t('My New Menu'),
      'description' => $t('My Menu description'),
    ));
  }
 }

ในไฟล์. install เดียวกันการใช้ hook_uninstall ()

function mymodule_uninstall() {
  if (module_exists('menu')) {
   if ($my_menu = menu_load('my-new-menu')) {
    menu_delete($my_menu);
  }
 }
}

ถัดไปในไฟล์. โมดูลของคุณขณะใช้งาน hook_menu ()

function mymodule_menu() {
  return array(
   'mypage' => array(
   'title' => 'My Page',        
   'description' => 'My Page description',    
   'page callback' => 'my_page_callback_func',
   'page arguments' => array(arg(0)),
   'access arguments' => array('access content'),
   'menu_name' => 'my-new-menu',
   'file' => 'my.new.page.inc',
   'file path' => drupal_get_path('module', 'mymodule') . '/includes',
  ),
 );     
}

ไฟล์. inin กำลังรวมโฟลเดอร์ที่อยู่ในโฟลเดอร์ mymodule

ดูที่devel.install ของโมดูลdevelและไฟล์ devel.module สำหรับข้อมูลเพิ่มเติม

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