Question

I'm writing a simple templating layer in PHP but I've got myself a little stuck. Here's how it works at the moment:

Firstly I use fetch_template to load the template contents from the database - this works (and I collect all the templates at startup if you're interested).

I use PHP variables in my template code and in the logic - e.g.:

// PHP:
$name = 'Ross';

// Tpl:
<p>Hello, my name is $name.</p>

I then use output_template (below) to parse through the variables in the template and replace them. Previously I was using template tags with a glorified str_replace template class but it was too inefficient.

/**
 * Returns a template after evaluating it
 * @param   string  $template   Template contents
 * @return  string  Template output
 */
function output_template($template) {
    eval('return "' . $template . '";');
}

My problem, if you haven't already guessed, is that the variables are not declared inside the function - therefore the function can't parse them in $template unless I put them in the global scope - which I'm not sure I want to do. That or have an array of variables as a parameter in the function (which sounds even more tedious but possible).

Does anyone have any solutions other than using the code from the function (it is only a one-liner) in my code, rather than using the function?

Thanks, Ross

P.s. I know about Smarty and the vast range of templating engines out there - I'm not looking to use them so please don't suggest them. Thanks!

Was it helpful?

Solution

Rather than run through your loop you can use include($template_name).

Or, if you want the content of the output from the template, you can do something like this:

$template_name = 'template.php';

// import the contents into this template
ob_start();
include($template_name);
$content = ob_get_clean();

// do something with $content now ...

And remember, in your template, you can use the often overlooked PHP syntax:

<?php if ($a == 5): ?>
A is equal to 5
<?php endif; ?>

Alternative syntax is available for if, while, for, foreach and switch ... perfect for manipulating the data in your template. See "Alternative syntax for control structures" for more details.

OTHER TIPS

I'd pass an associative array with variables to replace, then extract() them.

Then you could also pass $_GLOBALS to achieve the same result.

function output_template($template, $vars) {
    extract($vars);
    eval('return "' . $template . '";');
}

Edit: you might also want to consider string subtitution instead of eval, depending on who's allowed to write your templates and on who specifies which template to load. Then there might be a problem with escaping, too...

Also, expanding on davev's comment eval is a bit ugly.

If you can do something like

function inc_scope( $file , $vars )
{
    extract($vars); 
    ob_start(); 
    require($file); 
    return ob_get_clean(); 
}

Then you get to use plain-old-php as your templating language, and you don't get any evil-evals, and "extract" + buffering merely limits the visible scope of the php code in the require.

Create file

  1. config.php
  2. index.php

Create folder

  1. inc
  2. template/default/controller/ main files here home.php, login.php, register.php, contact.php, product.php ...

  1. headet.tpl and footer.tpl include home.php file.
  2. main dir /template/default

config.php code here

/* semu design */
// HTTP URL
define('HTTP_SERVER', 'http://localhost/1/');

// HTTPS URL DISABLE
// define('HTTPS_SERVER', 'http://localhost/1/');

// DİZİNLER
define('DIR_INC',       'C:\wamp\www\1/inc/');
define('DIR_TEMLATE',   'C:\wamp\www\1/template/default/');
define('DIR_MODULES',   'C:\wamp\www\1/template/default/module/');
define('DIR_IMAGE',     'C:\wamp\www\1/image/');
define('DIR_CACHE',     'cache'); // [php cache system turkish coder][1]

// DB
define('DB_HOSTNAME',   'localhost');
define('DB_USERNAME',   'root');
define('DB_PASSWORD',   '123');
define('DB_DATABASE',   'default');
define('DB_PREFIX',     '');

index.php code here

<?php 
// Version
define('VERSION', '1.0');

// Config file
if (file_exists('config.php')) {
    require_once('config.php');
}

// Moduller
require_once(DIR_INC . 'startup.php'); // mysql.php db engine, cache.php, functions.php, mail.php ... vs require_once code

// Cache System
//$sCache = new sCache();

/*$options = array(
    'time'   => 120,
    'buffer' => true,
    'load'   => false,
    //'external'=>array('nocache.php','nocache2.php'), // no cache file
);

$sCache = new sCache($options);*/

// page
$page = isset($_GET['page']) ? trim(strtolower($_GET['page'])) : "home";

$allowedPages = array(
    'home'          => DIR_TEMPLATE.'controller/home.php',
    'login'         => DIR_TEMPLATE.'controller/login.php',
    'register'      => DIR_TEMPLATE.'controller/register.php',
    'contact'       => DIR_TEMPLATE.'controller/contact.php'
);

include( isset($allowedPages[$page]) ? $allowedPages[$page] : $allowedPages["home"] );
?>
  1. index.php?page=home
  2. index.php?page=login ...

Active class code

<ul>
<li <?php if ( $page == 'home' ) echo 'class="active"'; ?> Home </li>
<li <?php if ( $page == 'login' ) echo 'class="active"'; ?> Login </li>
</ul>
  1. And Token system coming :
  2. index.php?page=home&token=Co54wEHHdvUt4QzjEUyMRQOc9N1bJaeS

Regards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top