From e3c85b478ea06a18f87256ae0b087055914a7f86 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 1 Feb 2013 14:55:37 -0500 Subject: [PATCH] Finished ViewRenderer. --- framework/base/View.php | 83 +++++++++++++-------------------------- framework/base/ViewRenderer.php | 86 ++++++++++------------------------------- todo.md | 3 ++ 3 files changed, 50 insertions(+), 122 deletions(-) diff --git a/framework/base/View.php b/framework/base/View.php index cd6e070..410e3c5 100644 --- a/framework/base/View.php +++ b/framework/base/View.php @@ -137,72 +137,43 @@ class View extends Component /** * Renders a view file. - * This method will extract the given parameters and include the view file. - * It captures the output of the included view file and returns it as a string. - * @param string $_file_ the view file. - * @param array $_params_ the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return string the rendering result - */ - public function renderFile($_file_, $_params_ = array()) - { - ob_start(); - ob_implicit_flush(false); - extract($_params_, EXTR_OVERWRITE); - require($_file_); - return ob_get_clean(); - } - - /** - * Renders a view file. * - * @param string $viewFile view file path - * @param array $data data to be extracted and made available to the view - * @param boolean $return whether the rendering result should be returned instead of being echoed - * @return string the rendering result. Null if the rendering result is not required. - * @throws CException if the view file does not exist + * If a [[ViewRenderer|view renderer]] is installed, this method will try to use the view renderer + * to render the view file. Otherwise, it will simply include the view file, capture its output + * and return it as a string. + * + * @param string $file the view file. + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return string the rendering result */ - public function renderFile($viewFile, $data = null, $return = false) + public function renderFile($file, $params = array()) { - $widgetCount = count($this->_widgetStack); - if (($renderer = Yii::$application->getViewYii::app()->getViewRenderer()) !== null && $renderer->fileExtension === '.' . CFileHelper::getExtension($viewFile)) { - $content = $renderer->renderFile($this, $viewFile, $data, $return); - } else { - $content = $this->renderInternal($viewFile, $data, $return); - } - if (count($this->_widgetStack) === $widgetCount) { - return $content; + $renderer = Yii::$application->getViewRenderer(); + if ($renderer !== null) { + return $renderer->render($this, $file, $params); } else { - $widget = end($this->_widgetStack); - throw new CException(Yii::t('yii', '{controller} contains improperly nested widget tags in its view "{view}". A {widget} widget does not have an endWidget() call.', - array('{controller}' => get_class($this), '{view}' => $viewFile, '{widget}' => get_class($widget)))); + return $this->renderPhpFile($file, $params); } } /** - * Renders a view file. - * This method includes the view file as a PHP script - * and captures the display result if required. - * @param string $_viewFile_ view file - * @param array $_data_ data to be extracted and made available to the view file - * @param boolean $_return_ whether the rendering result should be returned as a string - * @return string the rendering result. Null if the rendering result is not required. + * Renders a view file as a PHP script. + * + * This method treats the view file as a PHP script and includes the file. + * It extracts the given parameters and makes them available in the view file. + * The method captures the output of the included view file and returns it as a string. + * + * @param string $_file_ the view file. + * @param array $_params_ the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return string the rendering result */ - public function renderInternal($_viewFile_, $_data_ = null, $_return_ = false) + public function renderPhpFile($_file_, $_params_ = array()) { - // we use special variable names here to avoid conflict when extracting data - if (is_array($_data_)) { - extract($_data_, EXTR_PREFIX_SAME, 'data'); - } else { - $data = $_data_; - } - if ($_return_) { - ob_start(); - ob_implicit_flush(false); - require($_viewFile_); - return ob_get_clean(); - } else { - require($_viewFile_); - } + ob_start(); + ob_implicit_flush(false); + extract($_params_, EXTR_OVERWRITE); + require($_file_); + return ob_get_clean(); } /** diff --git a/framework/base/ViewRenderer.php b/framework/base/ViewRenderer.php index 4044edf..ecb216d 100644 --- a/framework/base/ViewRenderer.php +++ b/framework/base/ViewRenderer.php @@ -1,78 +1,32 @@ + * @since 2.0 */ abstract class ViewRenderer extends Component { /** - * @var boolean whether to store the parsing results in the application's - * runtime directory. Defaults to true. If false, the parsing results will - * be saved as files under the same directory as the source view files and the - * file names will be the source file names appended with letter 'c'. - */ - public $useRuntimePath = true; - /** - * @var integer the chmod permission for temporary directories and files - * generated during parsing. Defaults to 0755 (owner rwx, group rx and others rx). - */ - public $filePermission = 0755; - /** - * @var string the extension name of the view file. Defaults to '.php'. - */ - public $fileExtension = '.php'; - - /** - * Parses the source view file and saves the results as another file. - * @param string $sourceFile the source view file path - * @param string $viewFile the resulting view file path - */ - abstract protected function generateViewFile($sourceFile, $viewFile); - - /** * Renders a view file. - * This method is required by {@link IViewRenderer}. - * @param CBaseController $context the controller or widget who is rendering the view file. - * @param string $sourceFile the view file path - * @param mixed $data the data to be passed to the view - * @param boolean $return whether the rendering result should be returned - * @return mixed the rendering result, or null if the rendering result is not needed. - */ - public function renderFile($context, $sourceFile, $data, $return) - { - if (!is_file($sourceFile) || ($file = realpath($sourceFile)) === false) { - throw new CException(Yii::t('yii', 'View file "{file}" does not exist.', array('{file}' => $sourceFile))); - } - $viewFile = $this->getViewFile($sourceFile); - if (@filemtime($sourceFile) > @filemtime($viewFile)) { - $this->generateViewFile($sourceFile, $viewFile); - @chmod($viewFile, $this->filePermission); - } - return $context->renderInternal($viewFile, $data, $return); - } - - /** - * Generates the resulting view file path. - * @param string $file source view file path - * @return string resulting view file path + * + * This method is invoked by [[View]] whenever it tries to render a view. + * Child classes must implement this method to render the given view file. + * + * @param View $view the view object used for rendering the file. + * @param string $file the view file. + * @param array $params the parameters to be passed to the view file. + * @return string the rendering result */ - protected function getViewFile($file) - { - if ($this->useRuntimePath) { - $crc = sprintf('%x', crc32(get_class($this) . Yii::getVersion() . dirname($file))); - $viewFile = Yii::app()->getRuntimePath() . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . $crc . DIRECTORY_SEPARATOR . basename($file); - if (!is_file($viewFile)) { - @mkdir(dirname($viewFile), $this->filePermission, true); - } - return $viewFile; - } else { - return $file . 'c'; - } - } + abstract public function render($view, $file, $params); } diff --git a/todo.md b/todo.md index 7517b07..60e37c5 100644 --- a/todo.md +++ b/todo.md @@ -5,6 +5,9 @@ * mongodb (put it under framework/db/mongodb) * key-value-based (should allow storage-specific methods additionally to generic ones) * redis (put it under framework/db/redis or perhaps framework/caching?) +- base + * TwigViewRenderer + * SmartyViewRenderer - logging * WebTarget (TBD after web is in place): should consider using javascript and make it into a toolbar * ProfileTarget (TBD after web is in place): should consider using javascript and make it into a toolbar