Using a 'template' in PHP

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
waradmin
Forum Contributor
Posts: 240
Joined: Fri Nov 04, 2005 2:57 pm

Using a 'template' in PHP

Post by waradmin »

How hard is it to have a designed 'template' that each file you have will work off of? I know most sites do it, yet I cant figure out how they do it for the life of me. It makes sense, that way changes made to the template are global and you do not need to touch each file. But I am wondering if anyone knows of a resource I can look into as to learn how to do 'templates' on php pages.

Thanks in advance.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

There are two common ways (at least common to me):

1. Use includes to parse a header and footer section while your main body is handled by the page you are on.... or;
2. Use a template parser that grabs a single (or multiple) HTML pages and parses them using your page vars.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Have a look at savant template engine

A trivial template engine might do something like the following:

Code: Select all

<!-- Template: test.thtml -->
<html>
  <body>
    <b>{@BODY@}</b>
  </body>
</html>

Code: Select all

$buff = file_get_contents('test.thtml');

// TODO: Pull $body from somewhere like a DB or text file, etc...
$body = 'blank default contents';

$buff = str_replace('{@BODY@}', $body, $buff);

echo $buff; // Echo templated web page to screen
Obviously a very simplified template engine, but it demonstrates the gist of the idea...Savant, Smarty, etc all do a much more thourough job.

Cheers :)
User avatar
waradmin
Forum Contributor
Posts: 240
Joined: Fri Nov 04, 2005 2:57 pm

Post by waradmin »

All of these idea's sound great and I plan to test them out. I am in the process of trying to build a 'for fun' Social networking site that is like Facebook but open-source. Its actualy a project going on at my college with a group of computer science majors (myself included). Heres a screenshot: http://www.my-sn.com/homepage1.gif

Here is the code of a empty file so you can see the general table layout of the whole site. Which system would be best for this? I assume the first one hockey said wouldnt work because this has so many parts. Basicly the page is one big table with 2 colums. The content in column 1 are always the same. The content in colum 2 is the same in row 1 (title image row), row 2 displays the page title, so its dynamic, and then row 3 is where all of the other content is. Every page is layed out like this.

Code: Select all

<?php
//include some stuff
require("inc.php");
$who = $_GET['id'];
if($id == "")
{
	$result = mysql_query("SELECT * FROM loginphp WHERE Uname='{$_SESSION[Uname]}'") or die(mysql_error());
	$row = mysql_fetch_array( $result );
	$goto = $row['global_id'];
	header( 'Location: profile.php?id='.$goto.'' ) ;
	exit();
}
$result = mysql_query("SELECT * FROM loginphp WHERE global_id='$who'") or die(mysql_error());
$num_rows = mysql_num_rows($result);
if($num_rows == 0)
{
	echo "That user ID doesnt exist, please just follow links and don't type in custom user ID's... thank you.";
	echo '<FORM><INPUT TYPE="BUTTON" VALUE="Go Back" 
ONCLICK="history.go(-1)"></FORM>';
	exit();
}
?>
<style type="text/css">
<!--
.style1 {color: #999999}
.style2 {
	color: #3b5998;
	font-weight: bold;
	font-size: 12px;
}
.style3 {
	color: #3b5998;
	font-weight: bold;
}
.style5 {color: #808080}
-->
</style>

<title>Friendbook | <?php $result = mysql_query("SELECT * FROM loginphp WHERE global_id='{$_GET[id]}'") or die(mysql_error());
	$row = mysql_fetch_array( $result );
	echo $row['Fname'];
	echo " ";
	echo $row['Lname'];
	?></title><center><table width="764" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td width="134"><img src="images/left_title_header.gif" alt="face" width="134" height="34" /></td>
    <td width="630"><img src="images/title_bar_bg.gif" alt="title" width="630" height="34" /></td>
  </tr>
  <tr>
    <td style="border-right: 1px solid #d8dfea;" valign="top"><?php include('left_menu.php'); ?></td>
    <td valign="top"><table width="628" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="middle" style="background-color: #6d84b4;"><img src="images/spacer_lower_table_row.gif" alt="spacer" width="7" height="23" hspace="0" vspace="0" align="middle" />
	  <span class="style9">
	  <font color="#FFFFFF">Photos of <?php
	$result = mysql_query("SELECT * FROM loginphp WHERE global_id='$_GET[id]'") or die(mysql_error());
	$row = mysql_fetch_array( $result );
	if ($row['Uname'] == $_SESSION['Uname']) {
		?>
	  You
	  <?php
	}
	else echo $row['Fname']; ?> <?php echo $row['Lname'];
	?></font></span></td>
    <td valign="middle" style="background-color: #6d84b4;"><div align="right">
      <?php include('bar_top.php'); ?>
    </div></td>
  </tr>
</table>
<?php
	  $result = mysql_query("SELECT * FROM loginphp WHERE Uname='{$_SESSION[Uname]}'") or die(mysql_error());
	  $row = mysql_fetch_array( $result );
	  $global_id = $row['global_id'];
	  $result = mysql_query("SELECT * FROM friends WHERE global_id='$_GET[id]' AND friend_global_id='$global_id'") or die(mysql_error());
	  $num_rows = mysql_num_rows($result);
	  if($num_rows >= 1 || $global_id == $_GET['id']) {
	  ?>
      <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td valign="top">&nbsp;</td>
        </tr>
      </table></td>
  </tr>
</table>
  <?php include('footer.php'); ?>
<?php }
else
{
?>
</table>
<?php
include('footer.php');
?>
</center>
<?php } ?>
-Steve
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

Or check out Template Lite as it is one of the fastest and most comprehensive templating engines around with new feature added every release. :D

The link is in my signature. ;)
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

Hockey wrote:Have a look at savant template engine

A trivial template engine might do something like the following:

Code: Select all

<!-- Template: test.thtml -->
<html>
  <body>
    <b>{@BODY@}</b>
  </body>
</html>

Code: Select all

$buff = file_get_contents('test.thtml');

// TODO: Pull $body from somewhere like a DB or text file, etc...
$body = 'blank default contents';

$buff = str_replace('{@BODY@}', $body, $buff);

echo $buff; // Echo templated web page to screen
Obviously a very simplified template engine, but it demonstrates the gist of the idea...Savant, Smarty, etc all do a much more thourough job.

Cheers :)
You do know that even that can be considerably slower than using most other template engines. :) Nasty having to use the str_replace for altering tags in a template file.
User avatar
waradmin
Forum Contributor
Posts: 240
Joined: Fri Nov 04, 2005 2:57 pm

Post by waradmin »

Alright so when looking at template light, it gives the example:

Code: Select all

test.php
	=============================
	require('class.template.php');
	$tpl = new Template_Lite;
	$tpl->compile_dir = "compiled/";
	$tpl->template_dir = "templates/";

	$tpl->assign("foo","bar");
	$tpl->display("test.tpl");

	test.tpl
	=============================
	<html>
	<head>
	<title>Document Title</title>
	</head>
	<body>
	{* this is a comment *}
	{ $foo }
	</body>
	</html>

	output
	=============================
	<html>
	<head>
	<title>Document Title</title>
	</head>
	<body>
	bar
	</body>
	</html>
Now, I assume in test.tpl the template would be setup (HTML elements, etc). Then the { $foo } is where it reads out the $tpl ->assign("foo","bar"); but how would you go about assigning a whole block of PHP code to be set as a { $___ } value. For example, I want to display:

Code: Select all

$result = mysql_query("SELECT * FROM this WHERE id='$_GET[id]'");
$row = mysql_fetch_array( $result );
$num_rows = mysql_num_rows( $result );

$i = 0;
while($num_rows < $i)
{
     echo "Some content here";
     $i++
}
Thanks (template light looks really useful and powerful)
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

You could use a {foreach} or a {section} and assign the sorce of the var an array.
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

You can do what Everah mentioned. There are two other tags you can use { for } and {while} to loop through the array data. These are two tags that are specific to Template Lite.
User avatar
waradmin
Forum Contributor
Posts: 240
Joined: Fri Nov 04, 2005 2:57 pm

Post by waradmin »

Hm. Well because my page is 1 big table divided into sepearate tables, how would I setup the templates to function properly so i need only edit 1 file? As you can see in my code example its a giant table with smaller tables. Would I just call like a header with the first half, and a footer with the bottom closing tags then have a body one that varies based on page?

It seems like i need to learn a new language to use this. I mean can I not set any of my previous code as a variable that can be read by template light?
aliasxneo
Forum Contributor
Posts: 136
Joined: Thu Aug 31, 2006 12:01 am

Post by aliasxneo »

feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


I would just use Smarty. Don't know what this other thing is, but I am in the process of creating a CMS (Content Management System) and I am implementing the smarty tempating engine for it. It's very easy to use, and there are tons of tutorials on it, just google "Smarty Tutorials". Here are some examples from my CMS:

[syntax="smarty"]{include file="core_header.tpl"}


<!-------- Start News Feeding --------------->

{section name=i loop=$feeds}

	<!-------- Start Main Content Box ----------->

	<table width="610" border="0" cellpadding="0" cellspacing="0" background="images/main_box_bg.gif">
	<tr>
	<td background="images/0_05.gif" width="610" height="100"></td>
	</tr>
	<tr>
	<td background="images/0_08.gif" width="610" height="45" style="padding-left:20px;font-weight:bold;color:#FFFFFF;">
	<b><i>{$feeds[i].title}</i></b> by <b>{$feeds[i].author}</b> on <b>{$feeds[i].date}</b>
	</td>
	</tr>
	<tr>
	<td va lign="top" width="610" height="100" style="background-image:url(images/0_09.gif);background-repeat:no-repeat;	padding-left:10px;padding-right:12px;font-weight:normal;color:#333333;font-family:Veranda;font-size:14px;">
	{$feeds[i].content}
	</td>
	</tr>
	<tr>
	<td background="images/0_13.gif" height="13" width="610"></td>
	</tr>
	</table>
	
	<!-------- End Main Content Box ----------->

{/section}

<!-------- End News Feeding --------------->


{include file="core_footer.tpl"}
Then I simply had my header and footer coding in the proper files. It makes it simple and clean because I can use the header and footer over and over again, and change the structure of my entire page on runtime. I'm not going to explain any further, but if you're interested just google "Smarty".


feyd | Please use[/syntax]

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

aliasxneo wrote:I would just use Smarty. Don't know what this other thing is...
This "other thing" is a faster, smaller, better written Smarty compatible template engine that has a few more templating features. :D
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

TemplateLite is a better, cleaner rewrite of Smarty. It doesn't require any knowledge of a new language as long as you know PHP. But you should have some ability to form the logic of separating your page into sections for inclusion before using anything (even PHP includes for that matter). Basically you find the parts of your page that change and make the body that part. The part above becomes a header and the part below becomes a footer. This is not a comprehensive logical recommendation, but should at least offer some sort of logical process by which you can determine the best way at separating your HTML into sections.
User avatar
waradmin
Forum Contributor
Posts: 240
Joined: Fri Nov 04, 2005 2:57 pm

Post by waradmin »

How would say:

Code: Select all

$result = mysql_query("SELECT * FROM this WHERE id='$_GET[id]'");
$row = mysql_fetch_array( $result );
$num_rows = mysql_num_rows( $result );
this get represented in Template Lite? I understand all of the PHP, but as far as converting it into the 'template lite' code I get completely lost.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Code: Select all

<?php
$result = mysql_query("SELECT * FROM this WHERE id='$_GET[id]'");
$row = mysql_fetch_array( $result );
$num_rows = mysql_num_rows( $result );

$tpl->assign(array(
    'recordset' => $row,
    'recordcount' => $num_rows)
);
?>

Code: Select all

<html>
<head></head>
<body>
{foreach key=arraykey value=arrayvalue from=$recordset}
<p>{$arrayvalue}</p>
{/foreach}

<!-- OR YOU COULD USE A SECTION TAG -->

{section name=rs loop=$recordset}
<p>{$recordset[rs].record_name}</p>
{/section}
</body>
</html>
Post Reply