19 ago2011

Separando menu de sub-menu com Zend Navigation

por Matias Rezende

Olá galera!!!!

Mais um artigo da série sobre Zend Navigation. Já viu os outros? Aqui tem o link para a série completa. Vale a pena começar por lá.

Muita vezes temos em um site um menu superior e um menu interno, que varia de acordo com a página. Com o Zend Navigation é fácil de resolver este problema. Para isto, utilizaremos os métodos setOnlyActiveBranch(), setMinDepth(), setMaxDepth(), setRenderParents() e setUlClass() do objeto menu(). Explicando cada um deles rapidamente (maiores informações -> link):

setOnlyActiveBranch(bool false)

Define que somente o galho ativo deve ser exibido. Por exemplo, caso exista mais de um menu com sub-menus, só aparecerá o sub menu em que o menu principal esteja ativo. Ou seja, caso estejamos na página A Empresa, somente será exibido o ramo relativo à página A Empresa.

setMinDepth(int)

Define a profundidade mínima do menu a ser exibida.

setMaxDepth(int)

O oposto do método anterior. Define a profundidade máxima do menu a ser exibida.

setRenderParents(bool true)

Define se junto a um sub menu deve ser renderizado também o pai destes menus. Por exemplo, no caso da página A Empresa, define se no sub-menu o link para página A Empresa aparecerá também.

setUlClass(string)

Define o menu com esta classe. Util para definir formatação diferente para menu e sub-menu.

Então, para montar o menu superior sem sub-menu, colocando o sub-menu na lateral sem o menu principal, modificaremos o arquivo base de layout que temos usado na série de artigos para o seguinte:

arquivo default.ini (arquivo de navegação – mesmo do último artigo)

;; Página Início
home.label = "Início"
home.controller = "index"
home.action = "index"
home.class = "home"
home.title = "Página Inicial"
home.route = "default"
;; Página A empresa
empresa.label = "A empresa"
empresa.controller = "empresa"
empresa.action = "index"
empresa.title = "Informações sobre a empresa"
empresa.route = "default"
        ;; História
        empresa.pages.historia.label = "História"
        empresa.pages.historia.controller = "empresa"
        empresa.pages.historia.action = "historia"
        empresa.pages.historia.title = "História da empresa"
        empresa.pages.historia.route = "default"
        ;; Missão
        empresa.pages.missao.label = "Missão"
        empresa.pages.missao.controller = "empresa"
        empresa.pages.missao.action = "missao"
        empresa.pages.missao.title = "Missão da empresa"
        empresa.pages.missao.route = "default"
        ;; Visão
        empresa.pages.visao.label = "Visão"
        empresa.pages.visao.controller = "empresa"
        empresa.pages.visao.action = "visao"
        empresa.pages.visao.title = "Visão da empresa"
        empresa.pages.visao.route = "default"
;; Página Notícias
noticias.label = "Notícias"
noticias.controller = "noticias"
noticias.action = "index"
noticias.title = "Notícias sobre o mercado"
noticias.route = "default"
        ;; Categoria Esportes
        noticias.pages.esportes.label = "Esportes"
        noticias.pages.esportes.controller = "noticias"
        noticias.pages.esportes.action = "index"
        noticias.pages.esportes.title = "Notícias sobre Esportes"
        noticias.pages.esportes.route = "categoria"
        noticias.pages.esportes.params.categoria = "esportes"
        ;; Categoria Entretenimento
        noticias.pages.entretenimento.label = "Entretenimento"
        noticias.pages.entretenimento.controller = "noticias"
        noticias.pages.entretenimento.action = "index"
        noticias.pages.entretenimento.title = "Notícias sobre Entretenimento"
        noticias.pages.entretenimento.route = "categoria"
        noticias.pages.entretenimento.params.categoria = "entretenimento"
        ;; Categoria Tecnologia
        noticias.pages.tecnologia.label = "Tecnologia"
        noticias.pages.tecnologia.controller = "noticias"
        noticias.pages.tecnologia.action = "index"
        noticias.pages.tecnologia.title = "Notícias sobre Tecnologia"
        noticias.pages.tecnologia.route = "categoria"
        noticias.pages.tecnologia.params.categoria = "tecnologia"
;; Página Contato
contato.label = "Contato"
contato.controller = "contato"
contato.action = "index"
contato.title = "Entre em contato conosco"
contato.route = "default

layout.phtml

<div id="wrapper">
        <div id="top">
                <?php echo $this->navigation()->menu()->setMaxDepth(0);?><!-- /menu -->
        </div><!-- /top -->
        <div id="content">
                <?php echo $this->navigation()
                                ->menu()
                                ->setOnlyActiveBranch(true)
                                ->setMinDepth(1)
                                ->setMaxDepth(1)
                                ->setRenderParents(false)?>
                                ->setUlClass('sub-menu')?><!-- /sub-menu -->
                <?php echo $this->layout()->content;?>
        </div><!-- /content -->
        <div id="footer">
                <p>Blog do Matias &copy; <?php echo date('Y')?> • http://matiasrezende.com.br</p>
        </div><!-- /footer -->
</div><!-- /wrapper -->

Explicando:

  • No menu principal, definimos setMaxDepth(0) para evitar que fosse renderizado o sub-menu.
  • No sub-menu, definimos setOnlyActiveBranch(true) para que fosse exibido somente o sub-menu relativo ao menu selecionado.
  • Ainda no sub-menu, definimos setMinDepth(1) para evitar que fosse renderizado o menu principal no sub-menu e definimos setMaxDepth(1) para sobrescrever o que foi definido no objeto anterior (menu), permitindo que apareça só e somente 1 nível de sub-menu.
  • Como não queremos que apareça o menu pai renderizado no sub-menu, definimos setRenderParents(false).
  • Classe sub-menu somente para demonstrar a funcionalidade, apesar de não ser necessário.

Vejam que mesmo com o menu e sub-menu, o Zend Navigation continua definindo o menu e o sub-menu que está ativo com a classe active, como vimos no primeiro artigo.

Obs.:

Existe o método renderSubMenu(), que funciona quase como queremos. Ele renderiza, como o manual diz, o sub-menu mais profundo do container ativo. O problema aparece quando não existe sub-menu no menu ativo (no nosso exemplo, na página Início e Contato, que não tem sub-páginas). Nestes casos, o sub-menu renderizado passa a ser o próprio menu, o que não é o comportamento desejado para este caso, mas se em uma situação você SEMPRE tiver sub-menu, você pode trocar setMinDepth(), setMaxDepth(), setOnlyActiveBranch() e setRenderParents() pelo renderSubMenu().

Está começando a ficar bom utilizar o Zend Navigation??? Vai ficar ainda melhor, pois ainda não vimos Breadcrumbs, Sitemap e integração com Zend_Acl.

Fiquem ligados e acompanhando o restante da série sobre um ótimo recurso do Zend Framework, que facilita bastante nossa vida na hora de criar aplicações.

Comentem!!!

11 respostas para “Separando menu de sub-menu com Zend Navigation”

  • Jonas Lauxen

    Muito bom o material…

    Parabens

  • felipe gama

    boa tarde!!! primeiramente para bens pelo blog e pela forma como explica as coisas, é bem didático!!!

    tenho uma duvida, é possível fazer um menu com sub-menus (so que sub-menu fique “escondido” ate ocorrer uma ação sobre o botao “pai”).

    entendeu?? um menu que tem em varios sites e cms!!

    será que é possivel???

    desde ja, agradeço

  • Danillo

    Parabéns continue assim cara Que Deus abençoe de conhecimento em dobro para vc abraços

    Não vejo a hora de finalizar sobre o zend navigation to precisando urgentíssimo de chegar na acl valeuuUUUuu otimos tutoriais

  • Danillo

    Blz Estarei ansioso esperando e pode ter certeza valeu mesmo e continue sempre assim….

  • Danillo

    Vc por acaso tem algum exemplo do menu no formato ini com o efeito drop Down to procurando na net mais está muito complicado achar… sei que tem como fazer no css e JS mais não sei como por favor se souber de algum exemplo por mais simples que seja agradeceria muito abraços.

  • Danillo

    Seria como passar o mouse em Empresa por exemplo e surgir logo abaixo as opções Historia, Missão e Visão ao invés de clicar e aparecer logo abaixo seria bom, ate enquanto vc não posta sobre ACL porque ai eu iria estruturando o jeito que iria ficar ja o projetinho aqui abraços. e obrigado pela atenção.

  • Danillo

    Você sabe se tem como criar um outro item do sub menu exemplo:

    Você abre a empresa da empresa e abre a historia e da historia ele lista 3 categorias de historias..

    Entendeu… Seria como na linha empresa.pages.historia.label = “História” teria como criar um sub menu desse item obrigado.

    • Matias Rezende

      A lógica é a mesma. Seria algo assim:

      empresa.pages.historia.pages.primeira-categoria-historia.label = "Primeira História"
      empresa.pages.historia.pages.primeira-categoria-historia.controller = "controller"
      empresa.pages.historia.pages.primeira-categoria-historia.action = "action"
      empresa.pages.historia.pages.primeira-categoria-historia.title = "Primeira história"
      empresa.pages.historia.pages.primeira-categoria-historia.route = "default"
      
      empresa.pages.historia.pages.segunda-categoria-historia.label = "Segunda História"
      empresa.pages.historia.pages.segunda-categoria-historia.controller = "controller"
      empresa.pages.historia.pages.segunda-categoria-historia.action = "action"
      empresa.pages.historia.pages.segunda-categoria-historia.title = "Segunda história"
      empresa.pages.historia.pages.segunda-categoria-historia.route = "default"
      

      Captou a ideia?

      • Danillo

        Valeuuu Matias Consegui… lembra a Duvida do DropDow que eu queria consegui também ta ficando legalzinho agora…

        e ai quando é que vc vai postar sobre a ACL funcionando com o menu e as paginas… Estou muito ansioso….

        Meus parabéns novamente pelo Blog

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>