CodeIgniter create a layout/template library

27,924

Solution 1

Put the bottom class in libraries/Layout.php (your app not the sys). In the autoload add the library:

$autoload['libraries'] = array('layout');

In your controller just write $this->layout->render();

The class will render the layout views/layouts/default.php and the view views/$controller.views/$method.php

In the default layout just put

<?php $this->load->view($view,$data); ?>

and thats it.

The code is

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

class Layout
{
    public $data = array();
    public $view = null;
    public $viewFolder = null;
    public $layoutsFodler = 'layouts';
    public $layout = 'default';
    var $obj;

    function __construct()
    {
        $this->obj =& get_instance();
    }

    function setLayout($layout)
    {
        $this->layout = $layout;
    }
    function setLayoutFolder($layoutFolder)
    {
        $this->layoutsFodler = $layoutFolder;
    }

    function render()
    {

        $controller = $this->obj->router->fetch_class();
        $method = $this->obj->router->fetch_method();
        $viewFolder = !($this->viewFolder) ? $controller.'.views' : $this->viewFolder . '.views';
        $view = !($this->view) ? $method : $this->view;

        $loadedData = array();
        $loadedData['view'] = $viewFolder.'/'.$view;
        $loadedData['data'] = $this->data;

        $layoutPath = '/'.$this->layoutsFodler.'/'.$this->layout;
        $this->obj->load->view($layoutPath, $loadedData);
    }
}
?>

Solution 2

I'm doing layout thing is like bellow.

I get content to data['content'] variable.

This is my controller.

    class Article extends MY_Controller {

        function __construct() {
            parent::__construct();
            $this->load->model('article_model');
        }

        public function index() {

            $data['allArticles']    =   $this->article_model->getAll(); 

            $data['content']        =   $this->load->view('article', $data, true);
            $this->load->view('layout', $data);

        }

This is my Layout.I'm using bootstrap layout.

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <meta name="description" content="">
            <meta name="author" content="">
            <title>Starter Template for Bootstrap</title>
            <base href="<?php echo base_url(); ?>" />

            <!-- Bootstrap core CSS -->
            <link href="assets/bootstrap3.0.1/css/bootstrap.min.css" rel="stylesheet">

            <!-- Custom styles for this template -->
            <!--    <link href="starter-template.css" rel="stylesheet">-->

            <!-- Just for debugging purposes. Don't actually copy this line! -->
            <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->

            <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
            <!--[if lt IE 9]>
              <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
              <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
            <![endif]-->
        </head>

        <body>

            <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
                <div class="container">
                    <div class="navbar-header">
                        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                            <span class="sr-only">Toggle navigation</span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                        </button>
                        <a class="navbar-brand" href="#"> Article Management System</a>
                    </div>
                    <div class="collapse navbar-collapse">
                        <ul class="nav navbar-nav">
                            <li class="active"><a href="">Home</a></li>
                            <li class="dropdown">
                                <a class="dropdown-toggle" data-toggle="dropdown" href="#"> Admin <span class="caret"></span></a>
                                <ul class="dropdown-menu">
                                    <li><a href="article/add">Add Article</a></li>
                                    <li><a href="article">All Article</a></li>
                                </ul>
                            </li>
                        </ul>
                    </div><!--/.nav-collapse -->
                </div>
            </div>

            <div class="container" style="margin-top: 80px;">

                <?php echo $content; ?>

            </div><!-- /.container -->


            <!-- Bootstrap core JavaScript
            ================================================== -->
            <!-- Placed at the end of the document so the pages load faster -->
            <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
            <script src="assets/bootstrap3.0.1/js/bootstrap.min.js"></script>
        </body>
    </html>        

This is my content view

    <div class="row">

        <div class="col-xs-12 col-sm-12 col-md-12">

            <div class="page-header">
                <h4>All Articles </h4>
            </div>

        </div>

        <div class="col-xs-12 col-sm-12 col-md-12">

            <table class="table table-striped table-bordered">
                <thead>
                    <tr>
                        <th>Title</th>
                        <th>Description</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($allArticles as $row) { ?>
                    <tr>
                        <td><?php echo $row->title; ?></td>
                        <td><?php echo substr($row->description,0,100); ?> ....</td>
                        <td></td>
                    </tr>
                    <?php } ?>
                </tbody>
            </table>

        </div>
    </div>
Share:
27,924
ltdev
Author by

ltdev

Updated on July 09, 2022

Comments

  • ltdev
    ltdev almost 2 years

    Before I begin I have to say that I have recently started learning CodeIgniter, so I'm sorry if I repeat this subject once again.

    In procedural php I would do something like this

    // the header.php
    <!DOCTYPE html>
    <html>
    <head>
          <meta name="description" content="blah blah">
          <title>My Site</title>
          <link href="css/main.css" rel="stylesheet" media="screen">
    <php? if($current_page == 'about.php'): ?>
          <link href="css/secondary.css" rel="stylesheet" media="screen"> // or some embed styles (<stlye> ... </style>)
       <?php endif; ?> 
    
    
          <script src="http://code.jquery.com/jquery.js"></script>
          <script src="js/main_script.js"></script>
    
          <php? if($current_page == 'contact.php'): ?>
          <script src="js/validation.js"></script>
          <?php endif; ?>
    </head>
    <body>
         // end of header.php
    
         include('template/header.php');
    
         <h1>Heading1</h1>    
         <p>Lorem Ipsum...</p>
    
         include('template/footer.php');
    
        //footer.php
        //maybe some js and here
    </body>
    </html>
    

    So I would like to do something similar and in CI. All pages/views will have the same main styles or scripts, but in some cases, some specific pages (like contact.php) may include, and only in these pages, some specific styles or scripts (like the validation.js).

    I have found this video that shows how to create a template/layout library using CI, but I'm not quite sure how I can apply this functionality to work properly.

  • ltdev
    ltdev about 10 years
    I have developed a library quite similar to yours. Anyway thanks for your reply!
  • user66875
    user66875 over 8 years
    Thank you, that's great stuff! But can it be that the $data variable in the Controller will not be passed to the view this way? I pass the $data to the render method and changed $loadedData['data'] = $data;
  • Cheung
    Cheung almost 7 years
    So does it means <body> tag on header.php, and the close tag </body> on footer.php? If yes, this is very bad pattern.
  • Chutipong Roobklom
    Chutipong Roobklom almost 5 years
    example to use public function index() { $this->load->view('layouts/default', ['view'=>'dashboard/index' , 'data' => []]); }