/** * Given a filename, render it as a ProcessWire template file * * This is a shortcut to using the TemplateFile class. * * File is assumed relative to /site/templates/ (or a directory within there) unless you specify a full path. * If you specify a full path, it will accept files in or below site/templates/, site/modules/, wire/modules/. * * Note this function returns the output for you to output wherever you want (delayed output). * For direct output, use the wireInclude() function instead. * * @param string $filename Assumed relative to /site/templates/ unless you provide a full path name with the filename. * If you provide a path, it must resolve somewhere in site/templates/, site/modules/ or wire/modules/. * @param array $vars Optional associative array of variables to send to template file. * Please note that all template files automatically receive all API variables already (you don't have to provide them) * @param array $options Associative array of options to modify behavior: * - defaultPath: Path where files are assumed to be when only filename or relative filename is specified (default=/site/templates/) * - autoExtension: Extension to assume when no ext in filename, make blank for no auto assumption (default=php) * - allowedPaths: Array of paths that are allowed (default is templates, core modules and site modules) * - allowDotDot: Allow use of ".." in paths? (default=false) * - throwExceptions: Throw exceptions when fatal error occurs? (default=true) * @return string|bool Rendered template file or boolean false on fatal error (and throwExceptions disabled) * @throws WireException if template file doesn't exist * */ function wireRenderFile($filename, array $vars = array(), array $options = array()) { $paths = wire('config')->paths; $defaults = array('defaultPath' => $paths->templates, 'autoExtension' => 'php', 'allowedPaths' => array($paths->templates, $paths->adminTemplates, $paths->modules, $paths->siteModules), 'allowDotDot' => false, 'throwExceptions' => true); $options = array_merge($defaults, $options); if (DIRECTORY_SEPARATOR != '/') { $filename = str_replace(DIRECTORY_SEPARATOR, '/', $filename); } // add .php extension if filename doesn't already have an extension if ($options['autoExtension'] && !strrpos(basename($filename), '.')) { $filename .= "." . $options['autoExtension']; } if (!$options['allowDotDot'] && strpos($filename, '..')) { // make path relative to /site/templates/ if filename is not an absolute path $error = 'Filename may not have ".."'; if ($options['throwExceptions']) { throw new WireException($error); } wire()->error($error); return false; } if ($options['defaultPath'] && strpos($filename, './') === 0) { $filename = rtrim($options['defaultPath'], '/') . '/' . substr($filename, 2); } else { if ($options['defaultPath'] && strpos($filename, '/') !== 0) { // filename is relative to defaultPath (typically /site/templates/) $filename = rtrim($options['defaultPath'], '/') . '/' . $filename; } else { if (strpos($filename, '/') !== false) { // filename is absolute, make sure it's in a location we consider safe $allowed = false; foreach ($options['allowedPaths'] as $path) { if (strpos($filename, $path) === 0) { $allowed = true; } } if (!$allowed) { $error = "Filename {$filename} is not in an allowed path."; if ($options['throwExceptions']) { throw new WireException($error); } wire()->error($error); return false; } } } } // render file and return output $t = new TemplateFile(); $t->setThrowExceptions($options['throwExceptions']); $t->setFilename($filename); foreach ($vars as $key => $value) { $t->set($key, $value); } return $t->render(); }
/** * Get the output TemplateFile object for rendering this page * * You can retrieve the results of this by calling $page->out or $page->output * * @internal This method is intended for internal use only, not part of the public API. * @param bool $forceNew Forces it to return a new (non-cached) TemplateFile object (default=false) * @return TemplateFile * */ public function output($forceNew = false) { if ($this->output && !$forceNew) { return $this->output; } if (!$this->template) { return null; } $this->output = new TemplateFile(); $this->output->setThrowExceptions(false); $this->output->setFilename($this->template->filename); $fuel = self::getAllFuel(); $this->output->set('wire', $fuel); foreach ($fuel as $key => $value) { $this->output->set($key, $value); } $this->output->set('page', $this); return $this->output; }