0251 / 590 837 15
info@a-coding-project.de
;

Template Engine (CMS)

Ich habe vor im CMS, das Design des Admin-Bereichs vom ausgewählten Skin abhängig zu machen. So können wir auch zum Beispiel auch einen mobilen Admin-Bereich erstellen. Außerdem wird es bald möglich sein im Skin Plugin-Ausgaben nach eigenen Wünschen zu gestalten.

Aus diesem Grund legen wir heute eine Template-Engine an. Die hier geschriebene Klasse entstand in einem Projekt, was ich derzeit mit Johann von Photohunters erstelle (mehr davon in Kürze). Ich hab das ganze noch ein wenig an ContentLion angepasst, so dass folgendes dabei herauskam /system/classes/template.php:

<?php
  class Template{
    private $template = "";
    private $loop_templates = array();
    private $template_path = "";
    private $loops = array();
  
    private function read_file($filename){
      $code = "";
        if(file_exists($filename)){
          $templatefile = fopen($filename, "r");
          while(!feof($templatefile)){
            $code = $code.fgets($templatefile, 1024);
          }
          fclose($templatefile);
        }
      return $code;
    }
  
    private function initialize_loops($template){
      preg_match_all("/{LOOP:([w]+)[^}]*}((s*?.*?)*){/LOOP:\1}/", $template, $matches, PREG_SET_ORDER);

      foreach ($matches as $match) {
        $template = str_ireplace($match[0], "<!--LOOP(".$match[1].")-->", $template);
        $this->loop_templates[strtoupper($match[1])] = $match[2];
        if(!array_key_exists(strtoupper($match[1]), $this->loops)){
          $this->loops[strtoupper($match[1])] = array();
        }
      }
    
      return $template;
  }
  
    public function load($template){
      if(file_exists($template)){
        $template = $this->read_file($template);
      }
      elseif(file_exists($this->template_path."/".$template)){
        $template = $this->read_file($template_path."/".$template);
      }
      $template = $this->initialize_loops($template);

      $this->template = $template;
    }
  
    public function assign($type, $field, $value){
      $this->template = str_ireplace('{'.strtoupper($type).':'.$field.'}', $value, $this->template);
    }
  
    public function assign_var($field, $value){
      $this->template = str_ireplace('{VAR:'.$field.'}', $value, $this->template);
    }
  
    public function add_loop_item($name){
      $res = 0;
    
      $this->loops[strtoupper($name)][] = $this->loop_templates[strtoupper($name)];
      $res = count($this->loops[strtoupper($name)]) - 1;
    
      return $res;
    }
  
    public function assign_loop_var($loop_name, $index, $field, $value){
      $this->loops[strtoupper($loop_name)][$index] = str_ireplace('{VAR:'.$field.'}', $value, $this->loops[strtoupper($loop_name)][$index]);
    }
  
    public function import($area, $template){
      if(file_exists($template)){
        $template = $this->read_file($template);
      }
      elseif(file_exists($this->template_path."/".$template)){
        $template = $this->read_file($template_path."/".$template);
      }
      $template = $this->initialize_loops($template);
   
      $this->template = str_ireplace('{INCLUDE:'.$area.'}', $template, $this->template);
    }
  
    public function output(){
      foreach($this->loops as $key => $array){
        $loop_template = implode("n", $array);
        $this->template = str_ireplace('<!--LOOP('.strtoupper($key).')-->', $loop_template, $this->template);
      }
    
      echo $this->template;
    }
  }
?>

Mit dieser Klasse können wir das Design von den Daten komplett trennen. In den eben genannten Projekt hat das meiner Meinung nach auch wunderbar geklappt. Auf die genauen Teile der Klasse gehe ich bei der Benutzung drauf ein.

Kommentare

Andiministrator schrieb am 04.04.2010:

Alle Achtung, ganz schön umfangreiches Projekt. Für die Templates hätte ich aber eine bestehende Engine eingebunden, z.B. Smarty. Das ganze Caching, Template-Script-Sprache, Parsing, etc. wäre mir dann doch zu aufwendig. Ich bin mal gespannt, wie es mit dem CMS weiter geht :)

Stefan Wienströer schrieb am 04.04.2010:

Danke! Für das andere Projekt hatten wir auch erst Smarty getestet, waren aber damit nicht so zufrieden.