Crear un menú mediante programación en Drupal 7

15

Una pregunta de novato chicos.

¿Alguna idea de cómo puedo crear un menú mediante programación? Dice que tengo 3 menús diferentes que quiero crear. El primer menú se colocará en la esquina superior izquierda del encabezado. El segundo menú se colocará debajo del primer menú. El tercer menú será la navegación principal.

¿Podrían estos menús estar bajo el mismo grupo? ¿Sería un problema en el estilo?

Gracias

usuario8012
fuente

Respuestas:

25

Si está intentando hacer esto en un script de actualización, esto debería funcionar:

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

Los comentarios son bienvenidos si mi enfoque es incorrecto. Gracias.

ninjascorner
fuente
Esto es exactamente lo que quiero. Déjame probar tu código y te daré tu opinión más tarde Gracias por compartir
user8012
55
En lugar de ejecutar la consulta db $ exist, un método más a prueba de futuro (pero quizás un poco más lento) sería usar if (! Menu_load ($ menu ['menu_name'])) {menu_save ($ menu); }
Bala Clark
Genial, agradable!
Tyler Durden
Mi sugerencia sería usar menu_get_menus () en lugar de una consulta. Luego puede guardar los menús en una variable y simplemente hacer un if (!array_key_exists($menu, $menus)) {- también agregando el parámetro único FALSO a menu_get_menus () solo devuelve menús personalizados.
Christian
1
También cuando verifica si el enlace del menú existe: // Mire la tabla primero si los datos existen $ exist = ... También debe verificar el nombre del menú ya que la misma combinación de enlaces puede estar en diferentes menús.
hugronaphor
4

Aquí hay una manera de llenar fácilmente un menú desde una matriz:

<?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');
Adolescente
fuente
2

hook_menu()es todo lo que necesita implementar en su módulo personalizado. Para la creación de un módulo personalizado, consulte esta documentación .

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

Puede imprimir el menú en cualquier región agregando el siguiente código al page.tpl.phparchivo de su 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));
?>

No necesita imprimir third-menuporque, de forma predeterminada, aparecerá en el menú de navegación.


NOTA: Esta no es la mejor práctica para crear un menú de navegación y agregarlo a una página. hook_menu () es para crear devoluciones de llamada de página y no para crear menús de navegación. Lea ESTO , que explica las diferencias. Respondí esto cuando comencé a aprender Drupal y ya no recomiendo esta respuesta.

AjitS
fuente
1
Esta no es la mejor práctica para crear un menú de navegación y agregarlo a una página. hook_menu () es para crear devoluciones de llamada de página y no para crear menús de navegación. Lea lo siguiente que explica las diferencias. api.drupal.org/api/drupal/includes!menu.inc/group/menu/7
Christian
1
@Christian Acababa de comenzar a aprender Drupal mientras respondía esto; y la forma en que preferí aprender Drupal fue respondiendo preguntas aquí probando cosas. En el nivel actual de conocimiento que tengo, definitivamente también rechazaría este tipo de respuesta; pero en realidad estoy un poco orgulloso de la forma en que pensé al principio :) Le agradezco la forma en que explicó y el enlace proporcionado.
AjitS
Hola AjitS, todo bien, no voto las respuestas a menudo. Simplemente agregaría una actualización antes de la respuesta que dice que ya no sugiere este enfoque. Gracias por la respuesta.
Christian
He eliminado mi voto negativo.
Christian
0

También puede probar el módulo Importar menú . Es muy bueno y fácil para la implementación del menú. Puede crear un menú manualmente en su sitio web y usar el JSON generado. También puede crear nodos para páginas no existentes.

Aquí hay un ejemplo de script de exportación:

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

Puede ejecutar este script con hook_update_N () o Actualizar el procesador de script

milkovsky
fuente
0

Para crear un bloque de menú, en su archivo .install implementando hook_enable () escriba

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'),
    ));
  }
 }

En el mismo archivo .install, implementando hook_uninstall ().

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

Luego en su archivo .module, mientras implementa 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',
  ),
 );     
}

El archivo .inc incluye carpeta incluida dentro de la carpeta mymodule.

Consulte el archivo devel.install y devel.module del módulo devel para obtener más información.

sarathkm
fuente