/** * returns the given template rendered using the provided data and optional compiler * @param mixed $_tpl template, can either be a ITemplate object (i.e. Template\File), a valid path to a template, or * a template as a string it is recommended to provide a ITemplate as it will probably make things faster, * especially if you render a template multiple times * @param mixed $data the data to use, can either be a IDataProvider object (i.e. Data) or an associative array. if you're * rendering the template from cache, it can be left null * @param ICompiler $_compiler the compiler that must be used to compile the template, if left empty a default * Compiler will be used. * @param bool $_output flag that defines whether the function returns the output of the template (false, default) or echoes it directly (true) * @throws Exception * @throws \Exception * @throws Exception\CoreException * @return string|null or the template output if $output is false */ public function get($_tpl, $data = array(), $_compiler = null, $_output = false) { // a render call came from within a template, so we need a new dwoo instance in order to avoid breaking this one if ($this->template instanceof ITemplate) { $clone = clone $this; return $clone->get($_tpl, $data, $_compiler, $_output); } // auto-create template if required if ($_tpl instanceof ITemplate) { // valid, skip } elseif (is_string($_tpl)) { $_tpl = new File($_tpl); $_tpl->setIncludePath($this->templateDir); } else { throw new CoreException('Dwoo->get/Dwoo->output\'s first argument must be a \\Dwoo\\ITemplate (i.e. \\Dwoo\\Template\\File) or a valid path to a template file. Got: ' . $_tpl, E_USER_NOTICE); } // Put debug mode value $_tpl->setDebugMode($this->debugMode); // save the current template, enters render mode at the same time // if another rendering is requested it will be proxied to a new Core instance $this->template = $_tpl; // load data if ($data instanceof IDataProvider) { $this->data = $data->getData(); } elseif (is_array($data)) { $this->data = $data; } elseif ($data instanceof \ArrayAccess) { $this->data = $data; } else { throw new CoreException('Dwoo->get/Dwoo->output\'s data argument must be a \\Dwoo\\IDataProvider object (i.e. \\Dwoo\\Data) or an associative array', E_USER_NOTICE); } $this->globals['template'] = $_tpl->getName(); $this->initRuntimeVars($_tpl); // try to get cached template $file = $_tpl->getCachedTemplate($this); $doCache = $file === true; $cacheLoaded = is_string($file); if ($cacheLoaded === true) { // cache is present, run it if ($_output === true) { include $file; $this->template = null; } else { ob_start(); include $file; $this->template = null; return ob_get_clean(); } } else { // no cache present if ($doCache === true) { $dynamicId = uniqid(); } $recompile = false; do { // render template try { $compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler); $out = (include $compiledTemplate); } catch (Exception $e) { // output if ($_output === true) { ob_flush(); } else { ob_clean(); } throw $e; } if ($out === false) { // template returned false so it needs to be recompiled if ($recompile) { // this is the second time this happened... throw new Exception('Failed to compile template.'); } $_tpl->forceCompilation(); $recompile = true; } } while ($recompile); if ($doCache === true) { $out = preg_replace('/(<%|%>|<\\?php|<\\?|\\?>)/', '<?php /*' . $dynamicId . '*/ echo \'$1\'; ?>', $out); $out = BlockDynamic::unescape($out, $dynamicId, $compiledTemplate); } // process filters foreach ($this->filters as $filter) { if (is_array($filter) && $filter[0] instanceof Filter) { $out = call_user_func($filter, $out); } else { $out = call_user_func($filter, $this, $out); } } if ($doCache === true) { // building cache $file = $_tpl->cache($this, $out); // run it from the cache to be sure dynamics are rendered if ($_output === true) { include $file; // exit render mode $this->template = null; } else { ob_start(); include $file; // exit render mode $this->template = null; return ob_get_clean(); } } else { // no need to build cache // exit render mode $this->template = null; // output if ($_output === true) { echo $out; } return $out; } } return null; }