Codeigniter:构build部分视图的最佳方法

如何构buildCodeigniter中的下一页?

替代文字

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

  1. 左导航
  2. 内容导航
  3. login名
  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(); } } 

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

在新闻,用户,关于我们等所有的左侧导航链接中都有这样的代码可能会让人头痛。但是再次不是每个导航链接都有这些部分,所以我需要将部分作为“部分视图”

任何人都可以提出一个更好的方式做到这一点

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

 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> 

实现的方式是每个控制器将其输出封装在基本模板中,并且该视图具有有效的HTML,而不是在一个视图中打开标签并在另一个视图中closures。 如果我想要一个特定的控制器来使用不同的模板或者不使用模板,我可以重写magic _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>元素的'meta'视图):

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

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

@Reinis的答案可能正确地对老版本的CI小于2.0的点击,但是自那时以来有很多改变,所以我想我会回答这个问题,我已经做了最新的方法。

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

但是,这里是更新完成:

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

第2步:在你的MY_Controller.php文件中join以下内容:

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

第3步:创build一个基于MY_Controller.php的示例控制器,在这种情况下,我将在application / controllers /中创build一个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'); } } 

一旦您设置了这些控制器,请执行以下操作:

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

第5步:在/ application / views中创build另一个视图,并将这个视图命名为welcome_message.php,这个文件的内容是:

 <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>被放入了基本模板。

资源:

希望这可以帮助任何人碰到这种技术。

我的模板库可以处理所有这些。 您可以创build一个(或多个)布局文件,其中包含部分内容和主体内容所在的标签。

语法如下所示:

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

简单对吧?

把一些这样的东西放到MY_Controller中,它就更简单了。

你有没有考虑模板? 有许多体面的可用一点search – 检查CI维基。

模板可以或多或less地完成你正在做的事情。 您定义了一个主模板和“部分”,每次都会为您加载这些模板

不想插太多,所以这可能会让你开始 – CI中的模板库

我会做一个MY_Controller照顾这一切。 您可以使用布局(模板)/导航库将其置顶,以生成所有布局,导航,显示/突出显示所选菜单项,加载视图等。

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

我喜欢Phil Sturgeon所提到的。 虽然它被认为是非常复杂的,我真的很喜欢magento所具有的模板结构。

受到这种构build方式的启发,我创build了自己的逻辑,(虽然它不是很好,但它很简单,也许我可以重写 – >查看加载器并使其接受某种对象作为模板名称,根据需要加载结构)

第一 :这种方法必须非常负责任地使用(你准备在你的模板需要的控制器/方法中的数据!

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

这是我做的:

  • 在每一个控制器我有属性的数组types,如下所示:

     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/main.php中的第四个文件看起来像这样:

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

第五个包装是简单的一些PHP在结构化的HTML你有头(加载HTML标题,标题等…)头/头(如果有任何在传递$数据[加载标题中''视图'] ['头']variables/数组)布局(加载布局文件,只是具有新的HTML结构化文件与下一级加载文件)页脚/页脚(如果有任何在传递的$ data ['view'] ['footers']variables中加载页脚)脚本(在标记之前加载像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. $这 – >负载>视图( '主',$数据); < – 加载/app/view/main.php并传递$ data $ data有节点'view'($ data ['view']),并且它有子节点,它决定了其他重要的事情,例如:什么是结束,什么布局,什么标题,什么页脚等…

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

  3. 再次使用包装中的$ data ['view'] ['layout']中的数据加载其他更深的结构,如布局…
  4. 布局,使用相同的$数据['视图'] ['主栏'],$数据['视图'] ['边栏']和捕获其他重要部分加载像主栏模板,侧栏模板…

就是这个…

PS我很抱歉不使用数字,但stackoverflow系统是如此奇怪,而不是显示3.它显示了我1 ..正如你看到我有一些嵌套列表…

我所做的(在Kohana 2中)有一个包含所有子部分(如左侧菜单,顶部标题)的模板,以及一个用于填充模板中要replace的variables的控制器。

然后,每个子部分的variables可以由控制器本身调用的函数生成。 你也可以把这些函数放在一个单独的控制器类的构造函数中,每一个你的控制器扩展这个函数,这样它们就会自动运行并设置为类variables,以便于访问。

对于更好的模板,你可以在不同的文件中有小节,大模板包含它们:

 <?php include 'leftMenu.php'; ?>