Advanced PHP Templating (Maybe)
Posted: Sat Mar 19, 2011 10:15 pm
				
				All right, so it's been a while since I've logged in here and posted... But I have been lurking over the past year or so. ^^ Now, when I first signed up for the forums here, I posted a very basic templating tutorial. I have since looked around online at how other popular PHP application handle templating, and decided to opt for using the PHPbb system. So I wrote my own template class based on this. Here is an example of it:
I love using templating in PHP. I encourage everyone to at least look into it. If you aren't sure about what templating does, it just separates your PHP code from your HTML code, making things a lot less cluttered and easy to navigate. It also allows you to switch between multiple "styles" for your site, without touching the PHP side of things.
Anyway. The above code is a templating class I have written. I defined the constant "STYLE" at the top of the script, before the template class; usually you will do this in a configuration file, or store it in your database. I just put it in the template file for this example.
The template class itself takes 1 argument: this is the name of the HTML file you want to display to the user. All of my template files are given the file extension .tpl instead of .html, but they are just HTML files inside. So the template class takes the name of the HTML file, and gets the destination for it on the server, then stores this in the private variable Url, like so:
You can change this depending on where you are storing your template files.
The next function in the class is where things get a little complex.
This function assigns a variable to your template class. You need to do this for every variable that you want to display on the final page, but it is made a lot easier than it sounds! Why do you need to do it? Well. Any variable declared in the main section of your PHP script cannot be accessed by the template class; unless they are explicitly passed TO the template class, that is. So that's why we have our AssignVal function.
Now, AssignVal can take either an array of values, or a single value, and puts them into the private array $this->Vars. So now our template can (almost) see our variables! Yay!
Now for the final function, Output. This is where it all comes together.
The output function checks how many variables we have stored in $this->Vars. If we have any variables stored here, then it is going to call a cool little PHP function called "extract". Extract just takes everything that is in our array (Vars), and puts them into their own variables. For example:
And so on for every variable. So now our template file can access them just by using $Username or $Title, instead of $this->Vars['Username'] etc.  The very last piece of code in the template class checks if the template file specified actually exists, and if it does, then it uses the include function to output it to the user. DONE!
 The very last piece of code in the template class checks if the template file specified actually exists, and if it does, then it uses the include function to output it to the user. DONE!
Now we can write a HTML template. Here is the example template I wrote up for this tutorial:
Isn't that much easier than having MySql queries and whatnot clutted in amongst our nice HTML? Of course, you can use some if statements in your HTML, like this:
However, I stay away from using PHPs echo or print functions to output ANY HTML tags. That kind of ruins the idea of seperating HTML and PHP. So here is an example of the templating class assigning some variables, and outputting them through that ^^^^ example template.
PHP CODE:
TEMPLATE FILE (index.tpl):
RESULT IN BROWSER:

As you can see, it changed the title of the page to Templating Test, and outputted "Neil" as the username, as those are the values we assigned to the templating class. ^_^
I hope this tutorial is somewhat useful... I just realized how ridiculously long it is, so I'm not sure if I feel up to going back and proof reading it, haha. I have used this templating method for a text based MMO, so it does work for that. Just make templates for you different locations: eg. bank.tpl, fight.tpl, and so on.
 Just make templates for you different locations: eg. bank.tpl, fight.tpl, and so on.
Feel free to use/modify/redistribute my source code. Post a reply if you have any questions, but hopefully I explained everything well enough.
			Code: Select all
<?php
define ('STYLE', 'default');
class Template {
	private $Url, $Vars;
	
	public function __construct($Page) {
		$this->Url = 'styles/' . STYLE . '/template/' . $Page . '.tpl';
	}
	
	public function AssignVal($Variable, $Value = null) {
		if(is_array($Variable)) {
			foreach($Variable as $Key => $Value) {
				$this->Vars[$Key] = $Value;
			}
		} else {
			$this->Vars[$Variable] = $Value;
		}
	}
	
	public function Output() {
		if(count($this->Vars) > 0) {
			extract($this->Vars);
		}
		
		if (file_exists($this->Url)) {
			include($this->Url);
		}
	}
}
$Template = new Template('index');
$Template->AssignVal(array(
		'Title' => 'Templating Test!',
		'Username' => 'Neil'
));
$Template->Output();
Anyway. The above code is a templating class I have written. I defined the constant "STYLE" at the top of the script, before the template class; usually you will do this in a configuration file, or store it in your database. I just put it in the template file for this example.
The template class itself takes 1 argument: this is the name of the HTML file you want to display to the user. All of my template files are given the file extension .tpl instead of .html, but they are just HTML files inside. So the template class takes the name of the HTML file, and gets the destination for it on the server, then stores this in the private variable Url, like so:
Code: Select all
$this->Url = 'styles/' . STYLE . '/template/' . $Page . '.tpl';The next function in the class is where things get a little complex.
Code: Select all
public function AssignVal($Variable, $Value = null) {
      if(is_array($Variable)) {
         foreach($Variable as $Key => $Value) {
            $this->Vars[$Key] = $Value;
         }
      } else {
         $this->Vars[$Variable] = $Value;
      }
   }
Now, AssignVal can take either an array of values, or a single value, and puts them into the private array $this->Vars. So now our template can (almost) see our variables! Yay!
Now for the final function, Output. This is where it all comes together.
Code: Select all
	
public function Output() {
		if(count($this->Vars) > 0) {
			extract($this->Vars);
		}
		
		if (file_exists($this->Url)) {
			include($this->Url);
		}
	}
Code: Select all
$this->Vars['Username'] becomes $Username
$this->Vars['Title'] becomes $Title
 The very last piece of code in the template class checks if the template file specified actually exists, and if it does, then it uses the include function to output it to the user. DONE!
 The very last piece of code in the template class checks if the template file specified actually exists, and if it does, then it uses the include function to output it to the user. DONE!Now we can write a HTML template. Here is the example template I wrote up for this tutorial:
Code: Select all
<html>
<head>
<title>
	<?php echo $Title ?>
</title>
</head>
<body>
	Hello, <?php echo $Username ?>!
</body>
</html>
Code: Select all
<html>
<head>
<title>
	<?php echo $Title ?>
</title>
</head>
<body>
        <?php if ($LoggedIn == true): ?>
	Hello, <?php echo $Username ?>!
        <?php endif; ?>
</body>
</html>
PHP CODE:
Code: Select all
$Template = new Template('index');
$Template->AssignVal(array(
		'Title' => 'Templating Test!',
		'Username' => 'Neil'
));
$Template->Output();
Code: Select all
<html>
<head>
<title>
	<?php echo $Title ?>
</title>
</head>
<body>
	Hello, <?php echo $Username ?>!
</body>
</html>

As you can see, it changed the title of the page to Templating Test, and outputted "Neil" as the username, as those are the values we assigned to the templating class. ^_^
I hope this tutorial is somewhat useful... I just realized how ridiculously long it is, so I'm not sure if I feel up to going back and proof reading it, haha. I have used this templating method for a text based MMO, so it does work for that.
 Just make templates for you different locations: eg. bank.tpl, fight.tpl, and so on.
 Just make templates for you different locations: eg. bank.tpl, fight.tpl, and so on.Feel free to use/modify/redistribute my source code. Post a reply if you have any questions, but hopefully I explained everything well enough.
