Você está aqui: Página Inicial Documentação Criando uma seção de navegação personalizada

Criando uma seção de navegação personalizada

por Ramiro B. da Luz última modificação 13/11/2011 09:56
Ao criar uma skin personalizada, você pode querer algo mais elaborado do que uma árvore de navegação, ou mais flexível do que as abas do portal. Este documento apresenta como criar uma seção de navegação que é gerado automaticamente a partir do conteúdo de uma pasta.

Criar uma seção de navegação personalizada

Ao criar uma skin personalizada, você pode querer algo mais elaborado do que uma árvore de navegação, ou mais flexível do que as abas do portal. Este documento apresenta como criar uma seção de navegação que é gerado automaticamente a partir do conteúdo de uma pasta.

Se você estiver criando um skin personalizado, você pode ter uma seção de navegação personalizada, talvez em um portlet, ou simplesmente como parte de uma personalização no main_template ou em outro template padrão (header, por exemplo). Este documento mostra como fazer isso, com as seguintes premissas e ressalvas:

  • Todos os itens que aparecem na barra de navegação estarão sob uma única pasta. Para este exemplo, essa pasta será '/sections', mas você pode usar o que quiser. (Se você quiser usar a pasta raiz do portal, passe uma string vazia como o nome da pasta na chamada para getSections abaixo.)
  • A ordem de navegação é significativa. Um administrador do portal pode usar os botões de reordenamento de uma pasta padrão no Plone para mudar a ordem do conteúdo da pasta '/sections'.
  • Você pode querer ignorar alguns itens. O padrão do Plone é considerar o atributo exclude_from_nav, que é exposto a partir da guia Properties de todos os tipos de conteúdo padrão e funciona como na árvore de navegação padrão.
  • Você pode querer sub-menus na sua navegação - este método vai permitir que você especifique uma profundidade fixa de sub-menus a considerar. Por exemplo, se você tiver uma pasta '/sections/info', e você definir a profundidade de 2, você será capaz de criar links para as pasta 'info' em si e seus filhos. Alternativamente, você pode obter todas as sub-seções sob uma determinada raiz.
  • Você provavelmente vai querer destacar o item selecionado atualmente. O método getSections manipula o item que você está vendo e define sua propriedade 'selected' como 'True'. Isso acontece de forma recursiva, o que significa que se você tiver um sistema de navegação de nível dois, e o usuário estiver em '/sections/contact/email-form', tanto contactemail-form seriam marcados como 'selected'.

 

Uso simples

Esta abordagem consiste em duas parte: um script chamado getSections.py que você deve colocar na sua pasta de skin (ou portal_skins/custom) e um trecho de código TAL que você pode usar como base para desenvolver a sua navegação personalizada.

O código TAL para mostrar a navegação deve chamar o script getSections e utilizar a sua estrutura de dados retornados em um ou mais laços 'tal:repeat'. Para uma navegação de nível dois mostrando todas as pastas e documentos em '/sections' na raiz do seu portal, você pode usar algo como:

 

 <ul class="topLevelNavigation"
     tal:define="sections python:here.getSections('/sections', levels=2, types=['Folder', 'Document'])">
     <li tal:repeat="section sections">
         <a tal:attributes="href section/item/getURL;
            class python:test (section['active'], 'selected', '');"
            tal:content="section/item/Title">
            Top level section
         </a>
         <ul class="secondLevelNavigation">
             <li tal:repeat="subsection section/children">
                 <a tal:attributes="href subsection/item/getURL;
                    class python:test (subsection['active'], 'selected', '');"
                    tal:content="subsection/item/Title">
                    Second level section
                 </a>
             </li>
         </ul>
     </li>
 </ul>

Observe o uso das classes CSS - use essas (ou classes similares) de forma adequada ao seu estilo de navegação. Em particular, observe que a classe da tag '<a>' está definida como 'selected' para os itens selecionados. Redefina '.selected' em sua folha de estilo para destacar o item selecionado atualmente na navegação.

Para melhorar a acessibilidade, itens de navegação como esses devem ser listados dentro de '<ul>'. Para verificar se sua navegação funciona, tente acessar seu site em um navegador de modo texto como o Lynx, ou desative os estilos do seu navegador (algo fácil no Firefox ou Opera). Se você enxergar uma lista aninhada, é bastante provável que o seu site seja acessível a pessoas com deficiência, e por meio de navegadores menos capazes.

 

Macros e listas recursivas aninhadas

Para dar um passo adiante, você pode usar macros recursivas para obter arbitrariamente lista aninhadas, porém com profundidade. Isso requer doistemplates e o uso de macros.

Em primeiro lugar, crie um modelo chamado 'navigation_macros.pt':

<ul metal:define-macro="navigation_menu">
    <li tal:repeat="section sections">
        <a tal:attributes="href section/item/getURL;
           class python:test (section['active'], 'selected', '');"
           tal:content="section/item/Title">
           Top level section
        </a>
        <tal:recurse define="sections section/children"
            condition="nocall:sections">
            <metal:call use-macro="here/navigation_macros/macros/navigation_menu" />
        </tal:recurse>
    </li>
</ul>

Observe o bloco 'tal:recurse'. Ele exibe a mesma macro novamente para cada sub-item do item atual, o que produz listas aninhadas. Tal bloco funciona notemplate chamado pela macro para definir uma variável 'sections' apontando para as seções do nível superior, e então redefine-os para apontar para a sub-seções, de forma recursiva.

Agora só precisamos indicar a recursividade do template em que o menu de navegação será exibido:

<tal:block define="sections python:here.getSections('/info')">
    <metal:call use-macro="here/navigation_macros/macros/navigation_menu" />
</tal:block>

Por não passar o parâmetro 'levels', você receberá todas as seções sob '/info'.