Guest User

Template engine

a guest
Aug 26th, 2014
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.25 KB | None | 0 0
  1. a just4fun php template implementation (just written, not tested :D)
  2.  
  3. 1) configuring a template
  4. <?php
  5. echo (new TemplateWrapper())
  6.   ->setFilter('upper', function ($value) {
  7.       return mb_strtoupper($value);
  8.   })->setFilter('replace', function ($value, $to, $with) {
  9.       return str_replace($to, $with, $value);
  10.   })->setParameter('text', 'Hello World')
  11.     ->render('/path/to/template.php');
  12.  
  13. 2) Template (/path/to/template.php)
  14. <p><?=$this->text; ?></p>
  15. <p><?=$this->text->upper(); ?></p>
  16. <p><?=$this->text->replace('Hello', 'Goodbye'); ?></p>
  17.  
  18. 3) Result
  19. Hello World
  20. HELLO WORLD
  21. Goodbye World
  22.  
  23. 4) Implementation
  24. <?php
  25. class TemplateNotFoundException extends InvalidArgumentException
  26. {
  27. }
  28.  
  29. class ItemNotFoundException extends InvalidArgumentException
  30. {
  31. }
  32.  
  33. class FilterNotFoundException extends InvalidArgumentException
  34. {
  35. }
  36.  
  37. class FilterIsFrozenException extends RuntimeException
  38. {
  39. }
  40.  
  41. interface RendererInterface
  42. {
  43.     public function render($template, array $attributes);
  44. }
  45.  
  46. class PHPRenderer implements RendererInterface
  47. {
  48.     public function render($template, array $attributes)
  49.     {
  50.         if (!file_exists($template)) {
  51.             throw new TemplateNotFoundException;
  52.         }
  53.  
  54.         $approach = function () use ($template) {
  55.             ob_start();
  56.  
  57.             require $template;
  58.  
  59.             return ob_get_clean();
  60.         };
  61.         $scope = new ArrayObject($attributes, ArrayObject::ARRAY_AS_PROPS);
  62.         $approach->bindTo($scope, ArrayObject::class);
  63.  
  64.         return $approach();
  65.     }
  66. }
  67.  
  68. class TemplateParameter
  69. {
  70.     private $value;
  71.     private $filters = array();
  72.  
  73.     public function __construct($value, array $filters = array())
  74.     {
  75.         $this->value = (string)$value;
  76.         $this->filters = $filters;
  77.     }
  78.  
  79.     public function __toString()
  80.     {
  81.         return htmlspecialchars($this->value);
  82.     }
  83.  
  84.     public function __call($methodName, array $args = array())
  85.     {
  86.         if (!isset($this->filters[$methodName])) {
  87.             throw new FilterNotFoundException;
  88.         }
  89.  
  90.         return call_user_func_array($this->filters[$methodName], array_merge([$this->value], $args));
  91.     }
  92. }
  93.  
  94. class ParameterBag implements IteratorAggregate
  95. {
  96.     private $params = array();
  97.  
  98.     public function getIterator()
  99.     {
  100.         return new ArrayIterator($this->params);
  101.     }
  102.  
  103.     public function set($name, TemplateParameter $value)
  104.     {
  105.         $this->params[$name] = $value;
  106.         return $this;
  107.     }
  108.  
  109.     public function remove($name)
  110.     {
  111.         if (isset($this->params[$name])) {
  112.             unset($this->params[$name];
  113.             return $this;
  114.         }
  115.  
  116.         throw new ItemNotFoundException;
  117.     }
  118.  
  119.     public function get($name)
  120.     {
  121.         if (!isset($this->params[$name])) {
  122.             throw new ItemNotFoundException;
  123.         }
  124.  
  125.         return $this->params[$name];
  126.     }
  127.  
  128.     public function clear()
  129.     {
  130.         $this->params = array();
  131.     }
  132. }
  133.  
  134. class FilterBag extends ParameterBag implements IteratorAggregate
  135. {
  136.     public function set($name, callable $value)
  137.     {
  138.         parent::set($name, $value);
  139.     }
  140. }
  141.  
  142. class TemplateWrapper
  143. {
  144.     private $renderer;
  145.     private $frozenFilters = array();
  146.     private $filters;
  147.     private $parameters;
  148.  
  149.     public function __construct(RendererInterface $renderer = null)
  150.     {
  151.         $this->renderer = $renderer ?: new PHPRenderer();
  152.         $this->parameters = new ParameterBag();
  153.         $this->filters = new FilterBag();
  154.     }
  155.  
  156.     public function reset()
  157.     {
  158.         $this->parameters = new ParameterBag();
  159.         $this->filters = new FilterBag();
  160.     }
  161.  
  162.     public function setFilter($name, callable $filter)
  163.     {
  164.         $this->filters->set($name, $value);
  165.         return $this;
  166.     }
  167.  
  168.     public function setParameter($name, $value)
  169.     {
  170.         $this->parameters->set($name, $this->createParameterSkeleton($value));
  171.         return $this;
  172.     }
  173.  
  174.     public function render($template)
  175.     {
  176.         return $this->renderer->render($template, iterator_to_array($this->parameters->getIterator()));
  177.     }
  178.  
  179.     protected function createParameterSkeleton($value)
  180.     {
  181.         return new TemplateParameter($value, iterator_to_array($this->filters->getIterator()));
  182.     }
  183. }
Advertisement
Add Comment
Please, Sign In to add comment