代码之家  ›  专栏  ›  技术社区  ›  Gary Green

Codeigniter:构造局部视图的最佳方法

  •  37
  • Gary Green  · 技术社区  · 15 年前

    你如何在Codeigniter中构建下面的页面?

    alt text

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

    1. 内容导航
    2. 排行榜

    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();
        }
    
    }
    

    显然是这个 load_controller $this->view->load()

    这可能是一个头痛的是有这个代码在所有的左侧导航链接,如新闻,用户,关于我们,等等。。但是,并不是每个导航链接都有所有这些部分,所以我需要将这些部分作为“局部视图”的灵活性

    有人能提出更好的方法吗?

    7 回复  |  直到 15 年前
        1
  •  26
  •   slikts    15 年前

    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);
        }
    
    }
    

    名为“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>
    

    _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');
        }
    }
    

    然后我可以像这样在视图中使用它的属性(这是填充 <head>

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

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

        2
  •  29
  •   alvincrespo    14 年前

    @Reinis的答案可能对CI 2.0以下的旧版本是正确的,但是从那以后有很多变化,所以我想我应该用我所做的最新方法来回答这个问题。

    大部分类似于@Reinis方法,这里也有描述: http://codeigniter.com/wiki/MY_Controller_-_how_to_extend_the_CI_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));
        }
    
    }
    

    <?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');
        }
    
    }
    

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

    第4步:在/application/views中创建一个基本视图并命名文件基本.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>
    

    <h1>Welcome</h1>
    

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

    <!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>
    

    如你所见 <h1>Welcome</h1>

    资源:

    希望这有助于其他人遇到这个技术。

        3
  •  6
  •   Phil Sturgeon    15 年前

    语法非常简单:

    // 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); 
    

    简单是吧?

    把它放进我的控制器里,就更简单了。

        4
  •  1
  •   Ross    15 年前

    你考虑过模板吗?只要稍加搜索,就可以找到许多不错的网站-请查看CI wiki。

    模板的作用或多或少与你所追求的一模一样。您定义了一个主模板和“节”,并且每次都为您加载它们

    template libraries in CI

        5
  •  1
  •   rkj    15 年前

    我会做一个我的控制器来处理这一切。你可以用一个布局(模板)/导航库来生成所有的布局、导航、显示/突出显示选中的菜单项、加载视图等。

    如果你对每个页面部分都使用一个控制器,我会说这不是正确的方法。您可以使用视图和嵌套视图。

        6
  •  1
  •   user767124 user767124    14 年前

    我喜欢菲尔·斯特金提到的。虽然它被认为是非常复杂,我真的很喜欢magento的模板结构。

    受这种结构方式的启发,我制定了我的逻辑,(这一点都不伟大,但它很简单,因为它可以,。或许我可以重写->view loader,让它接受某种对象作为模板名,然后根据需要加载结构)

    :必须非常负责地使用此方法(您必须在模板所需的控制器/方法中准备数据!

    第二 :模板需要正确准备和结构。

    我就是这么做的:

    • 在每个控制器中,我都有数组类型的属性,如下所示:

      class Main extends CI_Controller {
      
      public $view = Array(
              'theend' => 'frontend',
              'layout' => '1column',
              'mainbar' => array('content','next template file loaded under'),
              'sidebar' => array('generic','next template file loaded under'),
              'content' => '',
      );
      
    • public function index()
      {
      $data['view'] = $this->view;  // i take/load global class's attribute
      $data['view']['mainbar'] = Array('archive','related_posts'); // i change mainbar part of it
      // i add/load data that i need in all those templates that are needed $data['view'] also my using same Array  $data['my_required_data_that_i_use_in_template_files'] = 1;
      $this->load->view('main',$data); //
      }
      

    第三的

    /view/main.php <-- which basically just determines which side's wrapper of web to load (frontend or backend or some other)
    
    /view/frontend/wrapper.php
    
    /view/backend/wrapper.php
    
    /view/mobile/wrapper.php   <-- this wrappers are again another level of structuring for ex:
    
    /view/backend/layouts/   <-- inside i have templates different layouts like 1column.php 2columns-left (have left side is narrow one),2columns-right,3columns... etc...
    
    /view/backend/mainbar/   <-- inside i have templates for mainbar in pages
    
    /view/backend/mainbar/.../ <-- in the same way it's possible to add folders for easily grouping templates for example for posts so you add for example
    
        /view/backend/mainbar/posts/  <-- all templates for creating, editing etc posts... 
    
        /view/backend/sidebar/   <-- inside i have templates for sidebar in pages
    
        /view/backend/...other special cases.... like dashboard.php
    

    向前地 文件位于/app/view/主要.php看起来像:

    if ($view['theend'] == "frontend")
    {
    $this->load->view('/frontend/wrapper');
    } elseif ($view['theend'] == "backend")
    {
    $this->load->view('/backend/wrapper');
    }
    

    第五 包装器是一个简单的php在结构化HTML中,你有 标题(加载html标题、标题等…) 布局(加载在布局文件中,该文件只包含新的html结构化文件和下一级加载文件) footer/footers(如果有传入的$data['view']['footers']变量,则在footers中加载) 脚本(在tag之前加载inscript,比如analytics/facebook脚本)

    第六

    如果我需要某种方法,我只需重写公共$view=Array(…)属性的一部分,而只重写不同的部分。

    它是这样做的:

    public function index()
    {
        $data['view'] = $this->view;  // i take/load global class's attribute
        $data['view']['mainbar'] = Array('archive','related_posts'); // i change mainbar part of it
    // i add/load data that i need in all those templates that are needed $data['view'] also my using same Array  $data['my_required_data_that_i_use_in_template_files'] = 1;
        $this->load->view('main',$data); //
    }
    

    1. $this->加载->视图('main',$data);<--加载/app/view/主要.php并传递$数据

    2. 使用$data['view']['theend']中定义的数据加载适当的包装器

    3. 再次使用$data['view']['layout']中的数据在包装器中进一步加载其他更深层次的结构,如layout。。。
    4. 布局,使用相同的$data['view']['mainbar'],$data['view']['sidebar'],并捕获其他要加载的重要部分,如mainbar模板,sidebar模板。。。

    就这样。。。

        7
  •  -2
  •   Fanis Hatzidakis    15 年前

    <?php include 'leftMenu.php'; ?>
    
    推荐文章