Dynamic content and templating

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Dynamic content and templating

Post 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.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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 -->
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post 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.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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 :)
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post 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.
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post 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.
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Post 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?
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post 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.
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Post 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?
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post 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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Dynamic content and templating

Post 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.
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Post 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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post 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.
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post 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.
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Post 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?
Post Reply