TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   General (http://www.talkphp.com/general/)
-   -   PHP Template (http://www.talkphp.com/general/4844-php-template.html)

Sirupsen 08-12-2009 11:37 AM

PHP Template
 
Greetings! I am currently making a few projects, but I am very worried about how I should do my templating system so I do not at some point regret how I did it, and want to recode it!

Basically, I just want to insert informations into my sites easily but also, it shouldn't become a mess with shit loads of php calls inside the HTML. I could pretty easily do something like this:

PHP Code:

<?php $articles $object->fetchArticles(); ?>
<?php 
foreach ($articles as $article) : ?>
    <h1><?php echo $article['title']; ?></h1>
    <p><?php echo $article['content']; ?></p>
<?php endforeach; ?>

That'd basically just require the fetchArticles method to return an array, containing an array for each article:

Example:
PHP Code:

public function fetchArticles() {
   
$query connectToDbAndRetrieveInformation();

   while (
$row mysql_fetch_array($query)) {
      
$data[] = array(
         
'title' => $row['title'],
         
'content' => $row['content']
         
// And for more fancy stuff something like this:
         
'time' => $this->timeDifference($row['time']),
         
'author' => $this->authorName($row['author_id'])
      );
   }
   
   return 
$data;


However, this probably is a pretty bad way to do it (I think?), I don't want to use something big as Smarty and have a whole different weird markup (the foreach loops in smarty are just weird) for the foreach loops. (And it's slooow.. And I won't need half the features) I have made some pretty simple stuff involving replacing {something} with a variable set. However, I can't use PHP in the template file (like if I needed to check something before printing something out, like if the user is administrator). Here is what I have currently:

PHP Code:

<?php
class Template {
    private 
$path 'template/';
    private 
$values = array();

    private function 
__set($name$value) {
        
$this->values[$name] = $value;
    }

    public function 
display($file) {
        
$file $this->path $file;
    
        
$file_content file_get_contents($file);
            
        foreach (
$this->values as $key => $value) {
            
$file_content str_replace('{' $key'}'$value$file_content);
        }    

        echo 
$file_content;
      }
}
?>

Maybe this could be expanded to be useful?

I hope I can get some help on doing this part properly. :)

Enfernikus 08-12-2009 01:28 PM

If you can't use PHP than use Smarty or PHPTal even if you say they're weird they're extremely useful and Smarty isn't that slow with File cahce and opcode code cacher installed.

Sirupsen 08-12-2009 01:37 PM

I'm looking for a short introduction, or someone to point me in the right direction of using PHP in a good way for templating. Since I'll learn a lot more from that, than I will by just using Smarty or any of these other engines..

Enfernikus 08-12-2009 01:53 PM

Well there are several ways to go about it and my preferred way is something to this effect..

php Code:
$tpl = new PHPTemplate('/path/to/templates/files/');
$tpl->assign('user', 'thisisausername');
$tpl->assign('posts', PostArray);
$tpl->display('blog');

And the template file would look something like this

php Code:
<strong>Hello, <?php echo $user; ?></strong>
Displaying <?php count($posts); ?> posts
<?php foreach( $posts as $post ): ?>
  <strong><?php echo $post['header']; ?></strong>
  <p>
    <?php echo $post['body']; ?>
  </p>
<?php endforeach; ?>

The actual class

php Code:
<?php


class PHPTemplate
{
    private $dir;
    private $data = array();
   
        public function __construct($dir)
        {
            if( is_dir($dir) )
            {
                $this->dir = $dir;
            }else{
               
                throw PHPTemplateException('Directory does not exists');
            }
        }
       
        public function assign($variable, $data)
        {
            $this->data[$variable] = $data;
        }
       
        public function display($template)
        {
            $template = rtrim($template, '.php') . '.php';
            if( file_exists($this->dir . $template) )
            {
                ob_start();
               
                $this->__fetch($this->dir . $template);
               
                ob_end_flush();
                return;
            }
           
            throw PHPTemplateException('File does not exists');
        }
       
        private function __fetch($____FILE)
        {
            extract( $this->data );
            include( $____FILE );
        }
}

class PHPTemplateException extends Exception
{
    public function __construct($message)
    {
        parent::__construct('[PHP Template]:' . $message);
    }
}

Sirupsen 08-12-2009 02:14 PM

Thanks a lot! :)

Would it be a bad habbit to use shortcuts here:
PHP Code:

<?php foreach( $posts as $post ): ?>
  <strong><?=$post['header']?></strong>
  <p>
    <?=$post['body']?>
  </p>
<?php endforeach; ?>

Edit: I took your class and mixed it with mine, and I'm pretty happy with the result, tell me if I can optimize/improve it further:

PHP Code:

<?php
require_once("bootstrap.php");

final class 
Template {
    private 
$dir;
    private 
$data;
    
    private function 
__clone() {}

    public function 
__construct($dir='templates/') {
        if(
is_dir($dir))
            
$this->dir $dir;
        else
            throw new 
Exception('Directory does not exists @ Template');
    }
   
    private function 
__fetch($file) {
        
extract($this->data);
        require(
$file);
    }
    
    public function 
__set($variable$data) {
        
$this->data[$variable] = $data;
    }

    public function 
display($template) {
        
$template rtrim($template'.php') . '.php';
        if(
file_exists($this->dir $template))
            
$this->__fetch($this->dir $template);
        else
            throw new 
Exception('File: ' $template ' does not exist in ' $this->dir);
    }
}
?>


Enfernikus 08-12-2009 03:23 PM

Unless it's your server and your site, it is ALWAYS bad habit to use shortcuts.

hello-world 08-18-2009 12:59 PM

I am also confused whether to use smarty or not,whether to use include/require functions or make a custom template class.
I have search many website there always pros and cons arguements about it.

Sirupsen 08-18-2009 01:19 PM

I made a rather simple "Framework" recently, as it's really good practise, this is my finished Template class if you'd like to see it.

It's faily simple to use, just browse the sample files. :)

ioan1k 08-18-2009 06:21 PM

Line 69 :
php Code:
Should be
php Code:

ob_end_clean() will clean all buffers started with ob_start() .. any buffer started before parsing the template will be flushed, while ob_clean() will only empty the last buffer started. Cleaning the enter buffer could result in later bugs, if using output buffering for other sections

Sirupsen 08-18-2009 06:34 PM

Quote:

Originally Posted by ioan1k (Post 27886)
Line 69 :
php Code:
Should be
php Code:

ob_end_clean() will clean all buffers started with ob_start() .. any buffer started before parsing the template will be flushed, while ob_clean() will only empty the last buffer started. Cleaning the enter buffer could result in later bugs, if using output buffering for other sections

Thanks a lot! :D

hello-world 08-23-2009 06:23 PM

I have got a question regarding your custom made template.
if you assign in index.php. It doesn't parse included html files.
Can you please tell me how to solove it ?
Index.php


All times are GMT. The time now is 08:21 AM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0