Hello,

I'm trying to replace {include %filename.php%} with that file from the server. I can get this to work file if the file is plan html text using the function below.

$str = "This would be a paragraph of text. {include %news.php%}";

preg_replace_callback("/\{include %(.*?)\%}/", function($m) {
  	return file_get_contents(CORE . 'includes/' .$m[1]);
}, $str);

But if the included file contains php code for example

<? echo "Hello World"; ?>

It doesn't work, it just prints "echo hello world".

If i change return file_get_contents to include it includes the file before my string of text. Unlike how the string is originally set with the text first then include the file.

Does anyone know how to achieve this?

the best syntax will be {%filename%} then where simple str_replace will do a job

$temp_file = "{%news%}"; //here you have it
$file_name = str_replace(array("{%", "%}"),array("", ""), $temp_file);
include $file_name.".php";

How would this work if I don't know what will between the {%%}.

How would this work if I don't know what will between the {%%}.

whatever will be between {% and %} will be considered as file name. That will be a syntax to be adhered!

I don't see how this would work. I getting my information from the database. The text would look like this.

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.

{%contactform%}


Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.

I need it to find {%%}, include the file within the tag then return everything in the same order as above.

The below works but its displaying the form before the text, not in the order it was saved in the database as.

if($result = $mysqli->query($sql)){
			
			$row = $result->fetch_object();
			$str = $row->bodyRight;
			
			$this->content = preg_replace_callback("/\{include %(.*?)\%}/", function($m) {
  								return(CORE . 'includes/' .$m[1]);
							  }, $str);
			
		}
		
		return $this->content;

Are you trying to make a template class?

I guess if that's what you call it.

I have a right hand column that is having that data be pulled from the database. I have a back end where a user can edit this data via a WYSIWYG editor. I need to let them be able to enter a tag such as {%filename%} and have that file include, but it also needs to allow php code to be ran and echoed in the included file.

Does that make sense?

don't include file names. Iam also in process of writing themeing engine for my application wanna be. Here is what I have so far. I want to make ang engine like Joomla's where one can drop the folder and add stuffs in a panel. Those are advanced stuffs and I have reserved them for a while. Take a look here

Member Avatar for diafol

There are better ways to build templates.

I looked at your code, but what I'm doing is completely different. Your are setting values using php manually. I'm getting the text from the database dynamically so I don't know what that value will be. Nor do i know if that value will be in the text.

So i need it to check if that tag is in the content, if so include that file where the tag is then return all of the content in order.


@ardav how would you achieve this?

I looked at your code, but what I'm doing is completely different. Your are setting values using php manually. I'm getting the text from the database dynamically so I don't know what that value will be. Nor do i know if that value will be in the text.

did you see this?

<?php 
    
    $layout = new HTemplate("layout.tpl");
    $layout->set("title", $id);
    $layout->set("heading", $heading);
    $layout->set("body", $body);

    echo $layout->render();

?>

did you ask yourself where do variables $id, $heading and $body are coming from?

What I'm saying is your replacing a {@body} with $body in a template, I'm not calling a template.

Take a look, the call to getContentRight is in my so called "template" file.

<div class='col-right'><? echo $page->getContentRight($page->id); ?></div>
//
// Example
//
public function getContentRight($id){
	global $mysqli;
		
	$sql = "SELECT bodyRight FROM pages WHERE id = '{$id}' LIMIT 1";
		
	if($result = $mysqli->query($sql)){
			
		$row = $result->fetch_object();
		$str = $row->bodyRight;
			
	$this->content = preg_replace_callback("/\{include %(.*?)\%}/",
function($m) {
  	return file_get_contents(CORE . 'includes/' .$m[1]);
	 }, $str);
			
	}
		
	return $this->content;
}

What I'm saying is your replacing a {@body} with $body in a template, I'm not calling a template.

Take a look, the call to getContentRight is in my so called "template" file.

<div class='col-right'><? echo $page->getContentRight($page->id); ?></div>
//
// Example
//
public function getContentRight($id){
	global $mysqli;
		
	$sql = "SELECT bodyRight FROM pages WHERE id = '{$id}' LIMIT 1";
		
	if($result = $mysqli->query($sql)){
			
		$row = $result->fetch_object();
		$str = $row->bodyRight;
			
	$this->content = preg_replace_callback("/\{include %(.*?)\%}/",
function($m) {
  	return file_get_contents(CORE . 'includes/' .$m[1]);
	 }, $str);
			
	}
		
	return $this->content;
}

what do you want to achieve?

I want to get the text from the bodyRight in the database, if there is a tag in the text like {%filename%}, replace that tag with an include. Take a look at the function below.

//
// Example
//
public function getContentRight($id){
	global $mysqli;
		
	$sql = "SELECT bodyRight FROM pages WHERE id = '{$id}' LIMIT 1"; 
		
	if($result = $mysqli->query($sql)){
			
		$row = $result->fetch_object();
		$str = $row->bodyRight;
			
	$this->content = preg_replace_callback("/\{include %(.*?)\%}/",
function($m) {
  	return file_get_contents(CORE . 'includes/' .$m[1]);
	 }, $str);
			
	}
		
	return $this->content;
}

The above works if the included file is HTML ONLY, if the included file has php it actually prints on the page <?php echo"Hello World"; ?> instead of just Hello World.

I would like to know how to make this work for both html and php files.

I gave you simplest way without including any file. Just Add that div in html template file, let say {%right_content%} with all necessary css/JS. Then add this line to replace with contents of the database

<?php 
    
    $layout = new HTemplate("layout.tpl");
    $layout->set("right_content", getContentRight($id));
    echo $layout->render();

?>

So what is wrong with this?

I'm not really trying to load a template, my template is loaded already. Take a look below.

I have a admin panel with the wysiwyg editor, a user types in,

<h1>Contact Us</h1>
<p>
	Need to get in touch with us?&nbsp; Drop us a line.&nbsp; We'd love to hear from you. You may also call, fax, email, or even write us a letter.</p>

<p>{include %contactForm.php%}</p>

this is saved into my database in bodyRight

now when the page is viewed it gets my template of below

<div class='col-right'><? echo $page->getContentRight($page->id); ?></div>

this calls this functions which receives the users input from the database.

//
// Example
//
public function getContentRight($id){
    global $mysqli;
     
    $sql = "SELECT bodyRight FROM pages WHERE id = '{$id}' LIMIT 1";
     
    if($result = $mysqli->query($sql)){
     
    $row = $result->fetch_object();
    $str = $row->bodyRight;
     
    $this->content = preg_replace_callback("/\{include %(.*?)\%}/",
    function($m) {
    return file_get_contents(CORE . 'includes/' .$m[1]);
    }, $str);
     
    }
     
    return $this->content;
}

In this example the included file that needs to be echoed is contactForm.php
that file looks like,

<div id='contact-success'></div>

	<form id="contactform" name="contactform" method="post" action="">
	<h2>Contact Form</h2>
	 <label>Your Name (Required)</label>
	 <input type="text" id="cname" name="cname" />
	 <label>Your Email Address (Required)</label>
	 <input type="text" id="email" name="email" />
	 <label>Message (Required)</label>
	 <textarea name='desc' id='desc'></textarea>
	 <p>We reply to every message we receive. </p>
	 <input type="submit" name="contactSubmit" id="contactSubmit" value="Send Message" />
	 </form>

Now This works and outputs correctly.

But if contactform.php had the following code.

<?php echo "hello world"; ?>

it would actually print <?php echo "hello world"; ?> take a look at the screenshot below.

I need to be able to run a php in the included file.

I'm not really trying to load a template, my template is loaded already. Take a look below.

I have a admin panel with the wysiwyg editor, a user types in,

<h1>Contact Us</h1>
<p>
	Need to get in touch with us?&nbsp; Drop us a line.&nbsp; We'd love to hear from you. You may also call, fax, email, or even write us a letter.</p>

<p>{include %contactForm.php%}</p>

this is saved into my database in bodyRight

now when the page is viewed it gets my template of below

<div class='col-right'><? echo $page->getContentRight($page->id); ?></div>

this calls this functions which receives the users input from the database.

//
// Example
//
public function getContentRight($id){
    global $mysqli;
     
    $sql = "SELECT bodyRight FROM pages WHERE id = '{$id}' LIMIT 1";
     
    if($result = $mysqli->query($sql)){
     
    $row = $result->fetch_object();
    $str = $row->bodyRight;
     
    $this->content = preg_replace_callback("/\{include %(.*?)\%}/",
    function($m) {
    return file_get_contents(CORE . 'includes/' .$m[1]);
    }, $str);
     
    }
     
    return $this->content;
}

In this example the included file that needs to be echoed is contactForm.php
that file looks like,

<div id='contact-success'></div>

	<form id="contactform" name="contactform" method="post" action="">
	<h2>Contact Form</h2>
	 <label>Your Name (Required)</label>
	 <input type="text" id="cname" name="cname" />
	 <label>Your Email Address (Required)</label>
	 <input type="text" id="email" name="email" />
	 <label>Message (Required)</label>
	 <textarea name='desc' id='desc'></textarea>
	 <p>We reply to every message we receive. </p>
	 <input type="submit" name="contactSubmit" id="contactSubmit" value="Send Message" />
	 </form>

Now This works and outputs correctly.

But if contactform.php had the following code.

<?php echo "hello world"; ?>

it would actually print <?php echo "hello world"; ?> take a look at the screenshot below.

I need to be able to run a php in the included file.

My point is, your templating approach is wrong and that is why it is giving you problem. There are better ways but yours is even worse. Now to be clear, my point is change the whole template!

How you could handle loops.

If i had to pass an array of say blog post to the template how would the template loop for each object in an array?

Also sorry for the communication break down.

How you could handle loops.

If i had to pass an array of say blog post to the template how would the template loop for each object in an array?

Also sorry for the communication break down.

No need to loop if array is associative. add function below and see usage at the bottom. Let me know how much helpful is this approach as I'm still reasearching if it is the better way.

public function set_array($values_array){
        $this->values=$values_array;
}

Usage

$layout = new HTemplate("layout.tpl");
$data = array("title"=>$title, "heading"=>$heading, "body"=>$body); 
$layout->set_array($data);
echo $layout->render();

I think The design need to be extended to add loops but I don't want to add new language and want to keep it PHP!

@utroda

Looking at how your syntax works and what you're trying to accomplish, you should take a look at a package called Twig (http://twig.sensiolabs.org/)

It is a template engine that has the exact functionality you are trying to create. It is simple to implement, very well documented and very well tested.

That looks really interesting but is a template system the best choice if i also need to integrate a shopping cart as well?

Well only you know the architecture of the system(s) you're trying to work within. If you are building them from scratch Twig is an excellent template system.

If you're trying to add to an existing one, than the reason your include is showing before the rest of your output is because the include is being executed before your output is sent. SO it is outputting before the rest of your output.

TO remedy this you will need to wrap the include with output buffering, essentially capture it into a variable and then output where appropriate.
http://php.net/manual/en/function.ob-start.php

Well this is the way i have it set up,

<?php
ob_start();
require_once("load.php");
session_start();
if(isset($_SERVER['HTTP_REFERER']) && trim($_SERVER['HTTP_REFERER']) != ""){
	if((substr($_SERVER['HTTP_REFERER'], 0, strlen($siteurl)) != $siteurl)){
		 LogReferrer($_SERVER['HTTP_REFERER']);
	}
}

$page = isset($_REQUEST["p"]) ? new Page($_REQUEST["p"]) : new Page();


if(isset($_REQUEST["view"])) : $page->getView($_REQUEST['view']); endif;

if($pStore == 1) :

	$store = new store();

	if(empty($_SESSION['cart'])) : $_SESSION['cart'] = $store->newSession(8); endif;

endif;


$blog = (isset($_REQUEST["p"]) && $_REQUEST["p"] == "blog") ?  new blog() :  false;


//
// Change Headers and Footers if needed
//
switch($page->slug){
	
	case "home": $sub = null; $spc = null; break;
	case "project": $sub = 'project'; $spc = 'project'; break;
        case "blog": $sub = 'blank';  $spc = null; break;	
	default: $sub = "sub"; $spc = null; break;
}	


$page->getHeader($sub);
$page->getTemplate($page->slug, $page->view);
$page->getFooter($spc);



session_write_close();
ob_end_flush();
?>

If my getTemplate called a 2 column page it would load 2col.php, which consist of

<div class='col-left'><? echo $page->getContentLeft($page->id); ?></div>
<div class='col-right'><? echo $page->getContentRight($page->id); ?></div>

Does this help?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.