Page 1 of 3

Dynamic content and templating

Posted: Fri Aug 26, 2005 4:54 am
by Ree
I'm having some questions once again, this time regarding templating. I'm very new to this, please have it in mind :).

Currently I have a simple class which basically replaces all tags (eg, {Message}, {Title}) in html templates with indicated values. Well, that's very simple, but what about more sophisticated dynamic content? Currently for dynamic content, I also have {} tags. For example, for a list of db records, I use {List} tag, which is replaced with HTML which is produced by a PHP file which looks like this:

Code: Select all

<div id="record_container" class="med_bg">
  <form method="post" action="../process/news.php?do=delete">
    <table>
      <tr>
        <th>Headline</th>
        <th class="padding_side">Posted</th>
        <th>&nbsp;</th>
      </tr>
      <?php

      while ($row = $rs->NextRow())
      {
        echo '<tr><td><a href="view_news.php?item=' . $row['id'] . '">' . $row['headline'] . '</a></td>';
        echo '<td class="padding_side">' . $row['date'] . '</td>';
        echo '<td><input type="checkbox" name="item_array[]" value="' . $row['id'] . '" /></td></tr>';      
      }
      
      ?>
      <tr>
        <td colspan="3"><input type="submit" value="Delete Selected" /></td>
      </tr>
    </table>
  </form>
</div>
I use output buffer to take the HTML produced and then replace {List} tag with it in the final page.

I am not happy with this approach, because the HTML formatting IS inside a PHP file, when most of other HTML is in simple .htm files with {} tags. So, in my case, if I wanted to change HTML design of the site, I would have no prob with static .htm templates, but I WOULD need to go and dig the dynamic content generating .php files to change HMTL there as well. Not that good for myself, for others even more so.

So my question is, how do you implement dynamic content in templating class? I would really like to make my own templating class, for better understanding of things, just I'm having some difficulties right now.

Would like to hear your input on the same.

Posted: Fri Aug 26, 2005 6:56 am
by feyd
several template engines use a "block" marker comment that when the template file is opened, they are pulled out (comments and whatever's stored inside). During set up, the engine will fill an array with relating information to that block. The block is then iterated over during output doing a replacement run on the block stored from the template with respect to the variables know to that block. Here's an example template snippet:

Code: Select all

<html>
  <head>
    <title>weeee</title>
<!-- [BLOCK:BEGIN] META -->    <meta {META.S_TAGNAME}="{META.S_TAGVALUE}" {META.S_ATTRIBUTE}="{META.S_ATTRIBUTEVALUE}" />
<!-- [BLOCK:END] META -->

Posted: Fri Aug 26, 2005 9:15 am
by nielsene
I've never liked templating, thought I know its popular.

I'ld probably tackle this problem differently than feyd suggested and more along a custom tag approach.

instead of coming up with several block tags to deal with, I'ld have a {{news_list}} tag. This tag would handle the entire loop and would ask a "view helper" of some kind for the needed result set. Thus the template stays pure.

You could search for tutorials on "JSP Custom Tags" or books on JSP (I like the O'Reilly one) to see how the Java world handles this method of templating.

Posted: Fri Aug 26, 2005 2:30 pm
by feyd
yeah, given the choice, I'd be building a totally different system. In fact, I am. Totally XML driven application building. Builds dynamic EXE's for *nix, Windows, Mac; builds php for the web, totally XHTML 1.1, cross browser blah blah..

Anyways, I've done the template thing, and as hinted at, was too limited in scope :)

Posted: Sat Aug 27, 2005 1:14 pm
by McGruff
One problem with replacing something like { list } with a whole block of html is that a designer working with Dreamweaver etc can't do anything with it. Perhaps there is another template fragment somewhere with the { list } formatting which they can edit but that's awkward. Ideally, they want to edit the page as a whole, all from one file. You really need to see how all the page elements bounce off each other.

You can create templates along these lines, using custom tags (invisible to Dreamweaver) to mark out the structure of the dynamic content:

Code: Select all

<foo-list>
<header><h2><value>Foo Header</value></h2></header>
<ul>
    <item><li><value>foo</value></li></item>
    <jabber>
    <li>bar</li>
    <li>quark</li>
    <li>strangeness</li>
    <li>charm</li>
    </jabber>
</ul>
</foo-list>
This implies a "parsing" stage where tags in the finished template are replaced with php echo calls, loops & simple conditionals. This, compiled, template is the one that would be used to respond to http requests.

The tags provide information required by the parser - you can probably think of better ones to use. "Jabber" for example will simply be ignored - this allows the designer to pad out a sample layout to get a better idea how it will fit in with the rest of the page. In the compiled template, php will loop through a result set echoing values in whatever formatting you defined in the <item> tags - <li> here. A designer can easily change this to a table as opposed to a list.

Often you will have shared layout elements - headers, footers etc. These can be managed with a Dreamweaver (etc) library with the main php code simply gathering up sets of data without any knowledge of how it's going to be laid out.

Posted: Sat Aug 27, 2005 1:28 pm
by nielsene
Agreed, sorry I gave a bad example. I do prefer the custom tags like JSP's would use so they are still moderately friendly to HTML editors.

Posted: Thu Sep 01, 2005 4:05 am
by Ree
Do I understand it correctly: the guy in Dreamweaver would see the output of this html, right?

Code: Select all

<h2>Foo Header</h2>
<ul>
    <li>foo</li>
    <li>bar</li>
    <li>quark</li>
    <li>strangeness</li>
    <li>charm</li>
</ul>
The template engine would have to find <foo-list> tag, replace anything that is within <value></value> of <header> tag with some value, and then generate a lot of <li>'s in a loop by replacing anything that is within <value></value> of <item> tag with the values from result set. The engine won't use <jabber> at all. Is that correct?

Posted: Thu Sep 01, 2005 6:02 am
by McGruff
Yes. Dreamweaver will just ignore tags which it doesn't recognise.

You can figure out your own scheme but the basic idea is to mark out the looped element and mark out the places where dynamic data will be substituted. Tags & html are replaced with php & html.

Posted: Thu Sep 01, 2005 6:34 am
by Ree
Hm... I am not sure about implementing the same. Since the dynamic content would differ from page to page (site to site), does that mean I would need to code custom functions for each of them? I wonder if there's a way to 'standardize' the functions so that they could generate different dynamic content blocks?

Posted: Thu Sep 01, 2005 9:27 am
by nielsene
The custom tag method does tend to require lots of custom tags. Sometimes you can get away with a few generic "list" tags, where you have an attribute that is the name of an array, and it'll turn it into a list. Or a "hyperlinked list" that will take an array of arrays and make links, etc. However, its been my experience that trying too hard to limit the number of custom tags isn't worth it. Your code only ends up being harder and harder to understand.

Re: Dynamic content and templating

Posted: Thu Sep 01, 2005 11:30 am
by Christopher
Ree wrote:I am not happy with this approach, because the HTML formatting IS inside a PHP file, when most of other HTML is in simple .htm files with {} tags. So, in my case, if I wanted to change HTML design of the site, I would have no prob with static .htm templates, but I WOULD need to go and dig the dynamic content generating .php files to change HMTL there as well. Not that good for myself, for others even more so.

So my question is, how do you implement dynamic content in templating class? I would really like to make my own templating class, for better understanding of things, just I'm having some difficulties right now.

Would like to hear your input on the same.
I don't see the problem with putting PHP into your templates as you have done. The loop is presentation logic and you have maintained separation so it is a reasonable design. As you said you use an embedded tag type template for you other pages then adding blocks to your templates would be the way for you to go. You would embed block markers like <!--{myblock}--> or <block name="myblock">There are a number of classes around that you can use as examples for this.

Posted: Thu Sep 01, 2005 2:22 pm
by Ree
nielsene, I'm not sure you understood me correctly. What I'm trying to understand is this. Say, for one site you need to generate a table with 3 columns to list some products in the db, and for another, it is required to generate a table with 1 column only to list services. Having in mind we use custom tags, will I have to create different table generating functions for each case (because the tables are different)? If so, that would mean I will not be able to create a universal templating engine to suit my needs for any case, because all cases are different in some way or another. But I can't believe there's no way to create methods that would apply to all table cases, list cases etc.

Posted: Thu Sep 01, 2005 2:46 pm
by Christopher
I often a renderArray() method to my template code that iterates over an array of rows and renders a template or block for each row. That allows your code not to have to know about the fiield names.

Posted: Thu Sep 01, 2005 3:11 pm
by McGruff
The template compiler would turn the example above into something like this:

Code: Select all

<h2><?php echo $table_title; ?></h2>
<ul>
    <?php
    while($foo = $foos->fetch()) {
        echo "<li>$foo</li>";
    }
    ?>
</ul>
The table formatting is independent of the number of rows so if there is just one row in $foos, that's all that prints. You're right though: you'll need to think a bit how to make nice, re-usable template code.

Posted: Thu Sep 01, 2005 3:40 pm
by Ree
If I get it right, from your code snippet the

Code: Select all

<li>$foo</li>
corresponds to

Code: Select all

<item><li><value>foo</value></li></item>
That means you would have to read <li> tag (with any attributes it may have) from the template, so that you could place it in your loop echo. So, if some designer put

Code: Select all

<item><li class="some_class"><value>foo</value></li></item>
your echo would look like this

Code: Select all

echo '<li class="some_class">$foo</li>';
Right?