Commit 25e82b3d by Qiang Xue

ViewRenderer WIP

parent a3963851
...@@ -359,6 +359,15 @@ class Application extends Module ...@@ -359,6 +359,15 @@ class Application extends Module
} }
/** /**
* Returns the view renderer.
* @return ViewRenderer the view renderer used by this application.
*/
public function getViewRenderer()
{
return $this->getComponent('viewRenderer');
}
/**
* Sets default path aliases. * Sets default path aliases.
*/ */
public function registerDefaultAliases() public function registerDefaultAliases()
......
...@@ -153,6 +153,59 @@ class View extends Component ...@@ -153,6 +153,59 @@ class View extends Component
} }
/** /**
* 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
*/
public function renderFile($viewFile, $data = null, $return = false)
{
$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;
} 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))));
}
}
/**
* 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.
*/
public function renderInternal($_viewFile_, $_data_ = null, $_return_ = false)
{
// 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_);
}
}
/**
* Creates a widget. * Creates a widget.
* This method will use [[Yii::createObject()]] to create the widget. * This method will use [[Yii::createObject()]] to create the widget.
* @param string $class the widget class name or path alias * @param string $class the widget class name or path alias
......
<?php
namespace yii\base;
/**
* Created by JetBrains PhpStorm.
* User: qiang
* Date: 2/1/13
* Time: 12:43 PM
* To change this template use File | Settings | File Templates.
*/
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
*/
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';
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment