raelgc / template

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

Adição de facilitadores #14

Closed Valkhan closed 7 years ago

Valkhan commented 8 years ago

Em primeiro lugar gostaria de parabenizar pelo projeto na qual eu sigo desde a versão 1.9 (ou até antes não me recordo), aprendi muito com sua classe e desde então não consegui achar uma outra biblioteca similar que se propõe a trabalhar com templates de forma simples e objetiva.

Atualizei à algum tempo atrás para versão 2.2 quando ainda não tinha suporte para namespaces, não estou certo se é aqui que devo postar esta sugestão (sou noob em github), o caso é que adicionei alguns facilitadores que acredito que vão auxiliar outras pessoas (inclusive acredito que um dos 'Issues' abertos 'Array no Template' #7 seja resolvido com uma de minhas sugestões) e agregar mais valor à classe.

1 - Modo 'amigável' de detecção de erros: Tem algumas validações (definição de variável e blocos por exemplo) que acho desnecessário (em alguns casos, principalmente quando é uma rotina na qual o usuário não tem poder de modificação de dados em exibição, ou quando estes dados são tratados via sistema antes) jogar um erro na qual barra o processamento PHP, logo criei um flag ao instanciar a classe se estes erros devem ser suprimidos ou não.

2 - Case Insensitive Na verdade nunca testei para saber se é obrigatório as variáveis e blocos serem escritos em caixa alta, mas a verdade é que acho altamente desnecessário ter que informar a variável em caixa alta, por isso no PHP transformo o nome da variável informada em caixa alta antes de definir/consultar o valor da variável ou bloco, no HTML por costume sempre utilizo caixa alta. Note que a alteração é somente no PHP, o comportamento de identificação de variável e bloco no HTML não alterei em nada.

3 - Adição de variáveis e blocos por array Na verdade aqui eu tenho 3 funções, todas para evitar que eu fique gerando muita linha de código no PHP, segue a documentação abreviada e os códigos aplicados na classe abaixo: A: Função privada que adiciona blocos de um dado array (blockArr) B: Função privada que adiciona variáveis de um dado array (varsArr) C: Função pública que é responsável por chamar a função A ou B. (addArray)

    /**
     * Adiciona um bloco por array.
     * @param string $bloco Nome do bloco
     * @param array $data Array com variáveis
     * @author Paulo Lima 
     */
    private function blockArr($bloco, $data) {
        foreach ($data as $inc => $inf) {
            foreach ($inf as $var => $val) {
                $var = strtoupper($var);
                $this->{$var} = $val;
            }
            $this->block($bloco);
        }
    }

    /**
     * Adiciona variáveis por array.
     * @param string $variavel
     * @param array $data
     * @author Paulo Lima 
     */
    private function varsArr($data) {
        foreach ($data as $inc => $inf) {
            foreach ($inf as $var => $val) {
                $var = strtoupper($var);
                $this->{$var} = $val;
            }
        }
    }

    /**
     * Adiciona variáveis ou blocos por array.
     * array(
     *      array('variavel' => 'valor')
     * )
     * @param array $data Array
     * @param mixed $bloco Nome do bloco ou False para variável
     * @author Paulo Lima 
     * @return \Template
     */
    public function addArray(array $data, $bloco = false) {
        if (!$bloco) {
            $this->varsArr($data);
        } else {
            $this->blockArr(strtoupper($bloco), $data);
        }
        return $this;
    }

Um exemplo de uso prático: quero listar dados de cliente.

faço a inclusão deste bloco da seguinte forma:

$t = new Template([caminho_do_html]);
$t->addArray($dadosCliente,'LISTA_CLIENTE');
$t->show();

Desta forma uso apenas 3 linhas onde usaria no mínimo 8 se fosse utilizar as funções nativas da classe conforme exemplo abaixo:

$t = new Template([caminho_do_html]);
$tamDados = count($dadosCliente);
for ($x=0;$x<$tamDados ;++$x){
    $t->NOME = $dadosCliente[$x]['nome'];
    $t->TELEFONE = $dadosCliente[$x]['telefone'];
    $t->EMAIL = $dadosCliente[$x]['email'];
    $t->block('LISTA_CLIENTE);
}
$t->show();

Tenho estas funções desenvolvidas já, porém julgando pela classe atual e a classe que tenho em minhas mãos o seu release 'master' está mais atualizado que a minha, gostaria de sua opinião se acha melhor que eu faça um fork ou te envie meu fonte para estudar a implantação de minhas sugestões.

raelgc commented 8 years ago

Oi @Valkhan!

Obrigado pelas sugestões!

Vamos a elas, por ordem de "polêmica":

3 - AddArray

Muito bom! Lembro de ter alguém ter comentado sobre isso no passado, mas acho que era pré GitHub.

Se me permite uma pequena sugestão, poderíamos continuar usando a atribuição direta ao invés de usar um novo método: no método __set fazer algo similar a checagem por objeto. Checar se o $value é array, e aí chamar o foreach.

Idem para blocos.

2 - Case Insensitive

Gostei da idéia!

Só penso em 2 possíveis problemas:

1 - Modo amigável

Isso é algo bem polêmico... Eu entendo que reclamar das variáveis ou blocos que não existem pareça algo chato. Mas quando isso não existe, a gente perde um tempo muito grande tentando achar erro na nossa lógica do lado PHP, quando na verdade era apenas o nome da variável que estava errado.

Eu enxergo que o arquivo de layout (HTML ou qualquer outro) funcione como um formulário: se o campo (variável) não está lá, não adianta tentar atribuir valor.

Mas, para tentar contornar isso, no passado criamos o método ifExists pra checar se uma variável existe. Também passamos o erro gerado para uma Exception, então basta usar try/catch e seu programa irá ignorar os erros de variáveis/blocos que não existem e continuar.

Valkhan commented 8 years ago

Grato pelo seu pronto retorno, tem algumas observações que gostaria de acrescentar aos seus comentários.

Sobre o item 3: Achei realmente prático sua sugestão, na verdade nem tinha pensado nessa opção pois a forma que desenvolvi foi para funcionar independente do 'core' da classe, na perspectiva de um plugin por exemplo, mas havendo um método/tratamento nativo, acho até mais interessante.

Quanto ao item 2: A minha perspectiva realmente foi do lado do PHP. Quanto ao HTML teria que ter alguma 'configuração' para que o PHP trate como case insensitive ou não.

Quanto ao item 1: Entendo que seja polêmico se você forçar a escolha do desenvolvedor, se uma configuração (mantendo a forma que está hoje como padrão) for criada não vejo problema.

Pessoalmente quando preciso que uma variável seja 'obrigatória' eu posso 'ligar os erros' e debugar, ou simplesmente trabalhar com os 'erros ativos' validando as variáveis. Penso nas seguintes situações:

Requer validação de bloco / variável travando o PHP: Quando o bloco e variável é ESSENCIAL para a visualização estrutural do HTML.

Não requer validação do bloco / variável não travando o PHP: Quando é um template padrão do sistema, sem que os dados dinâmicos enviados em variáveis e blocos possam influenciar a visualização estrutural do HTML.

Compatibilidade: Eu criaria um array de configurações pré-definido (com as características atuais) e permitiria que no construtor da classe fosse enviado o array de configuração personalizado (na qual sofreria um merge com o array de configuração padrão da classe sobrescrevendo os valores informados pelo programador), desta forma as 'configurações' ficam escaláveis (novas funcionalidades = novas entradas no array) e resolvendo problemas de compatibilidade garantindo um dinamismo maior para classe.

De qualquer forma são sugestões e é meu perfil de trabalho, você tem que definir se é parte do escopo de sua classe permitir estas customizações ou não, pois nem tudo que eu enxergo como útil pode ser útil para a maioria.

Valkhan commented 8 years ago

Outro facilitador (e muito bom por sinal, acredito ter visto em comentários em outros issues) é a compatibilidade com o composer, não é difícil de fazer e é extremamente útil, se preferir posso criar um issue específico do composer.

raelgc commented 8 years ago

@Valkhan Acho que o item 2 e 3 poderiam vir na classe diretamente, realmente são ótimas sugestões, obrigado mesmo (vou ver se até o fds trabalho nisso)!

O item 1 (das variáveis não checadas), como eu costumo resolver: se eu tenho um comportamento que tem a ver com a minha rotina pessoal ser diferente do que a Template faz, eu crio uma classe filha que herda a Template e modifica tais comportamentos.

Por ex: eu tenho uma classe chamada Form que herda Template, e lá faço algumas coisas diferentes. Acredito que seria o meio mais simples (você poderia ter nos métodos de set um bloco try/catch, e dentro deles chamar o equivalente da classe pai).

Valkhan commented 8 years ago

@raelgc Sua sugestão de herdar a classe é muito bem vinda, é que nos projetos que trabalhei o nível de customização de sua classe foi tão baixo que preferi ir contra as boas práticas e manter num único arquivo (quando vc fizer a compatibilidade com o composer vou ter que deixar disso e apelar para herança mesmo rs).

De qualquer forma fico no aguardo, me posicione se precisar que efetue testes.

Valkhan commented 7 years ago

Mesmo assunto que: #21.