CodeIgniter中的页眉和页脚


71

我真的不喜欢在每个控制器中编写代码:

    $this->load->view('templates/header');
    $this->load->view('body');
    $this->load->view('templates/footer');

是否可以这样做,将自动包含页眉和页脚,如果需要更改它,我们也可以这样做吗?你怎么处理那件事呢?还是您认为这不是问题?谢谢。


2
Code Igniter Wiki页面介绍了如何通过扩展核心控制器来执行此操作。
安迪

Answers:


106

这是我的工作:

<?php

/**
 * /application/core/MY_Loader.php
 *
 */
class MY_Loader extends CI_Loader {
    public function template($template_name, $vars = array(), $return = FALSE)
    {
        $content  = $this->view('templates/header', $vars, $return);
        $content .= $this->view($template_name, $vars, $return);
        $content .= $this->view('templates/footer', $vars, $return);

        if ($return)
        {
            return $content;
        }
    }
}

对于CI 3.x:

class MY_Loader extends CI_Loader {
    public function template($template_name, $vars = array(), $return = FALSE)
    {
        if($return):
        $content  = $this->view('templates/header', $vars, $return);
        $content .= $this->view($template_name, $vars, $return);
        $content .= $this->view('templates/footer', $vars, $return);

        return $content;
    else:
        $this->view('templates/header', $vars);
        $this->view($template_name, $vars);
        $this->view('templates/footer', $vars);
    endif;
    }
}

然后,在您的控制器中,这就是您要做的一切:

<?php
$this->load->template('body');

1
你还在吗 我不明白为什么“ $ this-> load-> template('body');” 返回任何内容,因为$ return设置为FALSE。“ if($ return)”应该返回false,因此不会返回$ content,但是在我测试它时会返回。我在这里想念什么?
timetofly 2012年

3
忽略我刚才说的话。手册中的答案:“如果将参数设置为true(布尔值),它将返回数据。默认行为是false,它将发送给您的浏览器。如果要返回数据,请记住将其分配给变量:” 。“ if($ return)”只是一个备份。
timetofly 2012年

2
我向应用程序/核心添加了文件LS_Loader.php,并提供了您的回复,但是当我调用$ this-> load-> template('my_template',$ data)时,它会抛出错误Call to undefined method CI_Loader::template()。还有其他步骤吗?还是这不适用于2.1.3?
2013年

1
好。它只能是MY_Loader.php。前缀是固定的。
2013年

2
@mehulved是MY_可配置的,但默认为MY_CI,并且对于所有自定义替代都相同。更改它可能会破坏其他插件
2013年

45

是。

template.php在您的views文件夹中创建一个名为的文件。

内容template.php

$this->load->view('templates/header');
$this->load->view($v);
$this->load->view('templates/footer');

然后,您可以从控制器中执行以下操作:

$d['v'] = 'body';
$this->load->view('template', $d);

这实际上是我个人加载所有视图的非常简单的版本。如果您将此想法发挥到极致,则可以进行一些有趣的模块化布局:

考虑是否创建一个init.php包含单行的视图:

$this->load->view('html');

现在创建html.php包含内容的视图:

<!DOCTYPE html>
<html lang="en">
    <? $this->load->view('head'); ?>
    <? $this->load->view('body'); ?>
</html>

现在创建一个head.php包含内容的视图:

<head>
<title><?= $title;?></title>
<base href="<?= site_url();?>">
<link rel="shortcut icon" href='favicon.ico'>
<script type='text/javascript'>//Put global scripts here...</script>
<!-- ETC ETC... DO A BUNCH OF OTHER <HEAD> STUFF... -->
</head>

body.php带有内容的视图:

<body>
    <div id="mainWrap">
        <? $this->load->view('header'); ?>
        <? //FINALLY LOAD THE VIEW!!! ?>
        <? $this->load->view($v); ?>
        <? $this->load->view('footer'); ?>
    </div>
</body>

并根据需要创建header.phpfooter.php查看。

现在,当您从控制器调用init时,所有繁重的工作就完成了,您的视图将被包装在其中,<html>并包含<body>标签,页眉和页脚。

$d['v'] = 'fooview'
$this->load->view('init', $d);

@QadirHussain很高兴能为您提供帮助。
乔丹·阿塞诺

1
该解决方案非常实用。
Ahsan

8

尝试跟随

资料夹结构

-application
 --controller
   ---dashboards.php
 --views
   ---layouts
      ----application.php
   ---dashboards
      ----index.php

控制者

class Dashboards extends CI_Controller
{

   public function __construct()
   {
     parent::__construct();
     $data                = array();
     $data['js']          = 'dashboards.js'
     $data['css']         = 'dashbaord.css'
   }

   public function index()
   { 
     $data                = array();
     $data['yield']       = 'dashboards/index';

     $this->load->view('layouts/application', $data);
   }
}

视图

<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8" />
      <title>Some Title</title>
      <link rel="stylesheet" href="<?php echo base_url(); ?>assets/css/app.css" />
      <link rel="stylesheet" href="<?php echo base_url(); ?>assets/css/<?php echo $css; ?>" />
   </head>
   <body>
     <header></header>
     <section id="container" role="main">
     <?php $this->load->view($yield); ?>
     </section>
     <footer></footer>
     <script src="<php echo base_url(); ?>assets/js/app.js"></script>
     <script src="<php echo base_url(); ?>assets/js/<?php echo $js; ?>"></script>
  </body>
</html>

当您需要加载其他js,css或页眉或页脚中的任何内容时,请使用__construct函数$this->load->vars

这里有种类似rails的方法


一旦您可以从视图子文件夹加载视图部分,就不需要+1权限来扩展类!
itsme 2013年

2

或更复杂,但使生活更轻松的是在引导中使用更多常量。因此,可以自由定义子类,并且可以使用单个方法显示视图。还可以将选定的常量传递到标头中的javascript。

<?php
/*
 * extends codeigniter main controller
 */

class CH_Controller extends CI_Controller {

    protected $viewdata;

public function __construct() {
    parent::__construct();
            //hard code / override and transfer only required constants (for security) server constants
            //such as domain name to client - this is for code porting and no passwords or database details
            //should be used - ajax is for this

    $this->viewdata = array(
                "constants_js" => array(
                    "TOP_DOMAIN"=>TOP_DOMAIN,
                    "C_UROOT" => C_UROOT,
                    "UROOT" => UROOT,
                    "DOMAIN"=> DOMAIN
                )
            );

}

public function show($viewloc) {
            $this->load->view('templates/header', $this->viewdata);
    $this->load->view($viewloc, $this->viewdata);
    $this->load->view('templates/footer', $this->viewdata);
}

//loads custom class objects if not already loaded
public function loadplugin($newclass) {
    if (!class_exists("PL_" . $newclass)) {
        require(CI_PLUGIN . "PL_" . $newclass . ".php");
    }
}

然后简单地:

$this->show("<path>/views/viewname/whatever_V.php");

将加载页眉,视图和页脚。


1

@Landons MY_Loader的简单重写,以包含正文的多个文件,ei页唯一的侧边栏...

<?php

class MY_Loader extends CI_Loader {
    public function template($template_name, $vars = array(), $return = FALSE)
    {
        $content  = $this->view('frontend/templates/header', $vars, $return);

        if(is_array($template_name)) { //return all values in contents

            foreach($template_name as $file_to_load) { 
                  $content .= $this->view('frontend/'.$file_to_load, $vars, $return);
            }
        }
        else {             
            $content .= $this->view('frontend/'.$template_name, $vars, $return);
        }

        $content .= $this->view('frontend/templates/footer', $vars, $return);

        if ($return)
        {
            return $content;
        }
    }
}

这是双向的...

将一个文件包含到模板中:

$data['moo'] = 'my data'];
$this->load->template('home', $data);

在模板中包含多个文件:

$data['catalog'] = 'catalog load 1';
$data['sidebar'] = 'sidebar load 2';           
$load = array('catalog/catalog', 'catalog/sidebar');        
$this->load->template($load, $data);


1

通过在应用程序/核心文件夹中添加名为“ MY_Loader.php”的文件并添加以下内容来重新定义CI_Loader :: view函数

/**
* /application/core/MY_Loader.php
*/

class MY_Loader extends CI_Loader 
{  
        public function view($view, $vars = array(), $return = FALSE, $include_template=TRUE)
        {
            $header='';
            $footer='';

            if($include_template)
            {
                    $header=parent::view('templates/header',$vars,$return);
            }

            $content=parent::view($view, $vars,$return);

            if($include_template)
            {
                    $footer=parent::view('templates/footer',$vars,$return);
            }

            if($return)
                    return "$header$content$footer";

            return $this;
        }
}


1

我尝试了本页提出的几乎所有答案以及许多其他内容。我最终保留在所有网站上的最佳选择是以下体系结构:

单一视图

我在浏览器中仅显示一个视图。这是我的主要视图(/views/page.php):

<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <?= $header ?? '' ?>
    </head>
    <body>
        <div style="width:1200px">
                <?= $content ?? '' ?>
        </div> 
    </body>
</html>

控制器处理多个视图

当然,我有几种观点,但是它们被串联起来以构建$header$content变量。这是我的控制器:

$data['header'] = $this->load->view('templates/google-analytics', '', TRUE)
                 .$this->load->view('templates/javascript', '', TRUE)
                 .$this->load->view('templates/css', '', TRUE);


$data['content'] = $this->load->view('templates/navbar', '', TRUE)
                  .$this->load->view('templates/alert', $myData, TRUE)
                  .$this->load->view('home/index', $myData, TRUE)
                  .$this->load->view('home/footer', '', TRUE)
                  .$this->load->view('templates/modal-login', '', TRUE);

$this->load->view('templates/page', $data);
  • 看看源代码多么美丽和清晰。
  • 您不再需要在一个视图中打开HTML标记并在另一个视图中关闭它。
  • 现在,每个视图都专用于一个并且只有一个内容。
  • 查看视图如何串联:方法链接模式,或者应该说:联合链接模式!
  • 您可以添加可选部分(例如$javascript,正文末尾的第三个变量)
  • 我经常将CI_Controller扩展为重载$this->load->view我的应用程序专用的额外参数,以保持控制器整洁。
  • 如果您总是在多个页面上加载相同的视图(这最终是问题的答案),则根据您的需要提供两个选项:
    • 在视图中加载视图
    • 扩展CI_Controller或CI_Loader

我为这种架构感到骄傲...


0

这是我的处理方式。我在视图文件夹中创建了一个名为template.php的文件。该文件包含我所有的主要站点布局。然后从该模板文件中调用其他视图。这是一个例子:

<!doctype html>
<html lang="en">
<head>
  <meta charset=utf-8">
  <title><?php echo $title; ?></title>
    <link href="<?php echo base_url() ;?>assets/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <link href="<?php echo base_url() ;?>assets/css/main.css" rel="stylesheet" type="text/css" />
<noscript>
Javascript is not enabled! Please turn on Javascript to use this site.
</noscript>

<script type="text/javascript">
//<![CDATA[
base_url = '<?php echo base_url();?>';
//]]>
</script>

</head>
<body>

<div id="wrapper">
    <div id="container">
        <div id="top">
            <?php $this->load->view('top');?>
        </div>

        <div id="main">
            <?php $this->load->view($main);?>
        </div>

        <div id="footer"> 
            <?php $this->load->view('bottom');?>
        </div>
    </div><!-- end container -->
</div><!-- end wrapper -->

<script type="text/javascript" src="<?php echo base_url();?>assets/js/jquery-1.8.2.min.js" ></script>
<script type="text/javascript" src="<?php echo base_url();?>assets/js/bootstrap.min.js"></script>

</body>
</html>

从我的控制器,我将视图的名称传递给$ data ['main']。所以我会做这样的事情:

class Main extends CI_Controller {

    public function index()
    {
        $data['main'] = 'main_view';
          $data['title'] = 'Site Title';
          $this->load->vars($data);
          $this->load->view('template', $data);
    }
}

0

我遇到了这个问题,我希望控制器以诸如“感谢该表单”和通用“未找到等”的消息结尾。我在views-> message-> message_v.php下执行此操作

<?php
    $title = "Message";
    $this->load->view('templates/message_header', array("title" => $title));
?>
<h1>Message</h1>
<?php echo $msg_text; ?>
<h2>Thanks</h2>
<?php $this->load->view('templates/message_footer'); ?>

这使我可以在单个文件中更改消息呈现站点的范围,以进行任何调用

$this->load->view("message/message_v", $data);

0

这个问题已经正确回答,但是我想补充一下我的方法,它与其他人所提到的没什么不同。

我使用不同的布局页面来调用不同的页眉/页脚,有的称为此布局,有的称为模板等。

  1. 编辑core/Loader.php并添加自己的函数以加载布局,我称该函数为layout

  2. 创建您自己的模板页面并使其调用header/footer,我将其命名default.php并放入新目录,例如view/layout/default.php

  3. 像往常一样,从控制器调用自己的视图页面。但是,布局函数将调用和,而不是调用$this-load->viewuse $this->load->layout,并将调用您的页眉和页脚。default.phpdefault.php

1)core/Loader.phpview()函数中,我复制了它并添加了我的

   public function layout($view, $vars = array(), $return = FALSE)
   {
       $vars["display_page"] = $view;//will be called from the layout page
       $layout               = isset($vars["layout"]) ? $vars["layout"] : "default";
       return $this->_ci_load(array('_ci_view' => "layouts/$layout", '_ci_vars' =>  $this->_ci_object_to_array($vars), '_ci_return' => $return));
   }

2)创建布局文件夹,并将default.php放入其中 view/layout/default.php

   $this->load->view('parts/header');//or wherever your header is
   $this->load->view($display_page);
   $this->load->view('parts/footer');or wherever your footer is

3)从您的控制器,调用您的布局

 $this->load->layout('projects');// will use 'view/layout/default.php' layout which in return will call header and footer as well. 

要使用其他布局,请在$data数组中包含新的布局名称

 $data["layout"] = "full_width";
 $this->load->layout('projects', $data);// will use full_width.php layout

当然,您必须在布局目录中具有新的布局,如下所示:

view/layout/full_width.php 

0

使用此助手进行动态模板加载

//  get  Template 
    function get_template($template_name, $vars = array(), $return = FALSE) {
        $CI = & get_instance();

        $content = "";
        $last = $CI - > uri - > total_segments();

        if ($CI - > uri - > segment($last) != 'tab') {
            $content = $CI - > load - > view('Header', $vars, $return);
            $content. = $CI - > load - > view('Sidebar', $vars, $return);
        }

        $content. = $CI - > load - > view($template_name, $vars, $return);

        if ($CI - > uri - > segment($last) != 'tab') {
            $content. = $CI - > load - > view('Footer', $vars, $return);
        }

        if ($return) {
            return $content;
        }
    }

0

我已经达到了这个目标,我希望可以帮助所有人在应用程序/核心中创建my_controller,然后将其中的代码作为您文件的名称进行更改

    <?php
defined('BASEPATH') OR exit('No direct script access allowed');
// this is page helper to load pages daunamically
class MY_Controller extends CI_Controller {

 function loadPage($user,$data,$page='home'){

  switch($user){

   case 'user':
   $this->load->view('Temp/head',$data);
   $this->load->view('Temp/us_sidebar',$data);
   $this->load->view('Users/'.$page,$data);
   $this->load->view('Temp/footer',$data);
   break;

   case 'admin':
   $this->load->view('Temp/head',$data);
   $this->load->view('Temp/ad_sidebar',$data);
   $this->load->view('Admin/'.$page,$data);
   $this->load->view('Temp/footer',$data);
   break;

   case 'visitor';
    $this->load->view('Temp/head',$data);
   $this->load->view($page);
   $this->load->view('Temp/footer',$data);
   break;

   default:
   echo 'wrong argument';
   die();
       }//end switch

   }//end function loadPage
}

在您的控制器中使用此

class yourControllerName extends MY_Controller

注意:关于控制器前缀的名称,您必须确定config.php文件上的前缀,我希望能为任何人提供帮助

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.