raelgc / template

PHP Template
http://raelcunha.com/template.php
GNU Lesser General Public License v2.1
73 stars 42 forks source link

Árvore com blocos #20

Closed szardo closed 8 years ago

szardo commented 8 years ago

Olá. Comecei a utilizar esta classe de templates a algumas semanas em um novo projeto até para aprender sobre ele e passar a utilizá-lo nos demais que virão. Gostei muito, estou ainda construindo o layout da página inicial (é um site da instituição que trabalho, pensei em reformulá-lo do zero). Mas tive um pequeno problema ao tentar fazer uma espécie de árvore dinâmica com blocos. Vou tentar explicar melhor.

arvore.html

<!-- BEGIN NIVEL1 -->
    TESTE 1<br />
    <!-- BEGIN NIVEL2 -->
        --TESTE 2<br />
        <!-- BEGIN NIVEL3 -->
            ---TESTE 3<br />
        <!-- END NIVEL3 -->
    <!-- END NIVEL2 -->
<!-- END NIVEL1 -->

arvore.php

$tpl->block("NIVEL1");
$tpl->block("NIVEL2");
$tpl->block("NIVEL2");
$tpl->block("NIVEL2");
$tpl->block("NIVEL1");
$tpl->block("NIVEL3");
$tpl->block("NIVEL2");
$tpl->show();

Eu tenho a seguinte saída:

TESTE 1 TESTE 1 --TESTE 2 --TESTE 2 --TESTE 2

Ou seja, após alcançar o "NIVEL2" ele omite o fato de eu querer repetir só o nível 1 no loop dos blocos. Tentei dar uma olhada no código da classe, fiz algumas alterações mas sem qualquer sucesso.

Existe alguma forma de funcionar e eu estou fazendo errado? Se não, há alguma forma de alterar o código para que funcione?

Cheguei a isso, pois estou colocando uma barra de navegação no topo do site com menu drop down, e queria deixá-lo dinâmico para que pudesse adicionar/remover/alterar os itens do menu pela área administrativa. Mas se não houver esta possibilidade através de blocos eu tiro um pouco o dinamismo desta barra de navegação e está tudo bem. Só não queria desistir antes de ter a certeza de que não tem esta possibilidade.

Valkhan commented 8 years ago

Na verdade vc esta fazendo errado, os blocos devem começar do ultimo para o primeiro ou seja do 3 para o um, se houver necessidade mais tarde faço um exemplo, agora estou no celular.

szardo commented 8 years ago

@Valkhan tentei fazer aqui e não deu muito certo, ou não é o que eu preciso ou eu não entendi como deve ser feito. Quando puder, me demonstre. Valeu pela atenção!

Valkhan commented 8 years ago

@szardo É assim, quando você começa a fazer blocos dentro de blocos, você tem que tratar o bloco filho antes do bloco pai logo:

Exibe conteúdo do bloco 3 -> Exibe conteúdo do bloco 2 -> Exibe conteúdo do bloco 1.

Exemplo do código:

<?php

include('template.php');
/*
Supondo que eu queira exibir:
- 1 - Bloco teste 1, apenas 1 repetição
--2 - Bloco teste 2, primeira repetição com 3 itens
---3
---3
---3
--2 - Bloco teste 2, segunda repetição com 5 itens
---3
---3
---3
---3
---3
*/

$tpl = new Template('template.html'); //-- Coloquei seu bloco de teste dentro de um arquivo html.

//-- Começa imprimir o teste 3 do primeiro nível 2
for($i = 0 ; $i < 3 ; ++$i){
    $tpl->block("NIVEL3");
}
//-- Imprime o primeiro nível 2
$tpl->block("NIVEL2");
//-- Começa imprimir o próximo nivel 3
for($i = 0 ; $i < 5 ; ++$i){
    $tpl->block("NIVEL3");
}
//-- Imprime o segundo nível 2
$tpl->block("NIVEL2");
//-- Imprime o primeiro nível
$tpl->block("NIVEL1");
$tpl->show(); //- exibe na tela

/*
Resulta em:
TESTE 1
--TESTE 2
---TESTE 3
---TESTE 3
---TESTE 3
--TESTE 2
---TESTE 3
---TESTE 3
---TESTE 3
---TESTE 3
---TESTE 3
 */

Inclusive você pode criar um array com todas essas quebras e dentro da leitura do array principal ir criando os blocos.

szardo commented 8 years ago

@Valkhan Então se eu chamar o bloco 2 ou bloco 3 não vai mais ter como chamar uma repetição do bloco 1 após isso né? Se for assim, vou ter que mudar minha estratégia, pois realmente não vai dar pra fazer o que eu quero.

raelgc commented 8 years ago

Não estou acompanhando exatamente a lógica da discussão, mas só pra lembrar que o método block tem o parâmetro $append, que se tiver o valor true, mantém o valor anterior do bloco + o conteúdo novo.

Valkhan commented 8 years ago

@raelgc O @szardo está com dificuldades no entendimento do funcionamento do block.

A forma mais clara que eu consigo explicar é:

Toda vez que você popula uma variável dentro do bloco, ela vai entrar para a 'memória' da classe. Quando você quiser 'escrever' o conteúdo daquele bloco você chama a função block esse processo se repete quantas vezes for necessário, talvez com o exemplo inicial o entendimento ficou mais confuso. (Se preferir, me diga o que pretende fazer e eu te ajudo a fazer, se quiser passo meu Skype ou e-mail para te ajudar pois o que você apontou aqui não é de fato um 'problema').

Como você disse que pretende fazer uma 'árvore', vou fazer um exemplo de listagem de pastas supondo que essa estrutura de pastas seja:

/disco1/ /disco1/musicas /disco1/musicas/rock /disco1/musicas/metal sinfônico /disco1/musicas/trilha sonora /disco1/imagens/ /disco1/imagens/wallpapers /disco1/imagens/fotos e /disco2/ /disco2/programas /disco2/programas/sublime_text /disco2/programas/xampp /disco2/jogos/ /disco2/jogos/watch_dogs /disco2/jogos/assassins_creed /disco2/jogos/nba 2k16

Arquivo template.html

<!-- BEGIN NIVEL1 -->
>{NOME_NIVEL1}<br>
    <!-- BEGIN NIVEL2 -->
    >>{NOME_NIVEL2}<br>
        <!-- BEGIN NIVEL3 -->
            >>>{NOME_NIVEL3}<br>
        <!-- END NIVEL3 -->
    <!-- END NIVEL2 -->
<br>    
<!-- END NIVEL1 -->

Arquivo index.php

<?php
include('template.php');
$tpl = new Template('template.html');
$pastas = array(
    'disco1' => array(
        'musicas'  => array('rock','metal sinfonico','trilha sonora'),
        'imagens'  => array('wallpapers','fotos')
        ),  
    'disco2' => array(
        'programas'  => array('sublime_text','xampp'),
        'jogos'  => array('watch_dogs','assassins_creed','nba 2k16')
        )
    );

foreach($pastas as $nivel1 => $prox){
    foreach($prox as $nivel2 => $prox2){
        $tpl->NOME_NIVEL2 = $nivel2;
        foreach($prox2 as $nivel3){
            $tpl->NOME_NIVEL3 = $nivel3;
            $tpl->block('NIVEL3'); //-- Note que eu começo 'escrevendo' do último nível para o primeiro
        }
        $tpl->block('NIVEL2'); //-- Depois que todo o nivel 3 foi 'escrito' eu escrevo o nível 2
    }
    $tpl->NOME_NIVEL1 = $nivel1;
    $tpl->block('NIVEL1'); //-- depois que todo o nivel 2 foi escrito eu escrevi o nível 1 e assim por diante
}
$tpl->show();
?>

Para ficar exatamente igual a estrutura escrita acima (pastas separadas por /), basta alterar o arquivo template.html para este modelo:

<!-- BEGIN NIVEL1 -->
/{NOME_NIVEL1}<br>
    <!-- BEGIN NIVEL2 -->
    /{NOME_NIVEL1}/{NOME_NIVEL2}<br>
        <!-- BEGIN NIVEL3 -->
            /{NOME_NIVEL1}/{NOME_NIVEL2}/{NOME_NIVEL3}<br>
        <!-- END NIVEL3 -->
    <!-- END NIVEL2 -->
<br>    
<!-- END NIVEL1 -->
szardo commented 8 years ago

Maravilha @Valkhan, era exatamente isso que eu queria. A minha aplicação real disso como havia dito anteriormente, é a criação de uma navbar com menu drop down, mas de forma dinâmica que possa ser gerenciado no painel do site. O menu da navbar é o nível 1, a caixa que abra com o drop down é o nível 2 e os links dentro do drop down são o nível 3. Dei o exemplo de árvore (como a de arquivos, que você exemplificou) pra ficar melhor o entendimento, mas o resultado final é praticamente o mesmo.

Meu erro era que eu estava chamando o bloco pai antes do loop do foreach. Eu estava fazendo assim:

...
foreach($nivel1 as $k => $d){
    $tpl->NIVEL1 = $d[0];
    $tpl->block("BLOCK_NIVEL1");
    foreach($nivel2[$k] as $dd){
         ...
     }
}
...

Ou seja, eu chamava o bloco pai antes do foreach que chama o bloco filho. Sei que havia me alertado isso antes, mas eu ja tava batendo cabeça com isso a pelo menos 3 dias seguidos e não prestei atenção. Desculpa o erro besta e muito obrigado pela atenção.

raelgc commented 8 years ago

@Valkhan Obrigado por toda ajuda!