我以前做的系统都是frameset的。这样有个好处就是代码精简,crud生成的代码基本够用。但有个不好的地方就是div的弹出不能超过边界。
我个人感觉如果用layout的话,则需要考虑到全局代码和提取数据,这样会+大代码复杂性。因为后台管理界面有时候是上下方式(上面菜单导航,下面主工作界面),有时候是上左右方式(上面菜单导航,下面是左右分开,左边子导航,右边主工作界面)。如果用一个layout还是做不到精简的样子。还得右边用widget。增加而外代码。如果用crud生成的代码是需要大改动的。
我以前做的系统都是frameset的。这样有个好处就是代码精简,crud生成的代码基本够用。但有个不好的地方就是div的弹出不能超过边界。
我个人感觉如果用layout的话,则需要考虑到全局代码和提取数据,这样会+大代码复杂性。因为后台管理界面有时候是上下方式(上面菜单导航,下面主工作界面),有时候是上左右方式(上面菜单导航,下面是左右分开,左边子导航,右边主工作界面)。如果用一个layout还是做不到精简的样子。还得右边用widget。增加而外代码。如果用crud生成的代码是需要大改动的。
尽量少用frameset,因为用户体验不好(尤其是前后翻页)。layout用好的话是可以很灵活的。
我最近做的一个项目需要有1列,2列和3列三种不同的layout。我是这样组织的:
在layouts目录下有:
main layout: main.php
child layout: layout1.php, layout2.php, layout3.php
main.php和平常的一样,layoutX.php实现X列的layout,main.php是它的parent layout。下面是layout2.php的代码:
<?php $this->beginContent(); ?> <div class="grid_4 alpha"> <div class="sidebar"> <?php foreach($this->portlets as $portlet) $this->renderPortlet($portlet); ?> </div> </div> <div class="grid_12 omega"> <?php $this->widget('Breadcrumbs', array('crumbs'=>$this->crumbs)); ?> <div id="content"> <?php echo $content; ?> </div> </div> <?php $this->endContent(); ?>
左边是一列portlets,右边上边是breadcrumbs,下边是主内容。
使用上略微复杂。下面是post list view:
<?php $this->layout='layout2'; $this->portlets[]=array('class'=>'LetterFilterPortlet', 'selection'=>$form->letter); $this->portlets[]=array('class'=>'StatusFilterPortlet', 'selection'=>$form->status); $this->portlets[]=array('class'=>'CityFilterPortlet', 'selection'=>$form->city); $this->portlets[]=array('class'=>'CategoryFilterPortlet', 'selection'=>$form->category); ?> <h1>Posts</h1> <?php $this->renderPartial('_list',array( 'pages'=>$pages, 'models'=>$models, )); ?>
其中portlets的代码可以进一步优化(例如从数据库里读配置)。最前面的一段代码也可以移到controller里去做,或是通过一个函数来做。
怎么让main.php是layout2.php的父layout?我看了您在别的帖子写的
<?php $this->beginContent('/path/to/layoutB'); ?> stuff for layout A <?php echo $content; ?> this is from the view stuff for layout A <?php $this->endContent(); ?>
beginContent里面会调用父layout。但这里没有这么写?难道哪里可以配置吗?
谢谢指教。
假如beginContent()里没有参数,那么view的内容将被插入到当前controller缺省的layout,也就是main.php
action里面定义了layout属性,但没有找到layout,没有报错。只出view的内容。
public function actionAdmin(){ $this->layout='layout2'; ... $this->render('admin',array( 'parentOrgan'=>$parentOrgan, 'organList'=>$organList, 'pages'=>$pages, 'sort'=>$sort, ),false,true);
系统采用了module和theming了。layout2.php放在themes\classic\views\layouts下面,配置文件配置了classis 这个theming激活。
如果你这个action是在一个module里的话,layout2只在module的layouts目录下找。
<div class="grid_4 alpha">
<div class="sidebar">&nbsp;
<?php foreach($this->portlets as $portlet) $this->renderPortlet($portlet); ?>
</div>
</div>
不明白$this->renderPortlet($portlet);在这里的意义。为什么不直接widget,还要包装。是不是有哪些要处理?
renderPortlet是做了一些处理,不过你用widget也是可以的。看你自己的需要了。
我还是想不通,$portlet就两个属性,一个class一个selection,再怎么变数也没法用一个统一的renderPortlet来做处理啊?用下面代码
<?php foreach($this->portlets as $portlet) $this->widget($portlet->class,array($portlet->selection)); ?>应该可以的?
可以举例renderPortlet里有什么特殊处理吗?
差不多是这样。单独写个函数是为了看起来更清晰。事实上,可能写个renderPortlets更有意义。毕竟这个函数是需要在每个页面上调用的。
Quote
刚在你的教程下提了个问题,但格式有问题,我在这里在贴一下:
I have some issues to have this work with theme,
for example,
here is the index.php view file
<?php $this->layout='column1'; ?> TEST
and this is colum1.php layout file:
<?php $this->beginContent(); ?> <div id="content"> <?php echo $content; ?> </div> <?php $this->endContent(); ?>
the problem is column1 layout was rendered, but main.php layout wasn't.
Any idea?
你的column1.php和main.php都在theme里么?
Quote
没错,都在 /themes/classic/views/layouts 同一个folder下
我刚试过,没问题啊。
我用的是yiic webapp产生的testdrive。在app config里使用classic theme。在index view里设定用column1.php。
Quote
我用的是yiic webapp产生的testdrive。在app config里使用classic theme。在index view里设定用column1.php。
不好意思,确认了,在一般app里面是好的。
但使用Module时就不行,我现在用module command 建了一个module: testmodule, 在theme目录下建立:
/themes/classic/views/testmodule/layouts (里面有 main.php, column1.php)
/themes/classic/views/testmodule/default (里面有 index.php)
php文件都是和上面中同样的内容, 现在的问题是, Yii 正确使用了
/themes/classic/views/testmodule/layouts/column1.php
但父layout文件使用的是:
/themes/classic/views/layouts/main.php
应该使用
/themes/classic/views/testmodule/layouts/main.php
有什么地方错了吗?
你的module没有设置layout属性吧?如果没设的话,用的是application的layout。
Quote
我在TestModule.php 里面加了:
public function init() { // this method is called when the module is being created // you may place code here to customize the module or the application // import the module-level models and components $this->setImport(array( 'testmodule.models.*', 'testmodule.components.*', )); $this->setLayoutPath('themes/classic/views/testmodule/layouts'); }
还是一样的结果,设定有什么不对吗?
问题是,为什么可以找到module layout 的 column1.php 却不能找到 main.php?
我说的是module的layout属性。它的缺省值是null,意思是用application定义的layout。
用下面的代码就可以了:
class MyModule extends CWebModule { public $layout='main'; }
Quote
用下面的代码就可以了:
class MyModule extends CWebModule { public $layout='main'; }
明白了,谢谢!