Codeigniter:构建部分视图的最佳方式

Gar*_*een 37 php design-patterns codeigniter

如何在Codeigniter中构建以下页面?

替代文字

我想为每个部分创建单独的控制器

  1. 左导航
  2. 内容导航
  3. 登录名
  4. 排行榜

排除内容部分(因为此更改取决于左侧导航栏和内容导航栏中用作有点子菜单的链接).所有其他部分保持大致相同

我想过:

Class User_Profile extends Controller
{

    function index()
    {
        $this->load_controller('Left_Nav');
        $this->load_controller('Content_Nav');
        $this->load_controller('Login_Name');
        $this->load_controller('Leaderboard', 'Board');

        $this->Left_Nav->index(array('highlight_selected_page' => 'blah'));

        $this->load('User');

        $content_data = $this->User->get_profile_details();

        $this->view->load('content', $content_data);

        $this->Login_Name->index();
        $this->Board->index();
    }

}
Run Code Online (Sandbox Code Playgroud)

显然这load_controller不存在,但这种功能将是有用的.每个部分的控制器从模型中获取所需的数据,然后加载页面$this->view->load()

在新闻,用户,关于我们等所有左侧导航链接中使用此代码可能会令人头疼.但是,然后再次并非每个导航链接都包含所有这些部分,因此我需要将这些部分作为"部分"的灵活性视图"

谁能建议更好的方法呢?

alv*_*spo 29

@Reinis的答案可能正确地针对小于2.0的旧版本的CI正确地点击了,但是从那以后很多都发生了变化,所以我想我会用我所做的最新方法回答这个问题.

其中大部分类似于@Reinis方法,也在这里描述:http://codeigniter.com/wiki/MY_Controller_-_how_to_extend_the_CI_Controller

不过这是我做过的更新:

步骤1:创建一个MY_Controller.php文件并将其存储在/ application/core中

第2步:在MY_Controller.php文件中输入以下内容:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

    function __construct()
    {
        parent::__construct();
    }

    function _output($content)
    {
        // Load the base template with output content available as $content
        $data['content'] = &$content;
        echo($this->load->view('base', $data, true));
    }

}
Run Code Online (Sandbox Code Playgroud)

步骤3:创建一个基于MY_Controller.php的样本控制器,在这种情况下,我将在application/controllers /中创建一个welcome.php控制器,其中包含以下内容:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Welcome extends MY_Controller {

    function __construct()
    {
        parent::__construct();
    }

    public function index()
    {
        $this->load->view('welcome_message');
    }

}
Run Code Online (Sandbox Code Playgroud)

设置好这些控制器后,请执行以下操作:

步骤4:在/ application/views中创建一个基本视图并命名文件base.php,该文件的内容应类似于:

<!DOCTYPE html>
<!--[if IE 7 ]><html lang="en" class="ie7"><![endif]-->
<!--[if IE 8 ]><html lang="en" class="ie8"><![endif]-->
<!--[if gt IE 8]><!--><html lang="en"><!--<![endif]-->
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title></title> 
        <link rel="stylesheet" href="<?php echo base_url(); ?>stylesheets/reset.css" media="screen" />
    </head>
    <body>
        <div id="section_main">
            <div id="content">
                <?php echo $content; ?>
            </div>
        </div>
        <?php $this->load->view('shared/scripts.php'); ?>
        </div>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

步骤5:在/ application/views中创建另一个视图并将此视图命名为welcome_message.php,该文件的内容将为:

<h1>Welcome</h1>
Run Code Online (Sandbox Code Playgroud)

完成所有这些后,您应该看到以下输出:

<!DOCTYPE html>
<!--[if IE 7 ]><html lang="en" class="ie7"><![endif]-->
<!--[if IE 8 ]><html lang="en" class="ie8"><![endif]-->
<!--[if gt IE 8]><!--><html lang="en"><!--<![endif]-->
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title></title> 
        <link rel="stylesheet" href="http://somedomain.local/stylesheets/reset.css" media="screen" />
    </head>
    <body>
        <!-- BEGIN: section_main -->
        <div id="section_main">
            <div id="content">
                <h1>Welcome</h1>
            </div>
        </div>
        <!-- END: section_main -->
        <script src="/path/to/js.js"></script>
        </div>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

如您所见,<h1>Welcome</h1>已放入基本模板.

资源:

希望这可以帮助其他人遇到这种技术.

  • 如果您是从干净安装中执行此操作,则还需要在application/config/autoload.php中启用"url"帮助程序(使`base_url()`正常工作). (3认同)

sli*_*kts 23

我不能保证这是最好的方法,但我创建了一个这样的基本控制器:

class MY_Controller extends CI_Controller {

    public $title = '';
    // The template will use this to include default.css by default
    public $styles = array('default');

    function _output($content)
    {
        // Load the base template with output content available as $content
        $data['content'] = &$content;
        $this->load->view('base', $data);
    }

}
Run Code Online (Sandbox Code Playgroud)

名为"base"的视图是一个模板(包含其他视图的视图):

<?php echo doctype(); ?>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <?php $this->load->view('meta'); ?>
    </head>
    <body>
        <div id="wrapper">
            <?php $this->load->view('header'); ?>

            <div id="content">
                <?php echo $content; ?>
            </div>

            <?php $this->load->view('footer'); ?>
        </div>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

这实现了每个控制器将其输出包装在基本模板中,并且该视图具有有效的HTML而不是在一个视图中打开标记而在另一个视图中关闭.如果我想让特定的控制器使用不同的模板或不使用模板,我可以覆盖魔术_output()方法.

实际的控制器看起来像这样:

class Home extends MY_Controller {

    // Override the title
    public $title = 'Home';

    function __construct()
    {
        // Append a stylesheet (home.css) to the defaults
        $this->styles[] = 'home';
    }

    function index()
    {
        // The output of this view will be wrapped in the base template
        $this->load->view('home');
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以在我的视图中使用它的属性(这是填充<head>元素的'meta'视图):

echo "<title>{$this->title}</title>";
foreach ($this->styles as $url)
    echo link_tag("styles/$url.css");
Run Code Online (Sandbox Code Playgroud)

我喜欢我的方法,因为它尊重DRY原则,页眉,页脚和其他元素只包含在代码中一次.


Phi*_*eon 6

我的模板库可以处理所有这些.您可以创建一个(或多个)布局文件,其中包含部分内容以及主体内容所在位置的标记.

语法简单如下:

// Set the layout: defaults to "layout" in application/views/layout.php
$this->template->set_layout('whatever') 

// Load application/views/partials/viewname as a partial
$this->template->set_partial('partialname', 'partials/viewname');

// Call the main view: application/views/bodyviewname
$this->template->build('bodyviewname', $data); 
Run Code Online (Sandbox Code Playgroud)

简单吧?

将其中的一些放入MY_Controller,它更容易.