render()内容;
public function render($view,$data=null,$return=false) { if($this->beforeRender($view)) { $output=$this->renderPartial($view,$data,true); if(($layoutFile=$this->getLayoutFile($this->layout))!==false) $output=$this->renderFile($layoutFile,array('content'=>$output),true); $this->afterRender($view,$output); $output=$this->processOutput($output); if($return) return $output; else echo $output; } }
调用render()时首先调用renderPartial();
public function renderPartial($view,$data=null,$return=false,$processOutput=false) { if(($viewFile=$this->getViewFile($view))!==false) { $output=$this->renderFile($viewFile,$data,true); if($processOutput) $output=$this->processOutput($output); if($return) return $output; else echo $output; } else throw new CException(Yii::t('yii','{controller} cannot find the requested view "{view}".', array('{controller}'=>get_class($this), '{view}'=>$view))); }
renderPartial()则调用getViewFile()
真正发现问题从这里开始
public function getViewFile($viewName) { // 检查是否使用theme,如果存在theme且可以在主题目录找到文件,则返回 if(($theme=Yii::app()->getTheme())!==null && ($viewFile=$theme->getViewFile($this,$viewName))!==false) return $viewFile; // 当未使用theme时 // $moduleViewPath,$basePath 默认视图路径,即根目录下的views路径 $moduleViewPath=$basePath=Yii::app()->getViewPath(); // 如果是模块,则返回resolveViewFile() // '$this->getViewPath()'是控制器对应的默认视图路径 // 如果在模块下,就会指向模块的views目录 if(($module=$this->getModule())!==null) $moduleViewPath=$module->getViewPath(); return $this->resolveViewFile($viewName,$this->getViewPath(),$basePath,$moduleViewPath); }
ok,开始调用resolveViewFile()
public function resolveViewFile($viewName,$viewPath,$basePath,$moduleViewPath=null) { // 没有视图文件名 if(empty($viewName)) return false; // 没有模块的视图路径 ??? // 没遇到过 if($moduleViewPath===null) $moduleViewPath=$basePath; // 没有写扩展名,则使用默认扩展名"php" if(($renderer=Yii::app()->getViewRenderer())!==null) $extension=$renderer->fileExtension; else $extension='.php'; if($viewName[0]==='/') { // 如果视图名是以双反斜杠开头 if(strncmp($viewName,'//',2)===0) // '默认视图路径 . 视图文件名' $viewFile=$basePath.$viewName; else // '模块视图路径. 视图文件名' // 根据 getViewFile()传递的参数来看,两者是一样的 ??? $viewFile=$moduleViewPath.$viewName; } // 也就是说以双反斜杠开头表示以根目录下的views为基础路径 // 如果文件名包含'.' elseif(strpos($viewName,'.')) 表示使用Yii的路径别名 $viewFile=Yii::getPathOfAlias($viewName); // 没有双反斜杠开头和'.'的情况, else // 控制器的对应的视图路径中的文件 // 这个应该是通常最频繁使用的情况---直接写视图名称 $viewFile=$viewPath.DIRECTORY_SEPARATOR.$viewName; if(is_file($viewFile.$extension)) return Yii::app()->findLocalizedFile($viewFile.$extension); elseif($extension!=='.php' && is_file($viewFile.'.php')) return Yii::app()->findLocalizedFile($viewFile.'.php'); else return false; }
结论:
1.控制器中的视图路径以themes最为优先
2.其次是根目录下的views
3.然后是别名
4.最后是控制器对应的views