DevProTalk

DevProTalk (http://www.devprotalk.com/index.php)
-   PHP (http://www.devprotalk.com/forumdisplay.php?f=9)
-   -   Mala Template klasa (http://www.devprotalk.com/showthread.php?t=1085)

Ilija Studen 04. 06. 2006. 17:53

Mala Template klasa
 
1 Prilog(a)
Nije template jezik već jednostavna klasa koja izoluje template od ostatka aplikacije i omogućava lako baratanje sa njima. Daklen:

PHP kôd:

<?php

  
include 'Template.class.php';
  
  
tpl_assign('firstname''Ilija');
  
tpl_assign('lastname''Studen');
  
tpl_display('templates/something.php');  

?>

A something.php izgleda:

PHP kôd:

<?php if($firstname && $lastname) { ?>
<p>Dobrodosao <?= $firstname ?> <?= $lastname ?></p>
<?php } else { ?>
<p>Ne znam tvoje ime i prezime :(</p>
<?php ?>

Pored display() koji printuje kod ima i fetch() metod koji otvara output buffer, poziva display i vraća sadržaj output buffera nakon što je template pozvan (tj. vraća šta god je template printao kao string). Tu je i assign_by_ref funkcija.

I... to je to :) Skoro godinu dana radim sa ovom klasom i nije mi se ukazala potreba za bilo čim složenijim. Maleno, jednostavno, radi posao i ne smeta.

PHP kôd:

<?php

  
/**
  * Template class
  *
  * This class is template wrapper, responsible for forwarding variables to the
  * templates and including them.
  * 
  * @version 1.0
  * @author Ilija Studen <ilija.studen@gmail.com>
  */
  
class Template {
    
    
/**
    * Array of template variables
    *
    * @var array
    */
    
var $vars = array();
    
    
/**
    * Assign variable value to the template
    *
    * @access public
    * @param string $name Variable name
    * @param mixed $value Variable value
    * @return boolean
    */
    
function assign($name$value) {
      if(
trim($name) == '') return false;
      
$this->vars[trim($name)] = $value;
      return 
true;
    } 
// assign
    
    /**
    * Assign value by reference
    *
    * @access public
    * @param string $name
    * @param mixed $value
    * @return boolean
    */
    
function assignByRef($name, &$value) {
      if(
trim($name) == '') return false;
      
$this->vars[trim($name)] = $value;
      return 
true;
    } 
// assignByRef
    
    /**
    * Display template and retur output as string
    *
    * @access public
    * @param string $template Absolute path template path
    * @return string
    */
    
function fetch($template) {
      
ob_start();
      
$display $this->display($template);
      if(
$display === false) {
        
ob_end_clean();
        return 
false;
      } 
// if
      
return ob_get_clean();      
    } 
// fetch
    
    /**
    * Display template
    *
    * @access public
    * @param string $template Template path or path relative to templates dir
    * @return boolean
    */
    
function display($template) {
      return 
$this->includeTemplate($template);
    } 
// display
    
    /**
    * Include specific template
    *
    * @access public
    * @param string $template Absolute template path
    * @return null
    */
    
function includeTemplate($template) {
      if(
file_exists($template)) {
        foreach(
$this->vars as $k => $v) {
          if(!isset($
$k)) $$k $v;
        } 
// foreach
        
        
include $template;
        return 
true;
      } else {
        return 
false;
      } 
// if
    
// includeTemplate
    
    /**
    * Return template service instance
    *
    * @access public
    * @param void
    * @return Template
    */
    
function &instance() {
      static 
$instance;
      if(!
is_object($instance) || !is_a($instance'Template')) {
        
$instance = new Template();
      } 
// if
      
return $instance;
    } 
// instance
  
  
// Template
  
  // ==============================================================
  //  Shortcut methods
  // ==============================================================
  
  /**
  * Assign template variable
  *
  * @access public
  * @param string $varname Variable name
  * @return boolean
  */
  
function tpl_assign($varname$varvalue) {
    
$template_engine =& Template::instance();
    return 
$template_engine->assign($varname$varvalue);
  } 
// tpl_assign
  
  /**
  * Assign variable by reference
  *
  * @access public
  * @param string $varname
  * @param mixed $varvalue
  * @return boolean
  */
  
function tpl_assign_by_ref($varname, &$varvalue) {
    
$template_engine =& Template::instance();
    return 
$template_engine->assignByRef($varname$varvalue);
  } 
// tpl_assign_by_ref
  
  /**
  * Render template and return it as string
  *
  * @access public
  * @param string $template Template that need to be rendered
  * @return string
  */
  
function tpl_fetch($template) {
    
$template_engine =& Template::instance();
    return 
$template_engine->fetch($template);
  } 
// tpl_fetch
  
  /**
  * Render specific template
  *
  * @access public
  * @param string $template Template that need to be rendered
  * @return boolean
  */
  
function tpl_display($template) {
    
$template_engine =& Template::instance();
    return 
$template_engine->display($template);
  } 
// tpl_display

?>


robi-bobi 04. 06. 2006. 20:04

cenim tudje iskustvo (koje moze biti drugacije od mojeg)
cenim to sto cesto citam od tebe dobre postove
cenim to sto si postovao svoj kod na download

ali kakav je smisao takvog template-a?
da konkretizujem pitanje:
sta konkretno dobijas ovom klasom?

ako se vec tezi laganom resenju, zasto ne otici korak dalje i uopste ne koristiti template

P.S. ne kazem da ne treba odvajati logiku od prezentacije (to je nesto sasvim drugo)

MorenoArdohain 04. 06. 2006. 20:20

Meni je zatrebao neki ultralaki template sistem, posto u Smarty-ju koristim skoro samo foreach, literal, if/else, count i include, pa cu u dogledno vreme osakatiti njegov engine..
Ilijina klasa resava stvar za neke sitnije projekte, ali za vece stvari ipak je dobro koristiti template engine..

Ilija Studen 04. 06. 2006. 20:20

Citat:

Originalno napisao robi-bobi
ali kakav je smisao takvog template-a?
da konkretizujem pitanje:
sta konkretno dobijas ovom klasom?

Sličan pristup odvajanja aplikacije od prezentacionog dela kao kod Smartyja samo minimalizovan. Teško da može manje od ovoga, a osnovna funkcionalnost je zadržana (ne zagađuje se scope aplikacije, sve je izolovano, a zadržana je kompletna fleksibilnost templatea jer se mogu koristiti sve mogućnosti PHPa kao jezika).

Šta podrazumevaš pod "otici korak dalje i uopste ne koristiti template"? Primer takvog načina pošto ja stvarno ne vidim ništa loše u korišćenju templatea.

BraMom 04. 06. 2006. 20:30

Dobra ideja, php i jeste preprocessor, a i lepo kodiranje.

Šta bih tu rado video:

1. Ruzna je ova sintaksa tipa "<?php } else { ?>", kad bi se u templejtu to mozda pisalo kao {else}, a da klasa generise ovakav fajl (koji je kod tebe templejt) i snima ga u neki direktorijum, npr. templates_c/

2. Pa jos neki plugin, za <select> tag (html_options) i slicno...

I dobiješ smarty light... Ali onda se odstupa od osnovne ideje, a i već imamo smarty.

Čekaću da "otvoriš" php code generator, pretpostavljam da će me više zainteresovati.

Ilija Studen 04. 06. 2006. 20:46

Citat:

Originalno napisao BraMom
1. Ruzna je ova sintaksa tipa "<?php } else { ?>", kad bi se u templejtu to mozda pisalo kao {else}, a da klasa generise ovakav fajl (koji je kod tebe templejt) i snima ga u neki direktorijum, npr. templates_c/

Jeste ružna. To je ujedno i jedina veća mana jer se mnogima neće svideti. Mada, opet preporučujem korišćenje nekog ozbiljnijeg PHP editora i nema problema. Zend Studio ne pravi nikakve probleme sa blokovima, jasno ih razaznaje iako je između otvaranja i zatvaranja umetnut blok HTMLa, radi code completion (od čega možeš da se oprostiš kod Smartyja) itd. Kad se jednom navikneš ista stvar kao bilo koji drugi template jezik...

Što se tiče dodataka za brzo generisanje select boxova i slično to ubacujem u template spolja. Nije deo ove klase (helper koncept pozajmljen or Railsa).

Petar Marić 05. 06. 2006. 10:46

Heh, tvoji template fajlovi me maksimalno podsećaju na JSP ;)

ivanhoe 05. 06. 2006. 11:40

pa dobro, JSP je jedna od lepsih stvari u vezi jave IMHO :D

Edit: Evo sad sam tek stigao da bacim pazljivije pogled na kod, i imam par sitnih zamerki :

PHP kôd:

if(trim($name) == '') return false;
      
$this->vars[trim($name)] = $value

ovo se pojavljuje na vise mesta u kodu. U najvecem broju slucajeva ce parametar biti ok, pa ces da imas dupliran poziv trim() funkcije. Efikasnije bi bilo da se pise :
PHP kôd:

if( ! $trimmed trim($name) )
       return 
false;
$this->vars[$trimmed] = $value

Dalje:
PHP kôd:

foreach($this->vars as $k => $v) {
     if(!isset($
$k)) $$k $v;
// foreach 

nema potrebe da se tako radi, postoji php funkcija extract() koja radi istu stvar, samo mnogo efikasnije..

Takodje mislim da je dizajn same klase mogao da bude jos jednostavniji, malkice je previse rasparcan kod, imas puno metoda koje su prakticno obicni wrapperi za druge metode.. Ako je ideja da dalje usloznjavas mogucnosti klase onda ok, a ako je ideja da je koristis ovakvu kakva je, sa naglaskom na brzini i efikasnosti, onda bi mogao da izbegnes posrednike, posto su pozivi metoda najsporiji deo koda (mislim bas na kod, ne na pozive ka spoljnim resursima tipa baze i fajlova, naravno)

robi-bobi 05. 06. 2006. 17:37

mislio sam na ovako nesto
t.j. cist plain PHP

PHP kôd:

<?php
  $firstname 
'Ilija';
  
$lastname 'Studen';

  include (
'templates/something.php');  
?>

PHP kôd:

<?php if($firstname && $lastname) { ?>
<p>Dobrodosao <?= $firstname ?> <?= $lastname ?></p>
<?php } else { ?>
<p>Ne znam tvoje ime i prezime :(</p>
<?php ?>

Sad, vidim da radis trim, ovo-ono, ali meni mozda treba taj novi red na kraju promenljive
Takodje radis neke return false i slicno, medjutim ne vidim da igde proveravas sta je vraceno ;)


Citat:

pošto ja stvarno ne vidim ništa loše u korišćenju templatea
sve je stvar navike i stila
ne kazem da je loshe, pitam sta realno dobijas ovim - iskreno me interesuje

Ilija Studen 05. 06. 2006. 18:42

Hvala za komentare. Ima ovde što-šta da se nauči. Šta bi tek bilo da sam postovao neko složenije parče koda :D

@Ivanhoe

1. 100% si u pravu, ne sećam se kad sam zadnji put uneo pogrešno ime promeljive. Ta provera se može tretirati suvišnom, ali ipak nek ostane. Samo ponavljanje treba saseći.
2. Tek sad čujem za extract(). extract($this->vars, EXTR_SKIP) radi isti posao.
3. Jedino što može da se uradi, a da se izbegne copy paste je da se unutar fetch() metoda koristi includeTemplate() direktno (jer display u stvari radi samo to).

@Robi-Bobi - problem sa tvojim pristupom je što promenljive koje koristiš u templateime moraju da budu u istom scopeu gde se vrši include templatea. U većini slučajeva možeš da namestiš takvu situaciju, ali je to po meni nepraktično. Recimo samo da znam bar jedan pristup gde je takav pristup kamen oko vrata (da sad ne opisujem kako i šta, može da potraje). Ovako jednostavno sve template promenljive uguraš u scope za koji si 100% siguran da će biti dostupan templateima i to je to.

Ne trimuje se vrednost promenljive već njeno ime. Whitespace ionako ne možeš da imaš u imenu promenljive.

Što se vraćanja vrednosti tiče ova klasa baca exceptione u originalnom obliku, ali pošto toga u PHP4 nema samo zamenio sa return false. Ko voli nek proverava ;)


Vreme je GMT +2. Trenutno vreme je 22:52.

Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.

Mišljenja, saveti, izjave, ponude ili druge informacije ili sadržaji nastali na Sajtu su vlasništvo onoga ko ih je kreirao, a ne DevProTalk.com, tako da ne morate da se oslanjate na njih.
Autori poruka su jedini odgovorni za ovakve sadržaje. DevProTalk.com ne garantuje tačnost, kompletnost ili upotrebnu vrednost informacija, stavova, saveta ili datih izjava. Ne postoje uslovi pod kojima bi mi bili odgovorni za štetu ili gubitak koji je posledica bilo čijeg oslanjanja na nepouzdane informacije, ili bilo kakve informacije nastale kroz komunikaciju između registrovanih članova.
Web sajt može sadržavati linkove na druge web sajtove na Internetu ili neke druge sadržaje. Ne kontrolišemo niti podržavamo te druge web sajtove, niti smo pregledali bilo kakve sadržaje na takvim sajtovima. Mi nećemo biti odgovorni za legalnost, tačnost ili prikladnost bilo kog sadržaja, oglasa, proizvoda, usluga ili informacije lociranim na ili distribuiranih kroz druge web sajtove, niti za bilo kakvu štetu nastalu kao posledica takvih informacija. DevProTalk.com drži i čuva druga prava vlasništva na web sajtu. Web sajt sadrže materijale zaštićene copyright-om, zaštitne znakove i druge informacije o pravu vlasništva ili softver. Članovi mogu poslatu informacije zaštićene pravima vlasništva njihovih nosilaca i ona ostaju zaštićena bez obzira da li su oni koji prenose te informacije to naveli ili ne. Osim informacija koje su u javnom vlasništvu ili za koje dobijete dozvolu, nemate pravo da kopirate, modifikujete ili na bilo koji način menjate, objavljujete, prenosite, distribuirate, izvršavate, prikazujete ili prodajte bilo koju informaciju zaštićenu pravima vlasništva. Slanjem informacija ili sadržaja na bilo koji deo DevProTalk.com, Vi automatski dozvoljavate i predstavljate garanciju da imate pravo da dozvolite DevProTalk.com ili članovima DevProTalk.com bespovratnu, kontinualnu, neograničenu, globalnu dozvolu da koriste, kopiraju, izvršavaju, prikazuju i distribuiraju takve informacije i sadržaje i da iz takvih sadžaja koriste bilo koji deo u bilo koje svrhe, kao i pravo i dozvolu da koriste gore navedene sadržaje. Svi zaštitni znakovi (trademarks), logotipi, oznake usluga, firme ili imena proizvoda koji se pominju na ovom web sajtu su vlasništvo kojim raspolažu njihovi vlasnici.