Crea un menu a livello di programmazione in Drupal 7


15

Una domanda da principiante ragazzi.

Qualche idea su come posso creare un menu a livello di codice? Dice che ho 3 diversi menu che voglio creare. Il primo menu verrà posizionato nella parte superiore sinistra dell'intestazione. Il secondo menu verrà posizionato sotto il primo menu. Il terzo menu sarà la navigazione principale.

Questi menu potrebbero essere nello stesso gruppo? Sarebbe un problema nello styling?

Grazie

Risposte:


25

Se stai provando a farlo in uno script di aggiornamento, dovrebbe funzionare:

$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);
    }
  }
}

I commenti sono ben accetti se il mio approccio è sbagliato. Grazie.


Questo è esattamente quello che voglio. Fammi provare il tuo codice e fornirò feedback in seguito. Grazie per aver condiviso
user8012

5
Invece di eseguire la query db $ esiste un metodo più a prova di futuro (ma forse leggermente più lento) sarebbe usare solo se (! Menu_load ($ menu ['menu_name'])) {menu_save ($ menu); }
Bala Clark l'

Bello, bello!
Tyler Durden,

Il mio consiglio sarebbe di usare menu_get_menus () invece di una query. Quindi è possibile salvare i menu in un var e semplicemente fare un if (!array_key_exists($menu, $menus)) {- anche l'aggiunta del singolo parametro FALSE a menu_get_menus () restituisce solo i menu personalizzati.
Christian,

1
Inoltre, quando controlli se esiste il link al menu: // Guarda prima la tabella se i dati esistono $ esiste = ... Devi anche controllare menu_name poiché la stessa combinazione di link può trovarsi in menu diversi.
Hugronaphor,

4

Ecco un modo per popolare facilmente un menu da un array:

<?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()è tutto ciò che devi implementare nel tuo modulo personalizzato. Per la creazione di un modulo personalizzato, consultare questa documentazione .

//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;
}

È possibile stampare il menu in qualsiasi regione aggiungendo il seguente codice al page.tpl.phpfile del tema.

//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));
?>

Non è necessario stampare third-menuperché per impostazione predefinita verrà visualizzato nel menu di navigazione.


NOTA: questa non è la migliore pratica per creare un menu di navigazione e aggiungerlo a una pagina. hook_menu () serve per creare callback di pagine e non per creare menu di navigazione. Si prega di leggere QUESTO , che spiega le differenze. Ho risposto a questa domanda quando avevo iniziato a studiare Drupal e non consiglio più questa risposta.


1
Questa non è affatto la migliore pratica per creare un menu di navigazione e aggiungerlo a una pagina. hook_menu () serve per creare callback di pagine e non per creare menu di navigazione. Si prega di leggere quanto segue che spiega le differenze. api.drupal.org/api/drupal/includes!menu.inc/group/menu/7
Christian

1
@Christian Avevo appena iniziato a studiare Drupal mentre rispondevo a questo; e il modo in cui ho preferito imparare Drupal è stato rispondere alle domande qui provando davvero le cose. All'attuale livello di conoscenza che ho, voterei sicuramente anche questo tipo di risposta; ma in realtà sono abbastanza orgoglioso di come pensavo all'inizio :) Apprezzo il modo in cui hai spiegato e il link fornito.
AjitS

Ciao AjitS, tutto bene - non voto spesso le risposte. Vorrei semplicemente aggiungere un aggiornamento prima della risposta che dice che non suggerisci più questo approccio. Grazie per la risposta.
Christian,

ho rimosso il mio voto negativo.
Christian,

0

Puoi anche provare il modulo di importazione dei menu . È molto bello e facile per la distribuzione dei menu. Puoi creare menu manualmente sul tuo sito Web e utilizzare JSON generato. Inoltre è possibile creare nodi per pagine inesistenti.

Ecco un esempio di script di esportazione:

$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);

È possibile eseguire questo script con hook_update_N () o il processore di script di aggiornamento


0

Per creare un blocco di menu, nel tuo file .install implementando il tipo 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'),
    ));
  }
 }

Nello stesso file .install, implementando hook_uninstall ().

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

Successivamente nel tuo file .module, durante l'implementazione di 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',
  ),
 );     
}

Il file .inc include la cartella inserita nella cartella mymodule.

Vedere il file devel.install e devel.module del modulo devel per ulteriori informazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.