HOWTO: Write Cleaner tpl.php Files

1

April 27, 2007 - 1:03am

The PHPTemplate system in Drupal is a powerful theming system. However, because it is written in PHP it is easy to abuse since it is possible to directly inject PHP logic into the templates. This often creates the effect of HTML-IN-PHP which is not good.

HTML-IN-PHP:

<span style="color: #000000"><span style="color: #0000BB"><?php<br /> </span><span style="color: #007700">print </span><span style="color: #DD0000">'<h2 class="title">'</span><span style="color: #007700">. </span><span style="color: #0000BB">$title </span><span style="color: #007700">.</span><span style="color: #DD0000">'</h2>'</span><span style="color: #007700">; <br /></span><span style="color: #0000BB">?></span></span>

PHP-IN-HTML:

<h2 class="title"><br /><span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">print </span><span style="color: #0000BB">$title ?></span></span><br /></h2>

Which do you think a themer who understands HTML/CSS will understand better? Of course the second, because it is mostly HTML and the themer can modify the HTML tags quite easily.

Conditional Statements

Another example of this is with logic statements.

HTML-IN-PHP:

<span style="color: #000000"><span style="color: #0000BB"><?php <br /></span><span style="color: #007700">global </span><span style="color: #0000BB">$user</span><span style="color: #007700">;<br />if (</span><span style="color: #0000BB">$user</span><span style="color: #007700">-></span><span style="color: #0000BB">uid</span><span style="color: #007700">) { </span><span style="color: #0000BB">?></span></span><br /><br /><h2 class="title">You are now logged in!</h2><br /><br /><span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">} </span><span style="color: #0000BB">?></span></span>

PHP-IN-HTML

<span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">global </span><span style="color: #0000BB">$user</span><span style="color: #007700">; </span><span style="color: #0000BB">?></span></span><br /><span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">if (</span><span style="color: #0000BB">$user</span><span style="color: #007700">-></span><span style="color: #0000BB">uid</span><span style="color: #007700">): </span><span style="color: #0000BB">?></span></span><br /><br /><h2 class="title">You are now logged in!</h2><br /><br /><span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">endif; </span><span style="color: #0000BB">?></span></span>

See how the second example is easier to read? It's also broken up into small pieces that a themer can move around quite easily. Having open and closing braces for an if statement is really hard to follow. But if(conditional): and endif; statements are easy to read, and "chunkify" or "modularize" the text in a clear way.

<span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">if (</span><span style="color: #0000BB">$test </span><span style="color: #007700">== </span><span style="color: #0000BB">TRUE</span><span style="color: #007700">): </span><span style="color: #0000BB">?></span></span> <br /><br /><!-- Block of HTML to printout if TRUE --><br /><br /><span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">endif; </span><span style="color: #0000BB">?></span></span>

PHPTemplate variables

The last thing that can make your life and the themer's life easier is to pass variables to the template files using phptemplate_variables. A tpl.php really should be mostly simple conditional statements and print statements. If you have PHP code spanning multiple lines or are working with arrays or something, you can probably pull that code out of the tpl.php and put it in template.php.

Example Node.tpl.php with too much PHP

<span style="color: #000000"><span style="color: #0000BB"><?php<br /></span><span style="color: #007700">if (</span><span style="color: #0000BB">$node</span><span style="color: #007700">-></span><span style="color: #0000BB">field_related</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][</span><span style="color: #DD0000">'nid'</span><span style="color: #007700">]) {<br />  </span><span style="color: #0000BB">$related_cck_node </span><span style="color: #007700">= </span><span style="color: #0000BB">node_load</span><span style="color: #007700">(</span><span style="color: #0000BB">$node</span><span style="color: #007700">-></span><span style="color: #0000BB">field_related</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][</span><span style="color: #DD0000">'nid'</span><span style="color: #007700">]);<br />  print </span><span style="color: #DD0000">'<div class="related-cck-link">'</span><span style="color: #007700">;<br />  print </span><span style="color: #0000BB">l</span><span style="color: #007700">(</span><span style="color: #0000BB">$related_cck_node</span><span style="color: #007700">-></span><span style="color: #0000BB">title</span><span style="color: #007700">, </span><span style="color: #DD0000">'node/' </span><span style="color: #007700">. </span><span style="color: #0000BB">$related_cck_node</span><span style="color: #007700">-></span><span style="color: #0000BB">nid</span><span style="color: #007700">);<br />  print </span><span style="color: #DD0000">'</div>'</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?></span></span>

Why is all that logic in the tpl.php? You can move that out into template.php.

Using Template.php to add variables to your tpl.php files

<span style="color: #000000"><span style="color: #0000BB"><?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">_phptemplate_variables</span><span style="color: #007700">(</span><span style="color: #0000BB">$hook</span><span style="color: #007700">, </span><span style="color: #0000BB">$vars </span><span style="color: #007700">= array()) {<br />  switch(</span><span style="color: #0000BB">$hook</span><span style="color: #007700">){<br />    case </span><span style="color: #DD0000">'node'</span><span style="color: #007700">:<br />      if (</span><span style="color: #0000BB">$vars</span><span style="color: #007700">[</span><span style="color: #DD0000">'node'</span><span style="color: #007700">]-></span><span style="color: #0000BB">field_related</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][</span><span style="color: #DD0000">'nid'</span><span style="color: #007700">]) {<br />        </span><span style="color: #0000BB">$related_cck_node </span><span style="color: #007700">= </span><span style="color: #0000BB">node_load</span><span style="color: #007700">(</span><span style="color: #0000BB">$vars</span><span style="color: #007700">[</span><span style="color: #DD0000">'node'</span><span style="color: #007700">]-></span><span style="color: #0000BB">field_related</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][</span><span style="color: #DD0000">'nid'</span><span style="color: #007700">]);<br />        </span><span style="color: #0000BB">$vars</span><span style="color: #007700">[</span><span style="color: #DD0000">'related_cck_link'</span><span style="color: #007700">] = </span><span style="color: #0000BB">l</span><span style="color: #007700">(</span><span style="color: #0000BB">$related_cck_node</span><span style="color: #007700">-></span><span style="color: #0000BB">title</span><span style="color: #007700">, </span><span style="color: #DD0000">'node/' </span><span style="color: #007700">. </span><span style="color: #0000BB">$related_cck_node</span><span style="color: #007700">-></span><span style="color: #0000BB">nid</span><span style="color: #007700">);<br />      }  <br />      break;<br />  }<br />  return </span><span style="color: #0000BB">$vars</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?></span></span>

Now the node.tpl.php file will get a new variable called $related_cck_link which you can easily print out.

Example Node.tpl.php file with logic removed

<span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">if (</span><span style="color: #0000BB">$related_cck_link</span><span style="color: #007700">): </span><span style="color: #0000BB">?></span></span><br />  <div class="related-cck-link"><br />    <span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">print </span><span style="color: #0000BB">$related_cck_link ?></span></span><br />  </div><br /><span style="color: #000000"><span style="color: #0000BB"><?php </span><span style="color: #007700">endif; </span><span style="color: #0000BB">?></span></span>

Comments

I'm building out a site using views and gmaps. I have three tabs on the info window and need different info from the node to populate the tabs.

I think this will point me in the right direct if it will work with views as well

as a node.

Thank you,

Evo/

Post a comment

To prevent automated spam submissions leave this field empty.
CAPTCHA
Let us know you're human by typing in this code. The code is case sensitive.
Image CAPTCHA
Enter the characters shown in the image.