Skip to content

Commit

Permalink
* (Fixes issue 1043) Improved view resolution to support using themea…
Browse files Browse the repository at this point in the history
…ble application views in a module
  • Loading branch information
qiang.xue committed Jun 17, 2010
1 parent 4f094d9 commit 7273b56
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 59 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Version 1.1.3 to be released
- Enh #952: Enhanced support for using defaultParams in CUrlManager (Qiang)
- Enh #1015: Added automatic column initialization when non-active data provider is used for CGridView (Qiang)
- Enh #1022: Added CMenu::activateItems (Qiang)
- Enh #1043: Improved view resolution to support using themeable application views in a module (Qiang)
- Enh #1127: Added support to automatically generate maxlength attribute for text/password inputs based on model rules (Qiang)
- Enh #1151: Added support to generate grid column header based on attribute names (Qiang)
- Enh #1158: Added translations in Latvian (lafriks)
Expand Down
4 changes: 2 additions & 2 deletions framework/cli/views/shell/crud/controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
class <?php echo $controllerClass; ?> extends Controller
{
/**
* @var string the default layout for the views. Defaults to 'column2', meaning
* @var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout='application.views.layouts.column2';
public $layout='//layouts/column2';

/**
* @var CActiveRecord the currently loaded data model instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
class Controller extends CController
{
/**
* @var string the default layout for the controller view. Defaults to 'application.views.layouts.column1',
* @var string the default layout for the controller view. Defaults to '//layouts/column1',
* meaning using a single column layout. See 'protected/views/layouts/column1.php'.
*/
public $layout='application.views.layouts.column1';
public $layout='//layouts/column1';
/**
* @var array context menu items. This property will be assigned to {@link CMenu::items}.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php $this->beginContent('application.views.layouts.main'); ?>
<?php $this->beginContent('//layouts/main'); ?>
<div class="container">
<div id="content">
<?php echo $content; ?>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php $this->beginContent('application.views.layouts.main'); ?>
<?php $this->beginContent('//layouts/main'); ?>
<div class="container">
<div class="span-19">
<div id="content">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
class <?php echo $this->controllerClass; ?> extends <?php echo $this->baseControllerClass."\n"; ?>
{
/**
* @var string the default layout for the views. Defaults to 'column2', meaning
* @var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout='column2';
public $layout='//layouts/column2';

/**
* @var CActiveRecord the currently loaded data model instance.
Expand Down
126 changes: 87 additions & 39 deletions framework/web/CController.php
Original file line number Diff line number Diff line change
Expand Up @@ -512,42 +512,79 @@ public function getViewPath()

/**
* Looks for the view file according to the given view name.
* This method will look for the view under the controller's {@link getViewPath viewPath}.
* If the view name starts with '/', the view will be looked for under the application's
* {@link CWebApplication::getViewPath viewPath}.
* The view script file is named as "ViewName.php". A localized view file
* may be returned if internationalization is needed. See {@link CApplication::findLocalizedFile}
* for more details.
* Since version 1.0.2, the view name can also refer to a path alias
* if it contains dot characters.
* Since version 1.0.3, if the controller belongs to a module, the view file
* will be searched under the {@link CWebModule::getViewPath module view path}.
* @param string name of the view (without file extension)
*
* When a theme is currently active, this method will call {@link CTheme::getViewFile} to determine
* which view file should be returned.
*
* Otherwise, this method will return the corresponding view file based on the following criteria:
* <ul>
* <li>absolute view within a module: the view name starts with a single slash '/'.
* In this case, the view will be searched for under the currently active module's view path.
* If there is no active module, the view will be searched for under the application's view path.</li>
* <li>absolute view within the application: the view name starts with double slashes '//'.
* In this case, the view will be searched for under the application's view path.
* This syntax has been available since version 1.1.3.</li>
* <li>aliased view: the view name contains dots and refers to a path alias.
* The view file is determined by calling {@link YiiBase::getPathOfAlias()}. Note that aliased views
* cannot be themed because they can refer to a view file located at arbitrary places.</li>
* <li>relative view: otherwise. Relative views will be searched for under the currently active
* controller's view path.</li>
* </ul>
*
* After the view file is identified, this method may further call {@link CApplication::findLocalizedFile}
* to find its localized version if internationalization is needed.
*
* @param string view name
* @return string the view file path, false if the view file does not exist
* @see resolveViewFile
* @see CApplication::findLocalizedFile
*/
public function getViewFile($viewName)
{
if(($theme=Yii::app()->getTheme())!==null && ($viewFile=$theme->getViewFile($this,$viewName))!==false)
return $viewFile;
$module=$this->getModule();
$basePath=$module ? $module->getViewPath() : Yii::app()->getViewPath();
return $this->resolveViewFile($viewName,$this->getViewPath(),$basePath);
$moduleViewPath=$basePath=Yii::app()->getViewPath();
if(($module=$this->getModule())!==null)
$moduleViewPath=$module->getViewPath();
return $this->resolveViewFile($viewName,$this->getViewPath(),$basePath,$moduleViewPath);
}

/**
* Looks for the view script file for a layout.
* This method will look for the view under the application's {@link CWebApplication::getLayoutPath layoutPath}.
* If the view name starts with '/', the view will be looked for under the application's
* {@link CWebApplication::getViewPath viewPath}.
* If the view name is null, the application's {@link CWebApplication::layout default layout}
* will be used. If the view name is false, this method simply returns false.
* Since version 1.0.2, the view name can also refer to a path alias
* if it contains dot characters.
* Since version 1.0.3, if the controller belongs to a module, the view file
* will be searched under the {@link CWebModule::getViewPath module layout path},
* and if the view name is null, the {@link CWebModule::layout module default layout}
* will be used.
* Looks for the layout view script based on the layout name.
*
* The layout name can be specified in one of the following ways:
*
* <ul>
* <li>layout is false: returns false, meaning no layout.</li>
* <li>layout is null: the currently active module's layout will be used. If there is no active module,
* the application's layout will be used.</li>
* <li>a regular view name.</li>
* </ul>
*
* The resolution of the view file based on the layout view is similar to that in {@link getViewFile}.
* In particular, the following rules are followed:
*
* Otherwise, this method will return the corresponding view file based on the following criteria:
* <ul>
* <li>When a theme is currently active, this method will call {@link CTheme::getLayoutFile} to determine
* which view file should be returned.</li>
* <li>absolute view within a module: the view name starts with a single slash '/'.
* In this case, the view will be searched for under the currently active module's view path.
* If there is no active module, the view will be searched for under the application's view path.</li>
* <li>absolute view within the application: the view name starts with double slashes '//'.
* In this case, the view will be searched for under the application's view path.
* This syntax has been available since version 1.1.3.</li>
* <li>aliased view: the view name contains dots and refers to a path alias.
* The view file is determined by calling {@link YiiBase::getPathOfAlias()}. Note that aliased views
* cannot be themed because they can refer to a view file located at arbitrary places.</li>
* <li>relative view: otherwise. Relative views will be searched for under the currently active
* module's layout path. In case when there is no active module, the view will be searched for
* under the application's layout path.</li>
* </ul>
*
* After the view file is identified, this method may further call {@link CApplication::findLocalizedFile}
* to find its localized version if internationalization is needed.
*
* @param mixed layout name
* @return string the view file for the layout. False if the view file cannot be found
*/
Expand All @@ -571,35 +608,41 @@ public function getLayoutFile($layoutName)
}
if($module===null)
$module=Yii::app();
return $this->resolveViewFile($module->layout,$module->getLayoutPath(),$module->getViewPath());
}
else
{
if(($module=$this->getModule())===null)
$module=Yii::app();
return $this->resolveViewFile($layoutName,$module->getLayoutPath(),$module->getViewPath());
$layoutName=$module->layout;
}
else if(($module=$this->getModule())===null)
$module=Yii::app();

return $this->resolveViewFile($layoutName,$module->getLayoutPath(),Yii::app()->getViewPath(),$module->getViewPath());
}

/**
* Finds a view file based on its name.
* The view name can be in one of the following formats:
* <ul>
* <li>absolute view: the view name starts with a slash '/'.</li>
* <li>absolute view within a module: the view name starts with a single slash '/'.
* In this case, the view will be searched for under the currently active module's view path.
* If there is no active module, the view will be searched for under the application's view path.</li>
* <li>absolute view within the application: the view name starts with double slashes '//'.
* In this case, the view will be searched for under the application's view path.
* This syntax has been available since version 1.1.3.</li>
* <li>aliased view: the view name contains dots and refers to a path alias.
* The view file is determined by calling {@link YiiBase::getPathOfAlias()}.</li>
* <li>relative view: otherwise.</li>
* The view file is determined by calling {@link YiiBase::getPathOfAlias()}. Note that aliased views
* cannot be themed because they can refer to a view file located at arbitrary places.</li>
* <li>relative view: otherwise. Relative views will be searched for under the currently active
* controller's view path.</li>
* </ul>
* For absolute view and relative view, the corresponding view file is a PHP file
* whose name is the same as the view name. The file is located under a specified directory.
* This method will call {@link CApplication::findLocalizedFile} to search for a localized file, if any.
* @param string the view name
* @param string the directory that is used to search for a relative view name
* @param string the directory that is used to search for an absolute view name
* @param string the directory that is used to search for an absolute view name under the application
* @param string the directory that is used to search for an absolute view name under the current module
* @return mixed the view file path. False if the view file does not exist.
* @since 1.0.3
*/
public function resolveViewFile($viewName,$viewPath,$basePath)
public function resolveViewFile($viewName,$viewPath,$basePath,$moduleViewPath)
{
if(empty($viewName))
return false;
Expand All @@ -609,7 +652,12 @@ public function resolveViewFile($viewName,$viewPath,$basePath)
else
$extension='.php';
if($viewName[0]==='/')
$viewFile=$basePath.$viewName;
{
if(strncmp($viewName,'//',2)===0)
$viewFile=$basePath.$viewName;
else
$viewFile=$moduleViewPath.$viewName;
}
else if(strpos($viewName,'.'))
$viewFile=Yii::getPathOfAlias($viewName);
else
Expand Down
25 changes: 13 additions & 12 deletions framework/web/CTheme.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ public function getSkinPath()
*/
public function getViewFile($controller,$viewName)
{
return $controller->resolveViewFile($viewName,$this->getViewPath().'/'.$controller->getUniqueId(),$this->getViewPath());
$moduleViewPath=$this->getViewPath();
if(($module=$controller->getModule())!==null)
$moduleViewPath.='/'.$module->getId();
return $controller->resolveViewFile($viewName,$this->getViewPath().'/'.$controller->getUniqueId(),$this->getViewPath(),$moduleViewPath);
}

/**
Expand All @@ -103,10 +106,10 @@ public function getViewFile($controller,$viewName)
*/
public function getLayoutFile($controller,$layoutName)
{
$basePath=$this->getViewPath();
$moduleViewPath=$basePath=$this->getViewPath();
$module=$controller->getModule();
if(empty($layoutName))
{
$module=$controller->getModule();
while($module!==null)
{
if($module->layout===false)
Expand All @@ -116,18 +119,16 @@ public function getLayoutFile($controller,$layoutName)
$module=$module->getParentModule();
}
if($module===null)
return $controller->resolveViewFile(Yii::app()->layout,$basePath.'/layouts',$basePath);
$layoutName=Yii::app()->layout;
else
{
$basePath.='/'.$module->getId();
return $controller->resolveViewFile($module->layout,$basePath.'/layouts',$basePath);
$layoutName=$module->layout;
$moduleViewPath.='/'.$module->getId();
}
}
else
{
if(($module=$controller->getModule())!==null)
$basePath.='/'.$module->getId();
return $controller->resolveViewFile($layoutName,$basePath.'/layouts',$basePath);
}
else if($module!==null)
$moduleViewPath.='/'.$module->getId();

return $controller->resolveViewFile($layoutName,$basePath.'/layouts',$basePath,$moduleViewPath);
}
}

0 comments on commit 7273b56

Please sign in to comment.