SitePoint Sponsor

User Tag List

Results 1 to 15 of 15

Thread: How Difficult

  1. #1
    SitePoint Member
    Join Date
    May 2003
    Location
    United States of America
    Posts
    9
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How Difficult

    How difficult is it to make your own Template Engine?

    I am tired of hassling with all these other ones for my application, they either dont have what i want, have too much, dont seem to work for me, or their way of doing things is just unbearable....

    ty

  2. #2
    ********* Wizard silver trophy Cam's Avatar
    Join Date
    Aug 2002
    Location
    Burpengary, Australia
    Posts
    4,495
    Mentioned
    0 Post(s)
    Tagged
    1 Thread(s)
    Learn regular expressions and you're laughing

    Of course you'll need to have a sound plan and layering structure but the main programming concepts in a templating system are regex and loops as far as I can tell

  3. #3
    "Of" != "Have" bronze trophy Jeff Lange's Avatar
    Join Date
    Jan 2003
    Location
    Calgary, Canada
    Posts
    2,063
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    First you need to decide how in-depth you want it to be.

    Then I would look into the eval() function, it makes it simple to run stored code at runtime.
    Who walks the stairs without a care
    It shoots so high in the sky.
    Bounce up and down just like a clown.
    Everyone knows its Slinky.

  4. #4
    public static void brain Gybbyl's Avatar
    Join Date
    Jun 2002
    Location
    Montana, USA
    Posts
    647
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could probably do an entire templating system in one huge regex, with a couple of other statements to get the saved parts. That would be sweet

    Definitely regex, unless you feel like breaking apart thousands of strings manually and checking ASCII values (which is essentially what regex do, so there's no use in reinventing the wheel)
    Ryan

  5. #5
    SitePoint Member
    Join Date
    May 2003
    Location
    United States of America
    Posts
    9
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    all i basically want is includes, loops, if-else-elseif statements, and the reg (replacing)

    basically about indepth it would get......

  6. #6
    public static void brain Gybbyl's Avatar
    Join Date
    Jun 2002
    Location
    Montana, USA
    Posts
    647
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well that depends on what kind of templating system you want -- If you just want one that will replace static strings with dynamic ones, then its easy, you can do something like "{SITE_NAME}" in the code, and then a str_replace() in the code -- There ya have it, boom.

    Now, if you want to get really in depth and offer flexibility and customization (why wouldn't you?), you can write something like "[% WHILE {hasMoreElements} %]" and loop through things, and templates within templates and such and such -- That's quite involved. I've never really gone that far (haven't needed to up to now). You might check out the source code for Smarty or some of the other popular template engines -- Might get some ideas. CVS is a powerful resource.
    Ryan

  7. #7
    "Of" != "Have" bronze trophy Jeff Lange's Avatar
    Join Date
    Jan 2003
    Location
    Calgary, Canada
    Posts
    2,063
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm in the process of writing looping into my template engine for version 2.

    I'd like to be able to use PHP5 interfaces to force loops to be linked to objects extending a strict API, but I'll think of something.
    Who walks the stairs without a care
    It shoots so high in the sky.
    Bounce up and down just like a clown.
    Everyone knows its Slinky.

  8. #8
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think I would fall into the camp of "Why Reinvent the Wheel?" Either use Smarty http://smarty.php.net/ or just plain PHP:
    PHP Code:
    <?php echo $var ?>
    Obviously, many other threads on this topic here.
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  9. #9
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Go for it if you want experience, but expect it to take longer than you think. Allow a week for each major feature.

    Also, if you want nested loops then simple regexing will drive you nuts. You will first want to break it into tokens with a Lexer...

    Code:
    <table>
        {foreach people as person:<tr><td>{person:name}</td></tr>}
    </table>
    ...will send this to your parser (omitting spaces)...

    Code:
    <table>
    {
    foreach
    people
    as
    person
    :
    <tr></td>
    {
    person
    :
    name
    }
    </td></tr>
    }
    </table>
    You parser can react to these and store any incoming state.

    You can save yourself writing a Lexer by using one built into PHP called "expat". It tokenises XML only, so your template language will end up a little more verbose, but gets you past the first step straight away. You can always write a Lexer later that generates XML like parse events for other non-XML languages (called a SAX parser).

    Writing a full blown template engine took me about a month and was great fun. It has loops, substitutions, aliasing, file includes and macros . Sadly performance is an issue with the site I wrote it for and so has been abandoned . For this reason alone, go with XML. It's faster and later on you can then XSLT the templates straight into PHP code a'la Smarty.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  10. #10
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Angry

    That's it! Since AwesomeTemplateEngine I've been threatening to do this and now I'm going finally to do it!

    AwesomeTemplateEngine simply used include to "parse" the templates. The two limitations were you couldn't control the output - the moment the file was included it was displayed to the browser and variable scope was a problem.

    So here goes - the template "engine";

    PHP Code:
    <?php
    class Template {
        var 
    $bindVars;
        var 
    $file;
        var 
    $output;
        function 
    Template() {}
        function 
    setBindVars($bindVars) {
            
    $this->bindVars $bindVars;
        }
        function 
    setTemplate($file) {
            
    $this->file $file;
        }
        function 
    parse() {
            
    $vars get_object_vars($this->bindVars);
            foreach ( 
    $vars as $key => $value ) {
                $
    $key $value;
            }
            
    ob_start();
            include(
    $this->file);
            
    $this->output ob_get_contents();
            
    ob_end_clean();
        }
        function 
    toString() {
            return 
    $this->output;
        }
    }

    // Empty class for data to be "bound" to a template
    class BindVars {
        function 
    BindVars(){}
    }
    ?>
    Now for three templates;

    header.php
    PHP Code:
    <html>
    <head>
    <title><?php echo ( $title )?></title>
    </head>
    <body>
    colors.php

    PHP Code:
    <table>
    <?php
    foreach ( $colors as $color ) {
    ?>

    <tr>
    <td><?php echo ( $color ); ?></td>
    </tr>

    <?php
    }
    ?>
    </table>
    footer.php
    PHP Code:
    </body>
    </
    html
    And the script that triggers the parsing;

    PHP Code:
    <?php
    require_once('template.php');

    $template = new Template();

    $page '';

    $bindVars = new BindVars();
    $title='Templating the easy way';
    $bindVars->title $title;
    $template->setBindVars($bindVars);
    $template->setTemplate('header.php');
    $template->parse();
    $page .= $template->toString();

    $bindVars = new BindVars();
    $colors = array('red','blue','green');
    $bindVars->colors=$colors;
    $template->setBindVars($bindVars);
    $template->setTemplate('colors.php');
    $template->parse();
    $page .= $template->toString();

    $bindVars = new BindVars();
    $template->setBindVars($bindVars);
    $template->setTemplate('footer.php');
    $template->parse();
    $page .= $template->toString();

    // No output is displayed until you get here!
    echo ( $page );
    ?>
    That's it. Total control. Should you want to you could cache the output. You could even cache some of the output (e.g. header.php and footer.php) as a file while re-rendering other parts on each view). All you need to do is exert some self discipline making sure your template scripts contain only View logic (as in MVC).

    Can we all get on with our lives now?

    Edit:


    PS: Don't tempt me - I might even sort out the limitation that the code above has with references, throw in some caching and release this as open source as a serious tool

  11. #11
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Couldn't help myself - now made it serious with more examples (showing simple MVC seperation - see dir_controller.php example for something using a class as the "Model") and integration with PEAR::Cache_Lite so you can cache HTML output.

    Use it as you like (if at all) - make sure Cache_Lite is installed correctly.
    Attached Files Attached Files

  12. #12
    SitePoint Enthusiast
    Join Date
    Jul 2003
    Location
    Switzerland
    Posts
    36
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    BEWARE:
    If you write your own parse function, there should be carefull with local variables in the function with

    PHP Code:
            foreach ( $vars as $key => $value ) {
                $
    $key $value;
            }
            
             or ..

             
    extract($vars); 
    you will overwrite any variable in it.

    PHP Code:
    function parse_template($file,$array)    
    {    
           .... 
           
    extract($array,EXTR_SKIP);  // [EDIT] is safer than extract($array); 
           
    include($file);
           ....

    This function brings you some headache if you want replace $file in the template ...

    just my 2 cents
    Last edited by Rubas; Jul 23, 2003 at 08:45.

  13. #13
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you write your own parse function, there should be carefull with local variable in the function with
    ...
    This function brings you some headache if you want replace $file in the template ...
    The attached version fixes this. The trade off if you can use the variables $_vars, $_key or $_value in your template. References are also now handled properly.

  14. #14
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by HarryF
    PS: Don't tempt me - I might even sort out the limitation that the code above has with references, throw in some caching and release this as open source as a serious tool
    Now you are out of control Pry the keyboard out of that man's hands

    AwesomerTemplateEngine ??

  15. #15
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Now you are out of control
    Too much so Occurs to me the populate() method breaks the link with references so watch out - that needs fixing.

    Looking at extract() seems it now has the option of creating references (4.3.0+) so that's probably a better way to go.


Bookmarks

Posting Permissions

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