用户
 找回密码
 入住 CI 中国社区
搜索
查看: 5252|回复: 8
收起左侧

[讨论/交流] 页面布局layout,实现非views下视图的加载

[复制链接]
发表于 2012-11-21 16:41:47 | 显示全部楼层 |阅读模式
       今天学了一下CI的页面布局layout,很好用,谢谢哈。原帖网址:http://codeigniter.org.cn/forums/forum.php?mod=viewthread&tid=1176,再次感谢!
       但是以前用其他开发者写的框架的时候,发现他们的layout不是写在views下的,于是就想看看CI能不能也可以实现views目录以外的目录下视图的加载。
       ....
       终于,可以实现了。麻烦大家看看哈,不好之处请多多指教。
方法一:
1,在application/core下扩展核心类load(具体见手册),如:
class MY_Loader extends CI_Loader {
2,重写view方法:
PHP复制代码
function view($view, $vars = array(), $return = FALSE, $layout = FALSE)
{
if ($layout) //加载布局页面
{
$ext = pathinfo($view, PATHINFO_EXTENSION);
$view = ($ext == '') ? $view.EXT : $view;
$path = APPPATH.'layout/'.$view; //layout目录下的视图
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_path' => $path, '_ci_return'
$return));
}
else
{
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
}
}
复制代码

3,页面布局layout类(library目录)中的view方法:
  
PHP复制代码
function view($view, $data1=null, $return=false, $layout = TRUE) //$layout参数传递给扩展核心类my_load.
{
$data2['content_for_layout'] = $this->obj->load->view($view,$data1,true); //内容页,如同在视图中输出数据,不同的是此数据为一个内容页面
 
if($return)
{
$output = $this->obj->load->view($this->layout,$data2, true, $layout);
return $output;
}
else
{
$this->obj->load->view($this->layout,$data2, false, $layout); //视图(布局)下的视图($data2的索引下包括内容视图及$data1)
}
}
复制代码

//4,可参考module(hmvc架构)类对$layout进行动态赋值。

方法二:
1,同方法一第1步
2,添加属性:var $_ci_is_inside_layout = FALSE; // 判断是否调用布局
3,添加方法:
PHP复制代码
public function _ci_layout_ready()
{
$this->_ci_is_inside_layout = TRUE;
}
复制代码

4,重写view方法:
PHP复制代码
function view($view, $vars = array(), $return = FALSE)
{
if ($this->_ci_is_inside_layout) //加载布局页面
{
$ext = pathinfo($view, PATHINFO_EXTENSION);
$view = ($ext == '') ? $view.EXT : $view;
$path = APPPATH.'layout/'.$view;
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_path' => $path, '_ci_return'
=> $return));
}
else
{
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
}
}
复制代码


5,页面布局layout类(library目录)中的view方法:
  
PHP复制代码
function view($view, $data1=null, $return=false)
{
//$this->obj->load->_ci_layout_ready();//切记不能在此处调用。按代码先后执行的顺序是先执行下面一行的view,但是此view是要加载views目录下的视图,若取消
注释该行则执行下面一行的view方法后会跳到自己设定的目录下寻找视图。
$data2['content_for_layout'] = $this->obj->load->view($view,$data1,true); //内容页,如同在视图中输出数据,不同的是此数据为一个内容页面
$this->obj->load->_ci_layout_ready();
if($return)
{
$output = $this->obj->load->view($this->layout,$data2, true);
return $output;
}
else
{
$this->obj->load->view($this->layout,$data2, false); //视图(布局)下的视图($data2的索引下包括内容视图及$data1)
}
}
复制代码



评分

参与人数 1威望 +5 收起 理由
Hex + 5 赞一个!

查看全部评分

发表于 2012-11-21 16:59:01 | 显示全部楼层
好贴,学习了,过两天就要用到这个
 楼主| 发表于 2012-11-21 17:24:03 | 显示全部楼层
liuhejia460 发表于 2012-11-21 16:59
好贴,学习了,过两天就要用到这个

嗯,多多交流哈,我也刚学这个。
发表于 2012-11-21 17:32:40 | 显示全部楼层
xyst0524 发表于 2012-11-21 17:24
嗯,多多交流哈,我也刚学这个。

好的~~~多多交流
发表于 2012-11-22 01:17:05 | 显示全部楼层
多谢分享~~正好最近碰到这个问题 我用的是hex的HMVC

我直接将你这个layout加到MY_Loader.php中
PHP复制代码
 
    // --------------- Layout extends --------------
 
    private $layout = 'default';
 
    public function _ci_layout_ready() {
        $this->_ci_is_inside_layout = TRUE;
    }
 
    public function set_layout( $layout ) {
        $this->layout = $layout;
    }
 
    public function layout( $view, $data1 = null, $return = false ) {
         //内容页,如同在视图中输出数据,不同的是此数据为一个内容页面
        $data2['content'] = $this->view( $view, $data1, true );
        $this->_ci_layout_ready();
        if ( $return ) {
            $output = $this->view( $this->layout, $data2, true );
            return $output;
        } else {
            //视图(布局)下的视图($data2的索引下包括内容视图及$data1)
            $this->view( $this->layout, $data2, false );
        }
    }
 
复制代码


其中需要修改一下MY_Loader.php的view方法
PHP复制代码
 
    function view($view, $vars = array(), $return = FALSE)
    {
        if ($this->_ci_is_inside_layout)
        {
            //加载layout页面
            $ext = pathinfo($view, PATHINFO_EXTENSION);
            $view = ($ext == '') ? $view.EXT : $view;
            $path = APPPATH.'layout/'.$view;
            return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_path' => $path, '_ci_return'
            => $return));
        } else if ($this->_ci_is_inside_module) {
            //加载module中的views
            $ext = pathinfo($view, PATHINFO_EXTENSION);
            $view = ($ext == '') ? $view.EXT : $view;
            $path = APPPATH.'modules/'.$this->_ci_module_path.'/views/'.$view;
 
            if (file_exists($path))
            {
                return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_path' => $path, '_ci_return' => $return));
            }
            else
            {
                return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
            }
        }
        else
        {
            return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
        }
    }
 
复制代码


在application目录下创建layout/default.php
PHP复制代码
 
<h3>header</h3>
<?php echo $content; ?>
<h3>footer</h3>
 
复制代码


模块控制器调用视图时写成
PHP复制代码
 
// index为该模块views目录下的index.php视图文件
$this->load->layout( 'index' );
 
复制代码

 楼主| 发表于 2012-11-22 10:17:20 | 显示全部楼层
paperen 发表于 2012-11-22 01:17
多谢分享~~正好最近碰到这个问题 我用的是hex的HMVC

我直接将你这个layout加到MY_Loader.php中

呵呵,都写到一起去了。要是再扩展layout的话是不是有点臃肿啊?
发表于 2012-11-22 20:54:53 | 显示全部楼层
xyst0524 发表于 2012-11-22 10:17
呵呵,都写到一起去了。要是再扩展layout的话是不是有点臃肿啊?

好吧 我还是放出来吧 谢谢提醒
发表于 2013-1-21 09:53:42 | 显示全部楼层
学习 .。。学习!
发表于 2013-1-25 17:39:03 | 显示全部楼层
可以学习下 magento 的写法.. layout 调用 block ,block 调用 (block跟 数据) 嵌套式的,自己一直写不出来,有点麻烦。有需要的朋友可以去了解下,觉得很不错 magento 的不一样的mvc机制

本版积分规则