Jump to content

do this only if(not as simple as it sounds)


doddsey_65

Recommended Posts

the current way i display a page on my site is like this

 

i have the php file which takes the contents onf a html file and replaces kets in curly braces with variables

 

the php file

$template->replace(array('SITE_NAME' => $site_name),'header_file');

 

the html file

<title>{SITE_NAME}</title>

 

everything runs smoothly until i come to an if statement.

I want to display the word login only if no user is logged in. If they are then display their username.(just an example)

 

one way to overcome this is:

 

the php

if(isset($_SESSION['logged_in']))
    {
        $user_name = $user->user_name_nl;
        $user_avatar = $user->avatar;
        $user_group = $user->group;
        
    }
    else
    {
        $user_name = 'Login';
        $user_avatar = '';
        $user_group = '';
    }
$template->replace(array('USERNAME' => $user_name, 'AVATAR' => $user_avatar, 'GROUP' => $group),'header_file');

 

the problem is that the username opens a menu once clicked and if i just did this then if they werent logged in it would display login but it would also open the same menu and all the keys would have to be replaced with ''.

 

now obv i cant include if statements in a html file so does anyone have any ideas or advice? i know phpbb includes the if statements in the html file between comment tags and somehow the same file appears in the cache folder as a php file with the comments stripped so the php code becomes active. but ive looked at how they do it and it just confuses me.

 

Thanks

Link to comment
Share on other sites

To get the functionality your require you are likely going to need to implement if statements within your template parser. this is why template engines are so inefficient. Your basically creating a mini programming language.

 

Can I ask you why you think using something like.....

 

<div class="foo">{FOO}</div>

 

Is a better option than using something like.....

 

<div class="foo"><?=$foo?></div>

 

?

 

The second option is far more flexible & efficient because it uses native PHP. Either way a designer is going to need to learn some new syntax, you may as well have them learn some basic PHP which is (by the way) also already well documented.

 

If you think using a template engine separates code from markup you misunderstand the concept.

Link to comment
Share on other sites

Then you need to make sure its defined.

 

An easy way to do this if you where using an mvc approach, or even just a simple bit of OOP would be to store all your variables within an object (View), this way you can easily make sure to return something.

 

<?php

class View
{
    private $_data = array();

    public function __set($name, $value)
    {
        $this->_data[$name] = $value;
    }

    public function __get($name)
    {
        if (isset($this->_data[$name])) {
            return $this->_data[$name];
        }
        return NULL;
    }

    public function render($template)
    {
        ob_start();
        include $template;
        echo ob_get_clean();
    }
}

 

Now, lets say you have the a template: example.php

<html>
  <head>
    <title><?php echo $this->title; ?></title>
  </head>
  <body>
    <p><?php echo $this->foo; ?></p>
  </body>
</html>

 

Even if the variable 'foo' isn't defined you wont get any error because it will just return NULL.

 

<?php

$v = new View;
$v->title = 'this is an example';
$v->render('example.php');

 

Of course this idea can be extended quite a bit but it's a start.

Link to comment
Share on other sites

thanks for the tips. but say i have a tpl file which has about 30 or so <?php echo $this->xxxx; ?>

 

in the php file i would be doing:

 

$v->xxxx = 'x';
$v->x = 'xxxx';

 

and so on for as many i need to define. is there a faster or better way?

Link to comment
Share on other sites

thanks for the tips. but say i have a tpl file which has about 30 or so <?php echo $this->xxxx; ?>

 

in the php file i would be doing:

 

$v->xxxx = 'x';
$v->x = 'xxxx';

 

and so on for as many i need to define. is there a faster or better way?

 

If there in an array or something you could quickly populate the object using a method like.....

 

public function setValues(array $values)
{
    $this->_data = array_merge($values, $this->_data);
}

Link to comment
Share on other sites

also when i use:

 

<p id="name">    
     <?php echo $this->board_name; ?>
</p>

 

i get the error:

 

Fatal error:  Using $this when not in object context

 

Are you using the render() method like in my example? Can we see your code?

Link to comment
Share on other sites

This is what I used to use, works very well and very fast but you will need to have a play with it as it was a long time since it was used so it might be slightly outdated now.

 

<?php 
class template {

	private $tags = array();

	function __construct() {

	}

	function newTemplate($tags, $templateName) {

		if(empty($templateName)) {
			$templateName = 'index';
		}

define('_TEMPLATE_', 1);

		$error = '<style>
		.error {
			background-color:#edf1f3;
			border-style:solid;
			border-width:1px;
			border-color:#9aaab4;
			padding:4pt;
			text-align:left;
			margin-left:10px;
			margin-right:6px;
		}

		.errortext {
			color:#009999;
			font-style: normal;
			font-family: monospace;
			font-weight:bold;
		}
		</style>
		<div class="error"><span class="errortext"><center>Sorry for inconvenience but our system has located an error due to this the site is now shutdown.</center></span></div>';

		if(!defined('_TEMPLATE_') OR !is_array($tags) OR !is_dir('./templates/' . _TEMPLATE_) OR !file_exists('./templates/' . _TEMPLATE_ . '/' . $templateName . '.html') OR !is_file('./templates/' . _TEMPLATE_ . '/' . $templateName . '.html') OR !is_readable('./templates/' . _TEMPLATE_ . '/' . $templateName . '.html')) {
			exit($error);
		}

		$tags['SITE_NAME'] = 'The Site Name';

			$keys = array_keys($tags);
			$del = array();
			$tagcheck = array();
			$tagz = array();
			$file = file_get_contents('./templates/' . _TEMPLATE_ . '/' . $templateName . '.html');

			if(!$file OR !is_array($tagcheck)) {
				exit($error);
			} else {

				if(preg_match_all("/\{([A-Z]*)\}/", $file, $match)) {

					foreach($match[1] as $k => $v){
						$tagcheck[$v] = $v;
					}

					foreach($tags as $t => $g) {
						$tagz[] = $t;
						if(is_int($t)) {
							unset($tags[$t]);
						}
					}

					foreach($tagcheck as $item => $itemvalue) {
						if(!in_array($item, $tagz, true)) {
							$del[] = '/{' . $item . '}/';
						}
					}

					foreach($keys as $key => $value) {
						$final[$key] = '{' . $value . '}';
					}

					$file = preg_replace($del, '', $file);

					exit(str_replace($final, $tags, $file));
				} else {
					exit($error);
				}
			}
		}
	}
}
?>

 

James.

Link to comment
Share on other sites

hi sorry for the late reply, been at work. here is the code i am using:

 

header.php

<p id="name">    
      <?php echo $this->board_name; ?>
</p>

 

template.php

class template
{
    var $root = '';
    var $template;
    var $template_root;

    private $_data = array();
    
    public function __set($name, $value)
    {
        $this->_data[$name] = $value;
    }

    public function __get($name)
    {
        if (isset($this->_data[$name])) {
            return $value;
        }
        return NULL;
    }
public function set_template($template='default')
    {
        global $config;
        
        $this->template_root = $config['asf_root'].'templates/';
        
        $this->template = $this->template_root.$template.'/';
    }
    
    public function replace($array, $file) 
    {
        $file = './html/'.$file.'.html';
        $file = file_get_contents($this->template.$file);
        if($file)
        {
            foreach ($array as $key => $val) 
            $file = str_replace('{'.$key.'}', $val, $file);
            echo $file;
        } 
        else
        {
            echo 'File '.$file.' doesn\'t exist';
        }
    }

    public function render($template)
    {
        ob_start();
        include $template;
        echo ob_get_clean();
    }
}

 

functions.php

function page_header($page_title)
{
    global $date_time, $template, $settings, $lang, $config, $user;
    
    $css_link = $template->template.'main.css';
    $board_logo = '<img src="'.$template->template.'images/'.$settings['board_logo'].'" alt="'.$settings['board_name'].'" />';

    $offset = $date_time->getOffset();
    $curr_time = $date_time->getTimestamp();
    
    $time = $curr_time - $offset;
    
    $template->board_name = $settings['board_name'];

    $template->render($template->template.'html/header.php');
}

 

index.php

page_header($lang->index);

 

Link to comment
Share on other sites

ill clean it up a bit:

 

header.php(the tpl file)

[color=rgb(0, 0, 0)]
<p id="name">    
<?php echo $this->board_name; ?>
</p>[/color]

 

template.php

class template
{
    var $root = '';
    var $template;
    var $template_root;

    private $_data = array();
    
    public function __set($name, $value)
    {
        $this->_data[$name] = $value;
    }

    public function __get($name)
    {
        if (isset($this->_data[$name])) {
            return $value;
        }
        return NULL;
    }
public function render($template)
    {
        ob_start();
        include($template);
        echo ob_get_clean();
    }
function page_header($page_title)
    {
        global $settings; // settings.php
        
        $this->board_name = $settings['board_name'];

        $this->render($this->template.'html/header.php');
    }
}

 

index.php

$template->page_header('Board Index');

 

any clearer?

Link to comment
Share on other sites

ive checked and done tests and header.php isnt being included other than the render function.

 

the test was i got rid of:

$template->page_header($lang->index);

 

the function page_header calls the render function:

public function render($template)
    {
        ob_start();
        include($template);
        echo ob_get_clean();
    }
    
    public function page_header($page_title)
    {
        global $date_time, $settings, $lang, $config, $user;
        
        $css_link = $this->template.'main.css';
        $board_logo = '<img src="'.$this->template.'images/'.$settings['board_logo'].'" alt="'.$settings['board_name'].'" />';

        $offset = $date_time->getOffset();
        $curr_time = $date_time->getTimestamp();
        
        $time = $curr_time - $offset;
        
        $this->board_name = 'boobs';
        
        echo 'template = '.$this->template.'html/header.php';
        $this->render($this->template.'html/header.php');
    }

 

i dont know why this is happening either as i have gotten your example to work on a test folder.

Link to comment
Share on other sites

ive worked out when it is throwing the error. on my test script(by your example) everything worked fine. and this is the dir tree:

 

ROOT FOLDER
index.php = calls the page_header function from class_view while calls the render function
init.php = starts the view class
class_view.php = the view class
tpl_index.php = the html for index.php

 

but when i split up the files into different dirs:

ROOT FOLDER
index.php
INCLUDES FOLDER
class_view.php
init.php
TEMPLATES FOLDER
   DEFAULT FOLDER
     tpl_index.php

 

i get the error:

Fatal error:  Using $this when not in object context in C:\wamp\www\test\templates\default\tpl_index.php on line 68

 

no idea why though.

Link to comment
Share on other sites

found the reason. i am including a config.php file which holds:

 

$config['asf_root'] = http://localhost/asf/';

 

and in the template.php file i have:

public function set_template($template='default')
    {
        global $config;
        
        $this->template_root = $config['asf_root'].'templates/';
        
        $this->template = $this->template_root.$template.'/';
    }

 

when i echo $config['asf_root'] it appears fine, but obv isnt working so i used the relative path and it worked in the test script. but in my main script the error has gone but it displays nothing.

Link to comment
Share on other sites

removed everything down to the basic and i am getting undefined variable value

 

here:

public function __get($name)
    {
        if (isset($this->_data[$name])) {
            return $value; // error thrown here
        }
        return NULL;
    }

 

EDIT:

replace it with:

 

public function __get($name)
    {
        if (isset($this->_data[$name])) {
            return $this->_data[$name];
        }
        return NULL;
    }

 

and it works fine

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.