Crie um menu programaticamente no Drupal 7

15

Uma pergunta de novato, pessoal.

Alguma idéia de como posso criar um menu programaticamente? Diz que tenho 3 menus diferentes que quero criar. O primeiro menu será colocado no canto superior esquerdo do cabeçalho. O segundo menu será colocado abaixo do primeiro menu. O terceiro menu será a navegação principal.

Esses menus podem estar no mesmo grupo? Seria um problema no estilo?

obrigado

user8012
fonte

Respostas:

25

Se você está tentando fazer isso em um script de atualização, isso deve 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);
    }
  }
}

Comentários são bem-vindos se minha abordagem estiver errada. Obrigado.

ninjascorner
fonte
É exatamente isso que eu quero. Deixe-me tentar seu código e enviaremos comentários mais tarde. Obrigado por compartilhar
user8012
5
Em vez de executar a consulta db $ existe, um método mais à prova de futuro (mas talvez um pouco mais lento) seria usar apenas se (! Menu_load ($ menu ['menu_name'])) {menu_save ($ menu); }
Bala Clark
Legal, legal!
precisa
Minha sugestão seria usar menu_get_menus () em vez de uma consulta. Depois, você pode salvar os menus em um var e simplesmente executar umif (!array_key_exists($menu, $menus)) { - também adicionar o único parâmetro FALSE a menu_get_menus () retorna apenas menus personalizados.
Christian
11
Além disso, quando você verifica se o link do menu existe: // Consulte a tabela primeiro se os dados existirem $ existe = ... Você também deve verificar o menu_name, pois a mesma combinação de links pode estar em menus diferentes.
hugronaphor
4

Aqui está uma maneira de preencher facilmente um menu a partir de uma 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');
Adolescência
fonte
2

hook_menu()é tudo o que você precisa implementar no seu módulo personalizado. Para criação do módulo personalizado, consulte esta documentação .

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

Você pode imprimir o menu em qualquer região adicionando o seguinte código ao page.tpl.php arquivo do seu 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));
?>

Você não precisa imprimir third-menu porque por padrão ele aparecerá no menu de navegação.


NOTA: Essa não é a melhor prática para criar um menu de navegação e adicioná-lo a uma página. hook_menu () é para criar retornos de chamada de página e não para criar menus de navegação. Por favor, leia ISTO , o que explica as diferenças. Respondi a isso quando comecei a aprender o Drupal e não recomendo mais essa resposta.

AjitS
fonte
11
Esta não é uma prática recomendada para criar um menu de navegação e adicioná-lo a uma página. hook_menu () é para criar retornos de chamada de página e não para criar menus de navegação. Por favor, leia o seguinte, que explica as diferenças. api.drupal.org/api/drupal/includes!menu.inc/group/menu/7
Christian
11
@ Christian, eu apenas comecei a aprender Drupal enquanto respondia isso; e a maneira como eu preferia aprender Drupal era respondendo perguntas aqui, realmente tentando as coisas. No nível atual de conhecimento que tenho, definitivamente votaria também neste tipo de resposta; mas, na verdade, estou meio orgulhosa da maneira como pensava no início :) Agradeço a maneira como você explicou e o link fornecido.
AjitS
Hey AjitS, tudo de bom - eu não voto respostas para baixo com frequência. Eu simplesmente adicionaria uma atualização antes da resposta que diz que você não sugere mais essa abordagem. Obrigado pela resposta.
Christian
removi meu voto negativo.
Christian
0

Você também pode experimentar o módulo de importação de menus . É muito legal e fácil para a implantação do menu. Você pode criar um menu manualmente no seu site e usar JSON gerado. Além disso, você pode criar nós para páginas inexistentes.

Aqui está um exemplo de script de exportação:

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

Você pode executar este script com hook_update_N () ou atualizar o processador de script

milkovsky
fonte
0

Para criar um bloco de menus, no seu arquivo .install, implementando hook_enable (), digite

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

No mesmo arquivo .install, implementando hook_uninstall ().

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

A seguir, no seu arquivo .module, enquanto 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',
  ),
 );     
}

O arquivo .inc está dentro da pasta inclui dentro da pasta mymodule.

Consulte o arquivo devel.install e devel.module do módulo devel para obter mais informações.

sarathkm
fonte