0
\$\begingroup\$

This is not really a question but I'd like to obtain some opinions about this simple class. For an old project I had the necessity to load some php template files that includes some foreach() and for() loops and other variables loaded from a database. I was start thinking how to obtain this using a templating class and this is what I wrote to achieve the objective, I've reworked a templating class that works well with html and php files that doesn't need to load data from variables. I know that I can also use simply the include, require or include_once and require_once but writing a reusable class was the solution that seemed to me more reliable. Can this class to be considered useful? Is it possible to improve it by using magic methods like __set() and __get() to output the desired data to a loop? In the usage example I will not post the $data variable that is an array of data loaded from database, this choiche is because I don't want to write a long post.

<?php

class Template{

    private $tpl;
    private $fileName;
    private $templatePath;

    public function __construct($templatePath){
        $this->templatePath = $templatePath;
    }

    public function loadTemplate(string $tpl){
        $this->fileName = basename($tpl.'.php');
        if(file_exists($this->templatePath.'/'.$this->fileName)){
             return $this->templatePath.'/'.$this->fileName;
        } else {
            throw new Exception('Template not found.');
        }
    }

}

?>

Usage example:

<?php

require_once 'Template.class.php';
//$data = array(); this array comes from a db
//$results = array(); this is an handmade array
$template = new Template('path/to/template/file');

include($template->loadTemplate('demo'));
?>

Template file that is loaded

          <div class="wrapper">
            <?php for($i = 0; $i < count($data); $i++): ?>
              <span><small class="text-uppercase"><?php echo $data[$i]['h']; ?></small>
              <small>&nbsp;-&nbsp;</small>
              <small class="text-uppercase"><?php echo $data[$i]['a']; ?></small>
              <p><?php echo $results[mt_rand(1,12)]; ?></p></span>
            <?php endfor;?>

          </div>
\$\endgroup\$
1
\$\begingroup\$

This is not a template class at all, but sort of a wrapper for file_exists() function. It does nothing of the templating business but just gets you a filename.

To make it a template class,

  • make it accept an array with all data used in the template
  • add a render() function that will extract data array into separate variables and then include the template file.
  • add some sort of auto-escaping feature (like going through the data array recursively and escaping all scalar values)
  • a possibility to return the rendered HTML instead of outputting it
  • add some facility to call a "master" template that will add the common site design to the certain page's template.

So a usage example would be

require_once 'Template.class.php';
$data = [
    'data' => $data,
    'results' => $results,
];
$template = new Template('path/to/template/file');
$template->render($data);

Quite off topic but consider a more tidy syntax for your template.

      <div class="wrapper">
        <?php foreach($data as $row): ?>
          <span><small class="text-uppercase"><?= $row['h'] ?></small>
          <small>&nbsp;-&nbsp;</small>
          <small class="text-uppercase"><?= $row['a'] ?></small>
          <p><?= $results[mt_rand(1,12)] ?></p></span>
        <?php endforeach ?>
      </div>
\$\endgroup\$
  • \$\begingroup\$ I'm not too experienced with the __set() and __get() methods, so I'm avoiding to use them. Can you show me an example of the render method you've implemented in the example? \$\endgroup\$ – user9741470 Aug 24 '18 at 16:01
  • 1
    \$\begingroup\$ it has nothing to do with __set() and __get() methods. It just literally does what I wrote, two lines: one extract($data) and then include(template). That's all. \$\endgroup\$ – Your Common Sense Aug 24 '18 at 16:03
  • \$\begingroup\$ public function render(string $tpl, array $data){ ob_start(); extract($data); include($this->loadTemplate($tpl)); $file = ob_get_clean(); return $file; } \$\endgroup\$ – user9741470 Aug 24 '18 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.