Skip to main content

Prosty system szablonów PHP

We wcześniejszym wpisie dość niepochlebnie wyraziłem się na temat systemu szablonów Smarty, więc wypadałoby podać jakąś alternatywę.
Chciałbym zaprezentować prosty, lecz funkcjonalny system szablonów.
Jak zwykle, to od programisty zależy, czy poprawnie wykorzysta dane narzędzie i czy szablon rzeczywiście będzie oddzielał widok od logiki aplikacji.
Do tego nie jest potrzebna tak na prawdę żadna biblioteka.

Przykładowa strona

default.php

<!DOCTYPE html>
<html lang="pl">

  <head>
    <meta charset="utf-8">
    <title><?php echo $title; ?></title>
  </head>

  <body>
    <h1><?php echo $title; ?></h1>
    <?php echo $body; ?>
    <?php echo $footer; ?>
  </body>

</html>

footer.php

  <footer>Stopka strony</footer>

Przykład użycia klasy epView

<?php
  try {
    $template = new epView('default');

    $template->assign('title', 'Tytuł strony');
    $template->assign('body', 'Treść strony');
    $template->assign('footer', new epView('footer'));

    echo $template->render();
  } catch (Exception $e) {
    echo 'Error: ' . $e->getMessage();
  }
?>

Implementacja klasy epView

<?php
  interface epIView {
    public function render($flush = false);
    public function assign($name, $value);
  }

  /**
   * epView Class
   * Implements Composite View pattern
   */
  class epView implements epIView {
    private $data = array();
    private $fileName;

    public function __construct($fileName) {
      $this->fileName = $fileName . '.php';
      if (!file_exists($this->fileName)) {
        throw new Exception("Template '$fileName' not found.");
      }
    }

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

    public function render($flush = false) {
      foreach($this->data as $key => $val) {
        if ($val instanceof epIView) {
          $this->data[$key] = $val->render();
        }
      }
      extract($this->data, EXTR_SKIP);

      ob_start();
      include $this->fileName;
      $content = ob_get_clean();

      if ($flush)
        echo $content;
      else
        return $content;
    }

    public function __toString() {
      return $this->render();
    }
  }
?>

markac

Full-stack Web Developer