engine = $engine; $this->name = new Name($engine, $name); $this->data($this->engine->getData($name)); } /** * Magic method used to call extension functions. * @param string $name * @param array $arguments * @return mixed */ public function __call($name, $arguments) { return $this->engine->getFunction($name)->call($this, $arguments); } /** * Alias for render() method. * @throws \Throwable * @throws \Exception * @return string */ public function __toString() { return $this->render(); } /** * Assign or get template data. * @param array $data * @return mixed */ public function data(array $data = null) { if (is_null($data)) { return $this->data; } $this->data = array_merge($this->data, $data); } /** * Check if the template exists. * @return boolean */ public function exists() { return $this->name->doesPathExist(); } /** * Get the template path. * @return string */ public function path() { return $this->name->getPath(); } /** * Render the template and layout. * @param array $data * @throws \Throwable * @throws \Exception * @return string */ public function render(array $data = array()) { $this->data($data); unset($data); extract($this->data); if (!$this->exists()) { throw new LogicException( 'The template "' . $this->name->getName() . '" could not be found at "' . $this->path() . '".' ); } try { $level = ob_get_level(); ob_start(); include $this->path(); $content = ob_get_clean(); if (isset($this->layoutName)) { $layout = $this->engine->make($this->layoutName); $layout->sections = array_merge($this->sections, array('content' => $content)); $content = $layout->render($this->layoutData); } return $content; } catch (Throwable $e) { while (ob_get_level() > $level) { ob_end_clean(); } throw $e; } catch (Exception $e) { while (ob_get_level() > $level) { ob_end_clean(); } throw $e; } } /** * Set the template's layout. * @param string $name * @param array $data * @return null */ public function layout($name, array $data = array()) { $this->layoutName = $name; $this->layoutData = $data; } /** * Start a new section block. * @param string $name * @return null */ public function start($name) { if ($name === 'content') { throw new LogicException( 'The section name "content" is reserved.' ); } if ($this->sectionName) { throw new LogicException('You cannot nest sections within other sections.'); } $this->sectionName = $name; ob_start(); } /** * Start a new append section block. * @param string $name * @return null */ public function push($name) { $this->appendSection = true; $this->start($name); } /** * Stop the current section block. * @return null */ public function stop() { if (is_null($this->sectionName)) { throw new LogicException( 'You must start a section before you can stop it.' ); } if (!isset($this->sections[$this->sectionName])) { $this->sections[$this->sectionName] = ''; } $this->sections[$this->sectionName] = $this->appendSection ? $this->sections[$this->sectionName] . ob_get_clean() : ob_get_clean(); $this->sectionName = null; $this->appendSection = false; } /** * Alias of stop(). * @return null */ public function end() { $this->stop(); } /** * Returns the content for a section block. * @param string $name Section name * @param string $default Default section content * @return string|null */ public function section($name, $default = null) { if (!isset($this->sections[$name])) { return $default; } return $this->sections[$name]; } /** * Fetch a rendered template. * @param string $name * @param array $data * @return string */ public function fetch($name, array $data = array()) { return $this->engine->render($name, $data); } /** * Output a rendered template. * @param string $name * @param array $data * @return null */ public function insert($name, array $data = array()) { echo $this->engine->render($name, $data); } /** * Apply multiple functions to variable. * @param mixed $var * @param string $functions * @return mixed */ public function batch($var, $functions) { foreach (explode('|', $functions) as $function) { if ($this->engine->doesFunctionExist($function)) { $var = call_user_func(array($this, $function), $var); } elseif (is_callable($function)) { $var = call_user_func($function, $var); } else { throw new LogicException( 'The batch function could not find the "' . $function . '" function.' ); } } return $var; } /** * Escape string. * @param string $string * @param null|string $functions * @return string */ public function escape($string, $functions = null) { static $flags; if (!isset($flags)) { $flags = ENT_QUOTES | (defined('ENT_SUBSTITUTE') ? ENT_SUBSTITUTE : 0); } if ($functions) { $string = $this->batch($string, $functions); } return htmlspecialchars($string, $flags, 'UTF-8'); } /** * Alias to escape function. * @param string $string * @param null|string $functions * @return string */ public function e($string, $functions = null) { return $this->escape($string, $functions); } }