Tema avançado de menu no Drupal 7

15

Naveguei pela Web e não é de todo óbvio como tema de menus personalizados. Eu procurei por horas e não encontrei uma única postagem que ilustra o processo, do início ao fim, de criar um menu e personalizar sua saída. Parece que este é um processo de várias etapas:

  1. Crie o menu através da interface Drupal.
  2. Crie uma função de tema no seu template.phparquivo para criar um tema para a saída.
  3. Exponha esse menu a um arquivo de modelo (de alguma forma) adicionando-o como uma variável.
  4. Chame a themefunção no menu no arquivo de modelo.

1 é fácil de resolver, os problemas com que encontro são 2, 3 e 4. Observando o modelo de página padrão, vejo que ele expõe o menu principal da variável $main_menu. Mais tarde, na página, você pode ver a função theme('links__system_main_menu', array('links' => $main_menu..., o que significa que está procurando uma função de tema com nome apropriado em algum lugar e usando-a para gerar a saída.

Sei que coloco function theme_links__system_main_menu(&$variables) {...}no meu arquivo template.php o Drupal usará essa função em oposição a function theme_menu_links(&$variables) {...}.

O que não sei é como o Drupal vincula o menu personalizado que criei com essa função. Digamos, por exemplo, que eu criei um menu chamado My Menu. Eu poderia criar a seguinte função no meu template.phparquivo e tema a saída para esse menu?function theme_links__system_my_menu(&$variables) {...}

Além disso, como tornar esse menu personalizado disponível para um arquivo de modelo? Como o Drupal expõe a $main_menuvariável ao page.tpl.php?

Acho que a chave que falta aqui é como incorporar a variável que representa meu menu personalizado em uma página de modelo. Na maioria das vezes, estou completamente perdido com o que fazer depois de criar o menu.

Obrigado pela ajuda.

Edição: Provavelmente deve postar o que estou fazendo. De acordo com meu comentário ao BetaRide abaixo, preciso injetar HTML personalizado nos <li>elementos dos itens de menu. Especificamente, estou adicionando ícones do Twitter Bootstrap.

Lester Peabody
fonte

Respostas:

13

A implementação de menus do Drupal é um pouco especial, nem sempre funciona da maneira que parece.

Você pode dar uma olhada na implementação principal de template_preprocess_page () para saber como os links do menu principal são adicionados como uma variável ao modelo de página. Você precisa detalhar um pouco os documentos da API, mas a função que você deseja chamar na implementação de theme_preprocess_page () é menu_navigation_links () , que retornará uma matriz de links no menu.

Observando a linha 106 do arquivo page.tpl.php do núcleo do Drupal , você pode ver como os links do menu principal são temáticos no modelo chamando a função theme ( ) com um gancho de 'links__system_main_menu'.

Teoricamente, essa implementação deve poder ser duplicada com um menu personalizado seguindo as convenções de nomenclatura padrão. Então, no template.php, você pode ter:

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
}

e em page.tpl.php, você adicionaria algo assim:

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

No entanto, não é necessário adicionar o menu personalizado como uma variável no seu modelo de página. Você pode facilmente colocar o bloco do menu personalizado em uma região desejada através da interface de administração do Drupal. Além disso, você pode alterar as configurações do site para a fonte do menu principal , substituindo efetivamente a variável padrão $ main_menu em page.tpl.php pelo menu personalizado.

EDIT: Acabei de ver sua adição sobre seu objetivo final: adicionar apenas um html personalizado aos itens de menu dos ícones. Dependendo de como você está adicionando esses ícones, existem algumas opções diferentes do módulo Drupal.

Ícones do menu - permite fazer upload de uma imagem através das configurações do item de menu e gera automaticamente CSS (personalizável por meio de um modelo) que adiciona a imagem como plano de fundo ao item de menu.

Atributos de menu - permite adicionar uma classe personalizada a cada item de menu por meio de suas configurações no administrador. Depois que uma classe exclusiva é adicionada a cada item de menu, você pode usar CSS para adicionar um ícone ao item de menu ou usar javascript para injetar o HTML adicional no item de menu.

sheena_d
fonte
Isso parece responder a todas as minhas perguntas perfeitamente. Esta é uma ótima resposta. Vou tentar isso imediatamente.
Lester Peabody #
11
Funcionou, mas levei a sério a opinião unânime de todos e não usei esse método. Usei o módulo de atributos do menu que você sugeriu e atribuiu IDs exclusivos aos itens de menu específicos e, em seguida, usei o jQuery para injetar o HTML diretamente onde eu precisava. Obrigado pelas dicas. 1
Lester Peabody
"Você pode facilmente colocar o bloco do menu personalizado em uma região desejada através da interface de administração do Drupal" ++. Acho essa solução muito mais simples.
Cdm19 /
1

Você pode procurar no módulo Nice Menus . Aqui está uma citação sobre ele (na página do projeto do módulo):

... ativa os menus expansíveis suspensos / direito / esquerdo. Ele usa apenas CSS para a maioria dos navegadores, com Javascript mínimo para o IE6. (A versão 2 usa o plug-in Superfish jQuery para todos os navegadores, com uma opção para desativar o JS e volta ao CSS somente para navegadores que podem lidar com isso.)

Atualmente, são possíveis três estilos / tipos de menus: horizontal, menus suspensos; vertical, os menus voam para a esquerda; Na vertical, os menus voam para a direita. Existe uma página do manual que fornece uma lista de sites que usam os menus de Nice .

Os Menus agradáveis ​​criam blocos que podem ser associados a qualquer menu de site existente que pode ser colocado onde quer que blocos normais possam ser colocados em um tema. Para os temas, também é possível criar um tema como um menu agradável diretamente usando as funções de tema fornecidas, para que um bloco não seja necessário. Uma função de tema específica para o menu Links Principais está disponível. As funções do tema também permitem que um desenvolvedor passe em uma árvore de menus personalizada (por exemplo, não use um menu Drupal). Há mais informações sobre como usar as funções do tema no documentação .

O módulo é fornecido com um esquema de cores genérico simples, que pode ser totalmente substituído, adicionando o CSS de substituição à folha de estilo normal do tema ou criando um arquivo CSS de Menus Agradáveis ​​e instruindo os Menus a usarem esse, em vez do seu próprio padrão, através do global configuração do tema. Vários exemplos de substituição de CSS são fornecidos no arquivo README.txt incluído e no manual .

Stan Ascher
fonte
Não vejo por que alguém votou nesta resposta. Com Menus agradáveis, você pode segmentar um item de menu individual, pois ele possui sua própria classe. Em seguida, você pode usar um gráfico como plano de fundo para essa classe individual. Eu já fiz isso antes em alguns grandes projetos.
9788 Stan Stancher
2
Não votei, mas direi que isso não aborda o cerne da (s) pergunta (s) que fiz (s), que é como cavar o núcleo do tema Drupal para itens de menu. É por isso que essas perguntas nunca são respondidas completamente, porque sempre há algum módulo que o nome de alguém deixa cair. Não me importo com módulos, quero fazer a codificação de modelos.
Lester Peabody
11
Também não votei, mas quero acrescentar ao que Lester disse. Ao sugerir um módulo em sua resposta, você também deve explicar por que o está sugerindo e como ele pode ser usado para resolver o problema do OP. Sem esses detalhes, sua resposta pode ser vista como não muito útil e pode ser negada. Cometi esse erro nas minhas primeiras respostas aqui também.
sheena_d
0

Dependendo do que você deseja personalizar, sua abordagem é muito complicada. Normalmente, eu crio o menu através da interface do Drupal, como você sugeriu. Eu uso o módulo de desenvolvedor de temas e o Firebug para descobrir quais modelos, ganchos e diretivas CSS tenho que sobrescrever para ajustá-lo às minhas necessidades.

Vale a pena considerar a criação de um subtema do tema base que você está usando antes de começar a ajustar. Isso facilita muito a atualização do tema base.

BetaRide
fonte
Preciso injetar HTML personalizado nos elementos <li> dos itens de menu. Especificamente, estou adicionando ícones do Twitter Bootstrap.
Lester Peabody
0

aqui está um código inteligente que pode acessar todos os itens de menu para qualquer nível 2, 3 ou mais

coloque este código dentro do seu arquivo tpl, não se esqueça de chamar as últimas versões boostrap js e 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);


           ?>

esse código retornará o menu para as classes css, você pode usar o seu próprio, estou usando o bootstrap com alguns css personalizados

esse código é necessário após um trabalho árduo, pode economizar seu tempo e é testado no drupal 7.xe funciona bem no menu principal. Você pode alterar o menu como quiser

elaz
fonte