SitePoint Sponsor

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 25 of 52

Hybrid View

  1. #1
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How to go about templates

    Hi gang, I am having a problem with how I should go about templates. I am not sure if my approach is a very good one considering its disadvanatges, so please have a look.

    here we go, the way I do it now. In order to require as little php knowledge as possible from the designer I even factor out very little template bits into their own files.

    Have a look at this code:

    PHP Code:
    <?php
        
    private function issueArchive() {  
            
    // fetch the issues from the collection and build
            // html with them
            
    $rows=array();

            while ( 
    $issue=$this->issueCollection->fetch() ) {            
                
    $issueRow =& new Template('issue_row'); 
                
    $issueRow->setValue('{DATE}',date('F d, Y'$issue->getDate() ));
                
    $issueRow->setValue('{ID}',$issue->getId());
                
    $issueRow->parse();            
                
    $rows[] = $issueRow->fetch();
            }
                   
            
    // Alternating Row Color Support
            
    require_once(VIEW_HELPER_PATH.'AlternatingRowColorer.php');
            
    $rowColorer=& new AlternatingRowColorer($rows'{ROW_COLOR_CLASS}''row1''row2');
            
    $rows=$rowColorer->fetch(); 
            
            
    // convert the rows to a string
            
    require_once(VIEW_HELPER_PATH.'ArrayToStringConverter.php');
            
    $conv=& new ArrayToStringConverter($rows);
            
    $rows=$conv->fetch(); 
            
            
    // acquire heading, etc - build the page
            
    if(count($rows) > 0) {
                
    // Get heading
                
    $heading =& new Template('issue_list_heading');
                
    $heading->setValue('{TEXT}','Community Crier Archive');
                
    $heading->parse();
                
    $heading $heading->fetch();
                
                
    $archive =& new Template('issue_list');           
                
    $archive->setValue('{TITLE}',$heading);
                
    $archive->setValue('{ROWS}',$rows);
            } else {
                
    $archive =& new Template('error_page');
                
    $archive->setValue('{TITLE}','Error Title');
                
    $archive->setValue('{CONTENT}','Sorry, there are no issues yet!');
            }
            
            
    $archive->parse();
            return 
    $archive->fetch();
        }
    }
    ?>
    Should be self-explaining, if not, please ask.

    This is what the issue_row template file includes:

    Code:
    <li>Issue from <a href="index.php?page=view_issue&amp;id={ID}">{DATE}</a></li>
    This is what the template file 'issue_list' includes:

    Code:
    {TITLE}
    <ul class="archive_list">
    {ROWS}
    </ul>
    Okay what does that tell us? The presentation is greatly outsourced into files. The designers won't have to deal with any php code or code of another scripting language (other than Javascript if they want to use it - the php coder doesn't care).

    Problem: He has to mess with HUNDREDS of files. Basically whenever I use a list of things I create a separate ****_list file template, that contains '<li>{VAR]</li>' or something. Now that is not very cool. The question is how can I mainatain all this decoupling while storing more template information in the different files? Sounds like using functions, but then again this would mean adding php code to the scripts. Any ideas here?

  2. #2
    SitePoint Guru gavwvin's Avatar
    Join Date
    Nov 2004
    Location
    Cornwall, UK
    Posts
    686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    most templating engines have language constructs like for loops:
    Code:
    {TITLE}
    <ul class="archive_list">
    <!-- BEGIN for ARCHIVES -->
    <li>Issue from <a href="index.php?page=view_issue&amp;id={ARCHIVES.ID}">{ARCHIVES.DATE}</a></li>
    <!-- END for -->
    /ul>
    Where ARCHIVES is an array. Perhaps you should consider introducing something similar

  3. #3
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Umm...

    I might be coming across as being two faced (I'm not, let me asure you) but I've long been an advocate of keeping PHP out of HTML, as I've thought of it as breaking layering.

    I still do, unfortunately I've taken steps to use PHP variables with HTML (where HTML is the markup, as in it ain't going to change) due to the needs of performance. Parsing the HTML template to look for your variables or tokens takes x amount of time.

    Depending on the server usage, as this increases there is a performance lose. Caches help to some degree, but even these become stale after a while. So what I'm saying I suppose, is that maybe it's just as well to use PHP iterator's within the HTML, ie For outputting the data?

    I'm not suggesting that you therefore place presentational logic in the HTML though, as that is going a bit too far

  4. #4
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you can live with your markup being xhtml-strict, you could also use XSLT as a template-engine. Being (mostly) declarative in nature, it may be more intuitive for a graphic-designer to use than an imperative language. It also has some benefits in portability. Regarding performance, I would guess it to be faster than a custom regexp-based algorithm. (Not that this should be decisive for your choice, I think)

  5. #5
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Norway - Oslo
    Posts
    198
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've gone the "smarty route" when building a template system, compiling the templates over to php code.
    Parsing templates at runtime is a lot slower than using the php parser, a _LOT_.
    Its also easier to compile the template over to php than writing a parser (which was the first solution i tried and found to be too slow).

    I just provide foreach-functionality and if/else to be used in templates. Without looping and control structures you will find the code you need to make a bit inefficient, thats my experience anyway.

  6. #6
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you all for your contributions. So do you guys also go about having lots of different template files (whether you use loops and conditional structures or not) or do you wrap them up into functions somewhere so that you don't have to deal with lots of files?

  7. #7
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I kind of like your idea of having a bunch of files for templates...

    What if you had some default ones that could be overwritten depending on the context/url/directory? EZPublish uses a neat override method that lets you override templates, depending on the "location" (fron-end, back-end etc...). There are lots of templates but as you get lower into the structure, you are inheriting from the parent directory (node actually) and override as needed. So, you'd have a default "List" template that would be used for all lists, but you could override at any point. etc...

    Matt

  8. #8
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DarkAngelBGE
    Thank you all for your contributions. So do you guys also go about having lots of different template files (whether you use loops and conditional structures or not) or do you wrap them up into functions somewhere so that you don't have to deal with lots of files?
    While programmers love decomposition, designers prefer to work with monolithic files because those look nice in their visual tools.

    Being (mostly) declarative in nature, it may be more intuitive for a graphic-designer to use than an imperative language.
    I can hardly imagine a graphic-designer that finds something like <xsl:template match="LINE[position()=last()]"> "intuitive".

  9. #9
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    One of the consequences of web development is that you will end up with a load of template files, just because of the nature of todays dynamic, interactive web sites and browser based applications.

    Just ain't no way around it as far as I see it. But really, it isn't a problem or issue as far as a developer goes, unless of course you need to design as well. From the development point of view, we are only concerned of fetching the files in question, making sure they are outputted in the order of the page structure as required, and not pretty they look.

    What does help though, is having a good relationship with the designer(s), as if communication is open and honest and discussion is clean ( ) then this is have the battle I think

  10. #10
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    Just ain't no way around it as far as I see it.
    Probably the only way to reduce the number is to put multiple template blocks into a single file where possible. I have found that this also helps designers to be able to work on the related parts together.
    Christopher

  11. #11
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't like having too much template files. One (rarely two) is more than enough, with different blocks being parsed according to the application logic.
    But it depends on your template engine (what features does it support), and how much time does it take to generate the output.

  12. #12
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by REMIYA
    I don't like having too much template files. One (rarely two) is more than enough, with different blocks being parsed according to the application logic.
    But it depends on your template engine (what features does it support), and how much time does it take to generate the output.
    I use templates for everything, usually heirarchical templates. I tend to use simple HTML templates with tags or PHP templates. The template code I use is about 2k, as simple and fast as you can get, and supports both styles with the same interface -- I just change the filename if I want to switch. As much as possible I try to let designers work as they normally do.
    Christopher

  13. #13
    SitePoint Guru
    Join Date
    Sep 2004
    Posts
    613
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's the route I'm taking...

    PHP Code:
    <?PHP
    $ACP_Design 
    = new ACP_Design();
    class 
    ACP_Design()
    {
            var 
    $action "";
            var 
    $method "";

            function 
    BeginTable($title ''$cols '1'$width '98%'$cellpadding '3'$cellspacing '0'$border '1'$bordercolor '485971')
            {
                    echo 
    "<table width='".$width."' cellpadding='".$cellpadding."' cellspacing='".$cellspacing."' style='border: ".$border." px solid #".$bordercolor.";'>\n";
                    if(
    $action != "" && $method != "")
                    {
                            echo 
    "        <form method='".$this->method."' action='".$this->action."'>";
                            unset(
    $this->method);
                            unset(
    $this->action);
                    }
                    if(!empty(
    $title))
    echo 
    "        <tr>
                    <td class='title' colspan="
    .$cols.">".$title."</td>
            </tr>"
    ;
            }

            function 
    NoResults($msg$cols '1'$class 'basic'$margin '8')
            {
                    echo 
    "
            <tr>
                    <td class='"
    .$class."' colspan=".$cols."><div style='margin:".$margin." px;'>".$msg."</div></td>
            </tr>
    "
    ;
            }
            
            function 
    EndTable($html ''$float 'right'$cols '1'$margin '2'$class 'solidheader')
            {
                    if(!empty(
    $html))
                    {
                            echo 
    "
            <tr>
                    <td class='"
    .$class."' colspan=".$cols."><div style='margin:".$margin." px; float: ".$float.";'>".$html."</div></td>
            </tr>"
    ;
                    }

                    echo 
    "\n</table>\n";
            }
    }
    ?>
    My reason for doing such is that primarily people just have to edit the CSS file.... if they want to modify the other stuff they can.... I just don't know a better way to do it..

    NOTE: This code is untested!!!

  14. #14
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Webnet
    Here's the route I'm taking...

    My reason for doing such is that primarily people just have to edit the CSS file.... if they want to modify the other stuff they can.... I just don't know a better way to do it..

    NOTE: This code is untested!!!
    That an HTML generator class not a Template class. I might do something like this instead:
    PHP Code:
    class HTMLTag {
        function 
    setAttribute($name$value) {}
        function 
    toHTML() {}
    }

    class 
    HTMLTable extends HTMLTag {
        function 
    addRow($row) {}
    }

    class 
    HTMLTableRow extends HTMLTag {
        function 
    addCol($col) {}
    }

    class 
    HTMLTableCol extends HTMLTag {
        function 
    addContent($html) {}

    Christopher

  15. #15
    SitePoint Guru OfficeOfTheLaw's Avatar
    Join Date
    Apr 2004
    Location
    Quincy
    Posts
    636
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    That an HTML generator class not a Template class. I might do something like this instead:
    PHP Code:
    class HTMLTag {
        function 
    setAttribute($name$value) {}
        function 
    toHTML() {}
    }

    class 
    HTMLTable extends HTMLTag {
        function 
    addRow($row) {}
    }

    class 
    HTMLTableRow extends HTMLTag {
        function 
    addCol($col) {}
    }

    class 
    HTMLTableCol extends HTMLTag {
        function 
    addContent($html) {}

    Heh, an html generator. Anyone remember that DOM article on phpPatterns "The Way of the Widget" where Harry used the dom to generate html? I smirked at the idea of using something like that where no designer in my area could ever dream of modifying the html

    Anyway, templating really depends on the skillset of the designer... if you have one of those designers who like their pretty GUI designer and have no clue what <abbr> would be used for, and don't like touching the "html source code" because they're a "graphical person", you may be a little stuck. I used smarty once and the designer complained the site looked completely broken in goLive, and when they edited something it broke it further, same thing with using xsl.

    But designer capabilities aside, I like the XSLT route myself. I've done something where I had a visitor that converted objects to xml, combined it with xsl, and served it up as xhtml. The only drawback I see is there are possible speed issues, which in that case I would suggest just using php as the templating language (since a lot of designers do know a little php to be comfortable with it). Just keep business logic seperated and php as sparse as possible.

    Here would be a good example, say you were generating a table of employees:

    PHP Code:
    <table id="employees">
     <thead>
      <tr>
       <th>Last Name</th>
       <th>First Name</th>
       <th>Department</th>
       <th>Hire Date</th>
      </tr>
     </thead>
     <tbody>
      <?php foreach(Employees::getAllEmployees() as $employee) { ?>
       <tr>
        <td><?php echo $employee->getLastName(); ?></td>
        <td><?php echo $employee->getFirstName(); ?></td>
        <td><?php echo $employee->getDepartment(); ?></td>
        <td><?php echo $employee->getHireDate(); ?></td>
       </tr>
      <?php ?>
     </tbody>
    </table>
    Basically you'd just be doing the same thing that java programmers use JSPs for the output from their servlets. Some may shun the idea of the fact some php code is there, but it is the fastes way with the least overhead imho. With an xml structure of a nodelist of employees, you could write the above as:

    Code:
    <table id="employees">
     <thead>
      <tr>
       <th>Last Name</th>
       <th>First Name</th>
       <th>Department</th>
       <th>Hire Date</th>
      </tr>
     </thead>
     <tbody>
      <xsl:for-each select='/Employees/employee'>
       <tr>
        <td><xsl:value-of select="./lastName"/></td>
        <td><xsl:value-of select="./firstName"/></td>
        <td><xsl:value-of select="./department"/></td>
        <td><xsl:value-of select="./hireDate"/></td>
       </tr>
      </xsl:for-each>
     </tbody>
    </table>
    Basically choose something that best serves your needs, but I really do need to suggest somethng about templates before you go using them. If it's a professional project for a client, you may want to consider using a pre-written templating engine like smarty, WACT's, PEAR::Sigma, or that other framework with a smilin shroom as it's mascot... because writing a templating engine is a project in itself that can very much overshadow the time and effort working on actual business logic, not to mention the documentation you'll need to write for others to use it!

    James Carr, Software Engineer


    assertEquals(newXPJob, you.ask(officeOfTheLaw));

  16. #16
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by OfficeOfTheLaw
    The only drawback I see is there are possible speed issues
    I think xslt has gotten a rumor of being incredibly slow. Surely, with very traffic heavy sites this might become an issue, but aren't we looking at a clearcut case of premature optimizatin here ? Besides - with some caching applied it makes no difference.

    I'd say a more impeding problem of the xml->xslt->xhtml route is that the whole chain has to be wellformed xml to work painlessly. Designers using visual tools such as golive don't like being told that their code should comply to xhtml-strict. And even worse - content might be violating the rules aswell.

  17. #17
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    NOTE: This code is untested!!!
    ... much later ...

    Use it at your peril

  18. #18
    SitePoint Guru
    Join Date
    Sep 2004
    Posts
    613
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No I meant like... the script using it hasn't been tested... there's nothing WRONG with it as far as I can tell ^_^

    This is for my admin area, which is only designed for the colors/basics to be modified...

  19. #19
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Still, you would greatly benefit from using templates, and extracting all that HTML out of your code.
    Garcia

  20. #20
    SitePoint Guru
    Join Date
    Sep 2004
    Posts
    613
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can you show me a good example of a good template? Cause for the front-end of this site we will be using a complete template.

    I need to know what to do with it ^_^

  21. #21
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Webnet
    Can you show me a good example of a good template? Cause for the front-end of this site we will be using a complete template.

    I need to know what to do with it ^_^
    Well I guess something simple might be:
    PHP Code:
    class Template {
        
    $filename '';
        
    $data = array();
        
    $buffer '';

        function 
    Template($filename) {
            
    $this->filename $filename;
        }

        function 
    set($name$value) {
            
    $this->data[$name] = $value;
        }

        function 
    render() {
            if (! 
    $this->buffer) {
                
    $this->buffer file_get_contents($this->filename);
            }
            return 
    str_replace(array_keys($this->data), $this->data$this->buffer);
        }

    Template mytemplate.html:
    Code:
    <html>
    <head>
    <title>^title^</title>
    </head>
    <body>
    ^content^
    </body>
    </html>
    Code
    PHP Code:
    $template = new Template('mytemplate.html');
    $template->set('^title^''My Title');
    $template->set('^content^''My Content');
    echo 
    $template->render(); 
    Christopher

  22. #22
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    the script using it hasn't been tested...
    The first paragraph was indeed in relation to it not being tested, and the second paragraph was in relation as a warning to others, as you are breaking any number of rules , for layering and object oriented good practices.

    Anyways, I eventually calmed down, and on a more serious note I think the suggested Tags approach would be what your looking for. Harry had an example of this on his site, but it's down.

    I tackled this a while back, of which I posted the script but that going back a while now, and I don't have the script at hand. In regards to this approach you can very quickly and easily build a complete page on the fly from Tag components.

    Ie Each Component could be a section of page which has a class that would pre build it for you as you want it, so in that regards, it's just a case of appending it to the web page 'frame'...

    The component is there for you to use, it's already build, so you get re-use, as if the page section changes, you don't need to change the client script which uses it... You just script a new component that is more readily suitable to your needs.

    The reason I no longer use this approach, and this is a major point, is that cause the page is build on the fly, a web designer has little say in the matter, so their role is purely CSS.

    The designer can't change the layout for example, unless they know PHP of course.

  23. #23
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Which is your favourite template engine?

  24. #24
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    When I remember about this, which may interest you, is this library...

    http://phphtmllib.newsblob.com/index.php

    I've searched the forums looking for that thread I know that's there, but not found it yet, so have a look at this and see what you think of it

  25. #25
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    Looks promising.


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
  •