Building a Site Engine with PHP, Part 4 - Give it a Little Class: (
Page 3 of 4 )
Now we need to talk about the template plug-in and how it works. This is basically
the only part of the entire engine that makes it only compatible with PHP5 because
we use SimpleXML to parse our XML file. SimpleXML works a lot like your average
PHP class. You simply set simplexml_load_file() to the value of a variable and call a file name with it to load the XML document
into the script, then you use the -> operator to call each element of the XML
file. Here’s a little thing you can do to test out simpleXML. Take the XML example
I showed you earlier and save it as template.xml, then save the following script
to the same directory as test.php.
<?
//load the template.xml file.
$template = simpleXML_load_file(template.xml);
//load the header element as a string
$header = $template->header;
//output the header element
echo $header;
?>
Go ahead and try that, then check the page source in your browser and you’ll
see the exact html that’s in the header element of the template.xml file. Compare
that to trying to make a parser do the same thing in PHP4 and you’ll understand
why it’s called simpleXML. As you can see simplexml_load_file() basically loads the XML file into the $template variable and sets it up as if it’s a class and you call each element as if it
were a class’s variable. Pretty simple isn’t it, hence the name simpleXML. Now
that you know how simpleXML is going to help us load the template file, we’re
going to talk about how to set up or plug-in so that it will easily load your
template file into the engine. So, let’s go ahead and take a look at the class
that handles the template system.
First we start off by defining the class, and all the variables that we plan
on using throughout the engine. $template_list is an array that holds a list of all the templates that we have, this is useful
for listing them out on a page to get information on what templates you have,
without having to look at the database. $cur_template will hold all the information on the template that we’re currently working with.
$loaded is the place holder for the template file after we’ve loaded it with simpleXML.
$elements is an array of all the elements in the XML file that aren’t columns. $columns is the array that will hold (gasp!) the column elements from our template file.
$tags is a rather important variable. It holds all the tags that we use through out
the engine. And last but not least, $page holds the final output of the entire engine that will be sent to the browser.
class template{
public $template_list;
public $cur_template;
public $loaded;
public $elements;
public $columns;
public $tags;
public $page;
The template function has been named the same as the class so that it will run
when we call the class. Basically it builds the list of templates that we can
use with the particular site, from the database. Then we call a few functions
so that those too load when the class is called.
function template(){
global $sql, $site;
$templates = $sql->_query("SELECT t_ID, t_name, t_file, t_status, t_author, t_date
FROM templates WHERE site_ID = '{$site->site['ID']}'");
while($template=$sql->_fetch_object($templates)){
$this->template_list['t_ID'][]=$template->t_ID;
$this->template_list['t_name'][]=$template->t_name;
$this->template_list['t_file'][]=$template->t_file;
$this->template_list['t_status'][]=$template->t_status;
$this->template_list['t_author'][]=$template->t_author;
$this->template_list['t_date'][]=$template->t_date;
}
$this->set_template();
$this->load_template();
$this->tags['host']=$site->site['host'];
}
Set template loads the template that the user has set as the template they want to use as
the $cur_template. If a user_ID isn’t found, it will load the template that has the status that’s
set to “loaded” as the default template.
function set_template(){
global $sql,$user;
if(isset($user->user['ID'])){
$U_ID=$user->user['ID'];
$user_template=$sql->_query("SELECT t_ID FROM template_users WHERE user_ID =
'$U_ID'");
while($user_temp=$sql->_fetch_object($user_template)){
$tempate_key=array_keys($this->template_list['t_ID'],$user_temp->t_ID);
}
}else{
$tempate_key=array_keys($this->template_list['t_status'],"loaded");
}
$this->cur_template['t_name']=$this->template_list['t_name'][$tempate_key[0]];
$this->cur_template['t_file']=$this->template_list['t_file'][$tempate_key[0]];
}
Load_template actually gets all the information from the template’s XML file and breaks it
down into each component. Then it sections them off into the correct array based
on the name of the element. As you can see, if the element’s name isn’t “header”,
“body”, “footer”, or “block”, it will get sent to the column's array because the
function recognizes anything other than those four elements as a column, which
releases you from the regular three column layout and lets you add as many columns
as you’d like. You can have one column or fifty columns if you’d like. There's
also a small amount of error handling put into the function so that if the template
isn’t loaded, you’ll be informed and you can correct the problem, which is usually
a misspelling of a templates name.
function load_template(){
global $site;
if(is_array($this->cur_template)){
if(file_exists("templates/{$site->site['host']}/{$this->cur_template['t_file']}/{$this->cur_template['t_name']}.xml")){
$this->cur_template['template']="templates/{$site->site['host']}/{$this->cur_template['t_file']}/{$this->cur_template['t_name']}.xml";
$this->loaded=simplexml_load_file($this->cur_template['template']);
$elements = array_keys(get_object_vars($this->loaded));
for($i=0;$i<count($elements);$i++){
if($elements[$i]=="header"||$elements[$i]=="body"||$elements[$i]=="footer"||$elements[$i]=="block"){
$this->elements[$elements[$i]]=$this->loaded->$elements[$i];
}else{
$this->columns[$elements[$i]]=$this->loaded->$elements[$i];
}
}
}else{
echo"ERROR Template <b>templates/{$site->site['host']}/{$this->cur_template['t_file']}/{$this->cur_template['t_name']}.xml</b>
Not Found";
}
}else{
echo"ERROR Template Data Not Specified";
}
}
This is the function that we call from the blocks plug-in after we’ve loaded
and sorted all the blocks. It reads the names of each column and matches them
to the array of blocks that have been set by the parse_block() function in the blocks plug-in, then it sends all the information to the tags
array as a single tag which replaces the <!content> tag in the body element.
function build_cols($col_content,$bcolumns){
global $blocks,$plugins;
if(is_array($this->columns)){
$columns_keys=array_keys($this->columns);
foreach($columns_keys as $column){
if(in_array($column,$bcolumns)){
$this->tags['content'].=$this->replace($col_content,$this->loaded->$column);
}
}
}
}
The parse_page function isn’t complicated at all, but it is still very important. It send the
rest of the remaining elements to the replace function to get the tags replaced,
then it puts them to the $page variable which I mentioned above that holds all the data that will be sent to
the browser. And, just as an added amount of security that all our tags get replaced
and to make sure any tags in the block’s loaded content get replaced, we run the
entire $page variable through the replace function before the final output.
function parse_page(){
$this->page.=$this->replace($this->tags,$this->loaded->header);
$this->page.=$this->replace($this->tags,$this->loaded->body);
$this->page.=$this->replace($this->tags,$this->loaded->footer);
return $this->replace($this->tags,$this->page);
}
?>
That’s about it for the template plug-in. Like all the other parts of the engine,
it’s not actually all that complicated if you just take a second to look at it.
| | Discuss Building a Site Engine with PHP, Part 4 | | | | | | | Suddenly the code is no longer indented. Is there a whitespace issue with PHP5 that... | | | | | | I agree, this part 4 was really a disappointment.
Hope the finale is a... | | | | | | I must agree with the above commments.
Since part 3 the quality of the articles has... | | | | | | I hope things gets easier to understand when I've read the full article.
As posted... | | | | | | in article 3: where do I have to put the blocks and authentification plug-ins?
in... | | | | | | IN article 3:
You have code for two different plugins, "auth" and "blocks".
Now... | | | | | | what about the replace() function? where do i have to put it?
... and that... | | | | | | the load_template() function tells you exactly where your xml file... | | | | | | I plan on rewriting this article due to the fact that it's a new writing style... | | | | | | >AND yes, if you read all the articles with attention, you'd know what to do with... | | | | | | First off, I don't consider myself an extremely knowledgeable user of PHP. That... | | | | | | "What are the file names of the Templates and XML plug-ins?"
"... and XML class... | | | | | | It's like trying to plug an episode of Jerry Springer
into Oprah show, they might... | | | | | | Has anyone tried this yet? I know some are dissapointed, but I think that it's... | | | | | | Ok, well Im treating this article as a guide to how to do it. I dont run PHP5 so I... | | | | | | I agree that a download of the sample code would be FANTASTIC. I think that would... | | | | | | Yeah thats pretty much it really, not the hardest thing I'll have done this month... | | | | | | this IS a guide on how to do it, this isn't a "heres the source code for a finished... | | | | | | I would like to thank you for writing these articles, the quality is going down a... | | | | | | I'll say that- it got me thinking. Overall this has been a big eye-opener to me, as... | | | | | | That is great that you the system up and running. Would it be possible for you to... | | | | | | why would the sql function (inside sql.inc.php) not have any arrguments. I couldn't... | | | | | | To get the sql function to work declare $config global in the function sql()... | | | | | | This is my current core.inc.php, shows the changes made to support the sql inc... | | | | | | So maybe you can add source to download ? with all files and mysql dump? | | | | | | Thanks a bunch Simon. That seems to clear it all up. It’s nice to see some progress... | | | | | | Well I made some progress on the parser today, it seems to do what the simpleXML... | | | | | | simon ...wow... only 3 weeks... could you share with us what tutorials/books you've... | | | | | | I'd really like to see a completed source package also. | | | | | | as would I! | | | | | | Well I dont have any PHP books, the online suport at php.net is very good as it is,... | | | | | | a complete working package would be very helpful to understand how it works | | | | | | The author made a comment saying he didn't want this to be a "heres a site download... | | | | | | you read my mind :) | | | | | | I'm studying this articles for a couple of hours and i have a question.
You... | | | | | | Any thoughts on the above comment? | | | | | | I don't think that these articles should be always targeted toward beginners. If you... | | | | | | Exactly, this is a guide, a tutorial. If you just want to download a working CMS,... | | | | | | you can make them yourself in your core.inc.php
this is my... | | | | | | you can write small modules which creates an instance of the plugin
Lets look at... | | | | | | Hi Simon,
Ive been having some problems getting your PHP4 simple xml parser... | | | | | | >>> Post your comment now! | | | | | |
|
 |