Web Design Forum: beginner: simple templating system? - Web Design Forum

Jump to content

WDF
WDF Premium Memberships Reseller Hosting
Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

beginner: simple templating system?

#1 User is offline   Fulmar 

  • Forum Newcomer
  • Pip
  • Group: Members
  • Posts: 3
  • Joined: 26-January 12
  • Reputation: 0

  Posted 26 January 2012 - 04:19 PM

Hello, I am new to web design, so consider me a beginner. I have learn't some basic HTML and CSS and I am working on a simple 8 page or so website for a friend (using a html text editor). My question may be obvious or have been asked a few times before, but I simply can't find a simple answer.

On the website I'm working on, there are a few common features to each page i.e. nav bar, footer, banner. But if I need to make a change e.g. add a link to the nav bar... then I have to edit the html of every single webpage..

So, in a nutshell, my question is: Is there a simple way to only make the change once and it automatically reflect throughout every other page in the website.

Thanks in advance.

Matt
0

#2 User is offline   FizixRichard 

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 325
  • Joined: 05-October 07
  • Reputation: 47
  • Gender:Male
  • Location:Market Deeping, England
  • Experience:Advanced
  • Area of Expertise:Web Designer

Posted 26 January 2012 - 06:05 PM

There are a few ways to do it, they all have their benefits and drawbacks. I personally developed my own, based originally off of google searches for developing a template engine.

I'll assume you have some PHP knowledge and aren't a complete beginner, seeing as you are asking about template engines. If this goes over your head I'll gladly explain it, or you can discard it as "eek".


I'll show you a simplified example of mine, you'll have a few classes, you don't really need to know how they work as such, just use them. Though I'll explain them to some extent.


So here goes, I don't think this is too complex, its a pretty basic OO application framework for websites, really basic as I've just simplified the skeleton.

But it is Object Orientated.



So you have your root script (i.e. index.php) and then an initialization script which is included, which sets up your database and such.


Here are the scripts you'll need to create:

index.php (this is your page if you like)
global.php (this is your initialization script)
./includes/config.php (this holds your database configuration settings)
./includes/class_core.php (this holds your websites core functions)
./includes/class_mysql.php (this holds your database functions, to connect, query etc.)
./includes/class_template.php (this is the template engine)


I'll show you the code for each

Starting with index.php

<?php
// -------------------------------------------------------------------------------------------------------
// Require Application Backend
// -------------------------------------------------------------------------------------------------------
// This is your global initialization script
require_once('./global.php');


... The code for the script goes here, I'll show you how to output a template generated page in a moment ...


// End of Script

?>




Now global.php is your initialization script, you will call this in every script (i.e. index.php, about.php). You could also use a bootstrap but we don't want to overload you.

global.php:
<?php


// Set the current working directory
define('CWD', (($getcwd = getcwd()) ? $getcwd : '.'));


// -------------------------------------------------------------------------------------------------------
// Require Application Core (these are classes in the includes folder
// -------------------------------------------------------------------------------------------------------
require_once('./includes/class_core.php');				// The application core
require_once('./includes/class_database.php');			// The database class
require_once('./includes/class_template.php');			// Template Engine Class



// Initialize the application (so we can access functions in the class_core.php script, from $appCore like this:
// $appCore->function_name()
$appCore = new appCore();


// Fetch your database configuration
$appCore->fetch_config();



// Instantiate your database (so we can use functions in the class_database.php script using $db)
$db = new appDatabase();


?>




Now the config.php file, this is just a script that has some variables in it, that you set to your databases connection settings.

<?php

// config.php

$config['database']['type'] = 'mysql';
$config['database']['host'] = 'localhost';
$config['database']['port'] = '3306';
$config['database']['name'] = 'databasename';
$config['database']['username'] = 'username';
$config['database']['password'] = 'password';
?>



Now, the class_core.php script, only has one thing in it, a function to fetch those configuration settings

<?php

// This is the application core class
class appCore 
{
	// ---------------------------------------------------------------------------------------
	// Declare variables
	public $config;						// Holds the database config settings
	public $templatecache;				// Holds a cache of our templates
	
	
	// ---------------------------------------------------------------------------------------
	// fetch_config()
	// Fetches your database configuration settings
	// ---------------------------------------------------------------------------------------	
	public function fetch_config()
	{
		// create the config array
		$config = array();
		
		// Get the configuration file
		include(CWD . '/includes/config.php');

		// Check size of config file
		if (sizeof($config) == 0)
		{
			echo("config.php does not exist");
			exit;
		}


		// Put the contents of config.php into the config array
		$this->config =& $config;
		
	
		return 0;
	}
}


?>



The class_database.php script just contains some functions for interfacing with the database:

<?

class appDatabase
{
	// Some variables
	private $connect;			// Holds the connection result
	private $select_db;			// Holds the DB selection result
	private $sql;				// Holds the SQL string to process in a query
	private $result;			// Holds the result of a query
	private $row;				// Holds records of data from the DB
	private $id;				// Holds the ID from an insert
	private $rowcount;			// Holds the number of rows a query results
	
	
	
	// -------------------------------------------------------------------
	// Constructor
	// -------------------------------------------------------------------
	// Construct the class (when we instantiate the class, this is called automatically
	public function __construct() 
	{  
		// Open the DB Connection
		$this->open_connection();

	}
	
	
	// To prevent cloning
	private function __clone() {}
	
	
	
	// -------------------------------------------------------------------
	// open_connection()
	// -------------------------------------------------------------------
	// Opens the database connection and selects the database
	public function open_connection()
	{
		global $appCore; // This is strictly speaking bad, but for simplicity we will do it this way
		// Basically that global, allows us to interface with the appCore (its what we set in the global.pgp script)
		
		$this->connect = mysql_connect($appCore->config['database']['host'], $appCore->config['database']['username'], $appCore->config['database']['password']) or die(mysql_error());
		$this->select_db = mysql_select_db($appCore->config['database']['name']) or die("Could not select Database");
	}
	
	
	// -------------------------------------------------------------------
	// close_connection()
	// -------------------------------------------------------------------
	// Closes the database connection
	public function close_connection()
	{
		mysql_close($this->connect);
	}
	
	
	
	// -------------------------------------------------------------------
	// query()
	// -------------------------------------------------------------------
	// Query the database
	public function query($sql)
	{
		global $querycount, $querylist;
				
		$this->result = mysql_query($sql) or die(mysql_error() . "<br />SQL: $sql");

		
		return $this->result;
	}
	
	
	// -------------------------------------------------------------------
	// escape_var()
	// -------------------------------------------------------------------
	// Escapes a Variable that will be used in a query
	public function escape_var($var)
	{
		$var = mysql_real_escape_string($var);
		
		return $var;
	}
	
	
	
	// -------------------------------------------------------------------
	// row_count()
	// -------------------------------------------------------------------
	// Returns the number of records from a query
	public function row_count($result)
	{
		$this->rowcount = mysql_num_rows($result);
		
		return $this->rowcount;
	}
	
	
	
	// -------------------------------------------------------------------
	// fetch_array()
	// -------------------------------------------------------------------
	// Returns the record array for a query
	public function fetch_array($result)
	{
		$this->row = mysql_fetch_array($result);
		
		return $this->row;
	}
	
	
	
	// -------------------------------------------------------------------
	// fetch_object()
	// -------------------------------------------------------------------
	// Returns the object for a query
	public function fetch_object($result)
	{
		$this->row = mysql_fetch_object($result);
		
		return $this->row;
	}
	
	
	
	// -------------------------------------------------------------------
	// insert_id()
	// -------------------------------------------------------------------
	// Returns the insert_id for the last query
	public function insert_id()
	{
		$this->id = mysql_insert_id();
		
		return $this->id;
	}
	
	
	// -------------------------------------------------------------------
	// real_escape_string()
	// -------------------------------------------------------------------
	// Performs a real_escape_string() on the passed value
	public function real_escape_string($value)
	{
		$value = mysql_real_escape_string($value);
		
		return $value;
	}
}
?>




Now for the complicated one, the template engine... This uses some static methods, so we don't need to instantiate it like we did the other classes.

<?php

// -------------------------------------------------------------------
// template class
// -------------------------------------------------------------------
// Template Engine Class
class appTemplate
{		
	private $template = '';							// Template to render			@var string
	private static $pre_registered = array();		// Preregistered vars			@var array (mixed)  (template_name = array(key=>variable))
	private $registered = array();					// Registered variables			@var array
	private static $type = "template";				// We can use this if there are different types of template
	
	
	
	// -------------------------------------------------------------------
	// create()
	// -------------------------------------------------------------------
	// Creates a template object and registers any preregistered vars.
	public static function create($template_name, $type="template")
	{
		self::$type = $type;
		
		
		// Create new template object
		$template = new appTemplate($template_name);

		// If pre_registered
		if (isset(self::$pre_registered[$template_name]))
		{
			$template->multi_register(self::$pre_registered[$template_name]);
			unset(self::$pre_registered[$template_name]);
		}

		return $template;
	}
	
	
	
	// -------------------------------------------------------------------
	// construct()
	// -------------------------------------------------------------------
	// Protected constructor	
	protected function __construct($template_name)
	{
		$this->template = $template_name;
	}
	
	

	// -------------------------------------------------------------------
	// register()
	// -------------------------------------------------------------------
	// Register a variable with the template
	// @param string 	name of variable to register
	// @return	mixed	value to be registered. This may be a scalar or an array
	public function register($name, $value)
	{
		$this->registered[$name] = $value;
	}
	
	
	
	// -------------------------------------------------------------------
	// multi_egister()
	// -------------------------------------------------------------------
	// Registers an array of variable with the template
	// @param string 	Assoc array of name => value to be registered
	public function multi_register($values)
	{
		if (!is_array($values))
		{
			return;
		}

		foreach ($values AS $name => $value)
		{
			$this->register($name, $value);
		}
	}
	
	

	
	
	// -------------------------------------------------------------------
	// render()
	// -------------------------------------------------------------------
	// Renders the template
	// @param 	boolean		We wont use this in this example
	// @return	string		Rendered version of the template
	public function render($parseexternal=false)
	{
		// Define global variables (yeah this is considered bad, but they are global)
		global $appCore, $db;

	
		
		extract($this->registered, EXTR_SKIP);



		// Fetch the template
		$template_code = self::fetch_template($this->template);
		
		
		if (strpos($template_code, '$final_rendered') !== false)
		{
			eval($template_code);
		}
		else
		{
			eval('$final_rendered = "' . $template_code . '";');
		}
		
		return stripslashes($final_rendered);
	}
	
	
	
	
	
	// -------------------------------------------------------------------
	// fetch_template()
	// -------------------------------------------------------------------
	// Fetches template from datastore or cache
	// @param	string		Name of template to fetch
	// @return	string
	protected static function fetch_template($template_name)
	{
		global $appCore, $db;


		// Does the template exist in the template cache?
		if(isset($appCore->templatecache["$template_name"]))
		{
			// Using a template from the cache
			$template = $appCore->templatecache["$template_name"];
		}
		else
		{
			// Fetching the template from the database
			$result = $db->query("SELECT pagetext FROM template WHERE title='$template_name'");
			
			
			
			// Process the template
			if($db->row_count($result) > 0)
			{
				$template_array = $db->fetch_array($result);
			}
			else
			{
				echo("The template $template_name does not exist " . $template_name);
			}
			
			
			$template = addslashes($template_array['pagetext']);
			
			// Cache the template
			$appCore->templatecache["$template_name"] = $template;
		}

		
		return $template;
	}
}
?>




So thats your framework.


You will need a database table called "template" which has the following fields:


template(
templateid INT 11 PRIMARY_KEY AUTO_INCREMENT
title VARCHAR 100
pagetext MEDIUMTEXT
)


So how to use it?


Well you have your templates in the database, try adding these templates:


PAGE_SHELL template

name: PAGE_SHELL
<html>
<head>
<title>$pagetitle</title>
</head>
<body>
$header

$content

$footer

</body>
</html>



header template
name: header
<p>This is the header for $sitename</p>


footer template
name: footer
<p>This is the footer for $sitename</p>




Now open up that index.php script and paste the following bits of code in.

At the bottom right before the ?>

$template = appTemplate::create("PAGE_SHELL");
	$template->register('pagetitle', "My homepage");
	$template->register('header', $header);
	$template->register('footer', $footer);
	$template->register('content', $content);
print_output($template->render(true));


This will print out a template, the registers are passing whatever is to be injected where the variables are in the PAGE_SHELL template.


Now above this add the following template call to set $header and $footer (we will create two templates and inject them in)



// First the header, we are basically fetching the template and putting it into the $header variable
$template = appTemplate::create("header");
	$template->register('sitename', "My Site");
$header= $template->render();



// Now we will do the footer, but slightly differently
// In the register bit, you can set these to variables, like this
$sitename = "My Web Site";

$template = appTemplate::create("footer");
	$template->register('sitename', $sitename);
$footer= $template->render();





Thats a template engine. You can pre register the header and footer, so you don't need to include them in that output template call, so they are 'globalised', same with variables.

But that might be making it all a bit too complicated.

This post has been edited by FizixRichard: 26 January 2012 - 06:20 PM

0

#3 User is offline   Wickham 

  • Web Guru
  • View gallery
  • Group: Moderators
  • Posts: 2,876
  • Joined: 11-June 09
  • Reputation: 257
  • Gender:Male
  • Location:Salisbury UK
  • Experience:Intermediate
  • Area of Expertise:Web Developer

Posted 26 January 2012 - 07:46 PM

Do you really have to do all that object oriented PHP? Won't a simple PHP "include" be enough for Fulmar who didn't mention a database.

Go to one typical page, cut out the html or php code that repeats on every page and put it in a separate file called nav.inc (no html, head or body tags, just the code that repeats). Do the same for the footer code and call that footer.inc. Do the same for the header code and call that header.inc

Then place <?php include ("header.inc"); ?> where the header was, <?php include ("nav.inc"); ?> where the nav code was and <?php include ("footer.inc"); ?> where the footer code was.

Cut out the same code and replace with the above in all the other main pages. All the main pages will need .php extension if they have .html at present.

Then when you need to edit the footer, you only have to edit one file. Same for the others. It won't process on your local computer unless you have a server like Apache, so you may have to upload to test or install WampServer 2 which includes Apache server.

This post has been edited by Wickham: 26 January 2012 - 07:54 PM

0

#4 User is offline   Fulmar 

  • Forum Newcomer
  • Pip
  • Group: Members
  • Posts: 3
  • Joined: 26-January 12
  • Reputation: 0

Posted 26 January 2012 - 08:38 PM

Thanks both for your suggestions. Although I have a book on PHP, I haven't read it yet, so I am at present unfamiliar with PHP, but yes, that PHP stuff looks ideal, in that you can change content in just the one file and it will reflect through all the pages where the php line of code is. Both suggestions look very useful and instructive. Perhaps, since I'm a PHP noobie, I should try wickham's suggestion first of all. But thanks FIzixRichard also for your indepth guidelines. All very useful! thanks, Matt :)
0

#5 User is offline   The Web Solution Provider 

  • Forum Newcomer
  • Pip
  • Group: Members
  • Posts: 7
  • Joined: 26-January 12
  • Reputation: 0
  • Gender:Male
  • Location:Scarborough,United Kingdom
  • Experience:Web Guru
  • Area of Expertise:Web Developer

Posted 26 January 2012 - 09:23 PM

View PostFulmar, on 26 January 2012 - 08:38 PM, said:

Thanks both for your suggestions. Although I have a book on PHP, I haven't read it yet, so I am at present unfamiliar with PHP, but yes, that PHP stuff looks ideal, in that you can change content in just the one file and it will reflect through all the pages where the php line of code is. Both suggestions look very useful and instructive. Perhaps, since I'm a PHP noobie, I should try wickham's suggestion first of all. But thanks FIzixRichard also for your indepth guidelines. All very useful! thanks, Matt :)


Your a beginner. There is no need for PHP you can use SSI to include one html file in another.

Create a file like header.html or nav.html etc and put your navbar code in there. You can then include the navbar on all pages with:

<!--#include virtual="path to file/include-file.html" -->


Your hosting needs to support SSI for this to work. Give it a try.

This post has been edited by The Web Solution Provider: 26 January 2012 - 09:24 PM

0

#6 User is offline   Wickham 

  • Web Guru
  • View gallery
  • Group: Moderators
  • Posts: 2,876
  • Joined: 11-June 09
  • Reputation: 257
  • Gender:Male
  • Location:Salisbury UK
  • Experience:Intermediate
  • Area of Expertise:Web Developer

Posted 26 January 2012 - 09:44 PM

View PostThe Web Solution Provider, on 26 January 2012 - 09:23 PM, said:

Your a beginner. There is no need for PHP you can use SSI to include one html file in another.

Create a file like header.html or nav.html etc and put your navbar code in there. You can then include the navbar on all pages with:

<!--#include virtual="path to file/include-file.html" -->


Your hosting needs to support SSI for this to work. Give it a try.


Doesn't SSI have to have a .shtml file extension? I'll have to test whether it works with a .html extension.
http://blog.dreamhos...x.cgi?area=2065

However, SSI is the poor man's PHP, hardly ever used now. I advise using PHP which will mean changing all main page extensions from .html to .php but as you may later want to add more PHP it will future-proof it.

This post has been edited by Wickham: 26 January 2012 - 09:45 PM

0

#7 User is offline   FizixRichard 

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 325
  • Joined: 05-October 07
  • Reputation: 47
  • Gender:Male
  • Location:Market Deeping, England
  • Experience:Advanced
  • Area of Expertise:Web Designer

Posted 27 January 2012 - 10:54 AM

View PostWickham, on 26 January 2012 - 07:46 PM, said:

Do you really have to do all that object oriented PHP? Won't a simple PHP "include" be enough for Fulmar who didn't mention a database.


Your right, the OP could do that. I just wouldn't call PHP includes 'templating' as such. I simply provided it as its what I use and its not exactly complicated.




View PostFulmar, on 26 January 2012 - 08:38 PM, said:

Thanks both for your suggestions. Although I have a book on PHP, I haven't read it yet, so I am at present unfamiliar with PHP, but yes, that PHP stuff looks ideal, in that you can change content in just the one file and it will reflect through all the pages where the php line of code is. Both suggestions look very useful and instructive. Perhaps, since I'm a PHP noobie, I should try wickham's suggestion first of all. But thanks FIzixRichard also for your indepth guidelines. All very useful! thanks, Matt :)


If you don't know PHP at all, Wickham's approach will be much easier, but when you know PHP I'd look at using the kind of engine I described.


View PostThe Web Solution Provider, on 26 January 2012 - 09:23 PM, said:

Your a beginner. There is no need for PHP you can use SSI to include one html file in another.

Create a file like header.html or nav.html etc and put your navbar code in there. You can then include the navbar on all pages with:

<!--#include virtual="path to file/include-file.html" -->


Your hosting needs to support SSI for this to work. Give it a try.


Wow, I forgot SSI existed lol. You *could* do that, but I'd still at least use PHP includes.
0

#8 User is offline   Fulmar 

  • Forum Newcomer
  • Pip
  • Group: Members
  • Posts: 3
  • Joined: 26-January 12
  • Reputation: 0

Posted 27 January 2012 - 06:10 PM

Thanks for all your advice, yes I tried out wickham's simple php include method and changed all pages from .html to .php. So far I have just done a header include... took a little time, but well worth it to make future changes easy. yes 'roger that' FizixRichard, once I'm more acquainted with php I will look into your more indepth method, but for now.. this php include way is very ideal! Matt :)
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users