Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    Senior Coder
    Join Date
    Aug 2005
    Posts
    1,119
    Thanks
    2
    Thanked 1 Time in 1 Post

    Suggestions for class based template engine

    Im interested in finding the best method for a template system. I wan to have the engine as a class, and all the templates will be in tpl files. Does anyone have any ideas on how to do variables, parse things, etc. Im looking for ideas.

  • #2
    Super Moderator Inigoesdr's Avatar
    Join Date
    Mar 2007
    Location
    Florida, USA
    Posts
    3,642
    Thanks
    2
    Thanked 405 Times in 397 Posts
    Just use Smarty.

  • #3
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    Template classes are IMO the best route to go. Reading from files is fine as well, though not quite as secure (depending on your methods) as users can directly access the template directory unless its above your root. Chances are that will not be a problem however.
    To start, parse variables using an eval function. This allows you to parse and store variables if desired. Eval does not print output to the screen so you will need to handle that as well.
    Next, beware of a common pitfall: escaping. Assuming that your .tpl file is nothing more than html with php variables, ie:
    Code:
    // Yeah I know I'm too lazy to declare
    <html>
        <head>
            <title>$pageTitle</title>
        </head>
    <body>
    ...
    </body>
    </html>
    or something of the sorts (note that you do not need to declare any html, head or body wrappers except on your 'shell' based templates). Just run an addslashes after reading before evaling.
    Skeleton code would probably look like so:
    PHP Code:
    public class TemplateHandler
    {
        public static function 
    fetchTemplate($templateName '');
        public static function 
    printTemplate($templateName '');
        private static function 
    parseTemplate($templateName '';

    Where fetchTemplate opens and stores the requested template, printTemplate, well prints it (uses the fetchTemplate), and parseTemplate evaluates the code as php.
    As you can see this is a static class and does not need an instantiation. You can create a TemplateHandler object if you want (Template->fetchTemplate()) or keep it static (TemplateHandler::fetchTemplate()). For php 4.x compatability, drop any public/privates and static declarations, and do keep in mind to not refer back to it as an object at any time if you want to keep it as a static method. This is really your choice. The above code is more of an abstract / interface class, but it will give you an idea.
    You may want to add more to it too, to update the templates and read the actual data without parsing. All easily added into the class
    Hope that gives you an idea!
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • #4
    Senior Coder
    Join Date
    Aug 2005
    Posts
    1,119
    Thanks
    2
    Thanked 1 Time in 1 Post
    The thing is, im planning on coding my own, but the issue im having is visualizing how to get everything to come together. Thats why i need ideas of how i should make it work, not links to actual scripts. The template files have to be outside of php for this script btw.

  • #5
    Super Moderator
    Join Date
    May 2002
    Location
    Perth Australia
    Posts
    4,040
    Thanks
    10
    Thanked 92 Times in 90 Posts
    well if it helps, my template is a single class which handles standard placeholders IF's and simple loops (no nested loops) it is called and constructed with the template..

    PHP Code:
    <?php
    include_once LIB.'/lib/std_tpl_parser.class.php';
    $yaks = new std_tpl_parser(TPL_PATH.'/tplname.tpl');

    //grab and set the standard replacements
    $static=array($db->fetch("SELECT * FROM table WHERE id=$id"));
    $yaks->set_static_data($static);

    //an iterator, there can be several in a template but not nested
    while($row=$db->fetch("SELECT id,name,blah FROM table")){
      
    $its[]=$row;
    }
    $yaks->set_iterator_data('MAIN'=>$its);
    return 
    $yaks->parse();
    ?>
    I use {REPLACE_THIS} for normal replacements (replaced from the $static associative array)
    and
    {{ITERATE=ITER_NAME}
    {ID},{NAME},{BLAH}<br />
    {/ITERATE}}

    I also allow for {INCLUDE=filename} etc and some other framework specific replacements...

    As for the how its sadly all down to regex, in my implementation I pre-parse the iterators and then the standard replacers from the template file all in the constructor...
    PHP Code:
    <?php
    class templater{
      function 
    templater($tpl){
        
    $this->tpl=file_get_contents($tpl);
        
    $this->iterators[]=$this->parse_iterators();
        
    $this->includes[]=$this->parse_includes();
        
    $this->static_vars[]=$this->parse_static();
        
    $this->static_vars[]=$this->parse_constants();
      }

      function 
    iterators(){
        
    //regex to find and store all of the {{ITERATE=*}{/ITERATE}} stuff
      
    }
      function 
    static_vars(){
        
    //regex to find and store all the {VARS} in the template
      
    }
      
    //etc
    }
    ?>
    then the calls to set_static_data and set_iterator_data will store the replacement data ready for the parse() call which sticks it all together

    I found that it was important to remove the iterated content and the included content from the template before parsing for static vars.

    Pre-parsing the template itself to extract placeholders seemed OTT but it does allow for extras like checking that a template has all the required placeholders before moving any further.

    Sadly my regex is shocking and I have yet to implement any template-engine level caching but that is the plan.

    I did not use smarty or similar because I wanted something lightweight, did not want to create my own language within PHP etc since PHP IS a templating engine ... but I do regret not adding an ELSE option which I will do when I try again!
    resistance is...

    MVC is the current buzz in web application architectures. It comes from event-driven desktop application design and doesn't fit into web application design very well. But luckily nobody really knows what MVC means, so we can call our presentation layer separation mechanism MVC and move on. (Rasmus Lerdorf)

  • #6
    Senior Coder
    Join Date
    Aug 2005
    Posts
    1,119
    Thanks
    2
    Thanked 1 Time in 1 Post
    can you post your entire templater class for me to work off of?

  • #7
    Senior Coder
    Join Date
    Aug 2005
    Posts
    1,119
    Thanks
    2
    Thanked 1 Time in 1 Post
    *bump*


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •