phphtmltemplate-engine

How to eval plain text php and and export the result to an html file


I am currently trying to create a small template engine for a project that I am working on, and I am using a system where I am replacing {$tag} with a preset tag. So say I put {username} in my template file, it will return a string which is the username. Now I want to go beyond just a simple string replacing a string. So using the same code I put

$tpl->replace('getID', '<?php echo "test"; ?>);

And it didn't work, so when I went to inspect element, I saw that it returned <!--? echo "test"; ?-->...

So now I am just trying to figure out why it returned commented code.

Here is my class file:

class template {

  private $tags = [];
  private $template;

  public function getFile($file) {
    if (file_exists($file)) {
      $file = file_get_contents($file);
      return $file;
    }
    
    return false;
  }

  public function __construct($templateFile) {
    $this->template = $this->getFile($templateFile);
    if (!$this->template) return "Error! Can't load the template file $templateFile";   
  }

  public function set($tag, $value) {
    $this->tags[$tag] = $value;
  }

  private function replaceTags() {
    foreach ($this->tags as $tag => $value) {
      $this->template = str_replace('{'.$tag.'}', $value, $this->template);
    }

    return true;
  }

  public function render() {
    $this->replaceTags();
    print($this->template);
  }

}

And My index file is:

require_once 'system/class.template.php';

$tpl = new template('templates/default/main.php');

$tpl->set('username', 'Alexander');
$tpl->set('location', 'Toronto');
$tpl->set('day', 'Today');

$tpl->set('getID', '<?php echo "test"; ?>');

$tpl->render();

And my template file is:

<!DOCTYPE html>

<html>

<head></head>

<body>
    {getID}
  <div>
    <span>User Name: {username}</span>
    <span>Location: {location}</span>
    <span>Day: {day}</span>
  </div>
</body>
</html>

Clarification

At the time when I was making the aforementioned template engine, one of my goals was to create something that would be able to take both raw php and plain text and be able to pump an output out that would just work (similar to twig).

What I was effectively trying to ask was how do I take php code surrounded by <?php //... ?> and pipe the output of that as a string to be rendered in html. What I would do now is use an eval statement. This would basically turn $tpl->replace('getID', '<?php echo "test"; ?>); into $tpl->replace('getID', eval('<?php echo "test"; ?>)); which would work. This is a much more elegant way of doing this as it allows for any static php to be piped in during execution, and the output to be piped out in plain text (or html) after resolution.

Another solution, as mentioned by Unbranded Manchester, is that instead of writing more php and just piping that in, I can use specialty functions that would do the job of the eval'd code. So the example would look like $tpl->replace('getID', fetchID());


Solution

  • You're redeclaring PHP in a php file when there is no need to. i.e. you're trying to print <?php which is why it's messing up.

    So, you can replace this:

    $tpl->set('getID', '<?php echo "test"; ?>');
    

    with this

    $tpl->set('getID', 'test');
    

    But, you obviously already know that, you're just trying to go further, the way to do this is by using php inside the set. So, as an idea, you could try this:

    $tpl->set('getID', testfunction());
    

    (You're calling testfunction here to define the 'getID' here btw)

    So, now you want to write a little function to do something fancy, for the sake of this example:

    function testfunction(){
      $a = 'hello';
      $b = 'world';
      $c = $a . ' ' . $b;
      return $c;
    }
    

    The above should then return hello world in place of {getID}

    In reference to your comments - if you want to go one step further and start being more advanced with the return results, you can do the following:

    function testfunction(){
      $content = "";
      foreach ($a as $b){
        ob_start();
      ?>
        <span><?php echo $b->something; ?></span>
        <a href="#">Some link</a>
        <div>Some other html</div>
        <?php 
          $content += ob_get_clean();
      }
      return $content
    }