Page 1 of 1
Using a 'template' in PHP
Posted: Sat Oct 07, 2006 2:41 pm
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.
Posted: Sat Oct 07, 2006 5:44 pm
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.
Posted: Sat Oct 07, 2006 6:09 pm
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

Posted: Sat Oct 07, 2006 6:29 pm
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"> </td>
</tr>
</table></td>
</tr>
</table>
<?php include('footer.php'); ?>
<?php }
else
{
?>
</table>
<?php
include('footer.php');
?>
</center>
<?php } ?>
-Steve
Posted: Sat Oct 07, 2006 7:02 pm
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.
The link is in my signature.

Posted: Sat Oct 07, 2006 7:05 pm
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.
Posted: Sat Oct 07, 2006 9:03 pm
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)
Posted: Sat Oct 07, 2006 10:25 pm
by RobertGonzalez
You could use a {foreach} or a {section} and assign the sorce of the var an array.
Posted: Sat Oct 07, 2006 11:21 pm
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.
Posted: Sun Oct 08, 2006 12:37 am
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?
Posted: Sun Oct 08, 2006 1:32 am
by aliasxneo
feyd | Please use 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
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]
Posted: Sun Oct 08, 2006 12:35 pm
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.

Posted: Sun Oct 08, 2006 1:25 pm
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.
Posted: Sun Oct 08, 2006 4:07 pm
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.
Posted: Sun Oct 08, 2006 5:04 pm
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>