2010-03-22

CodeIgniter 레이아웃 이용하기

CodeIgniter 에는 기본으로 레이아웃을 사용할 수 있지가 않다. 여러개의 뷰로드하기 를 통해서 같단히 레이아웃 효과를 낼 수 있지만, 부족한 부분이 있다.


Layout Library 를 이용한 방법

  1. /application/libraries/Layout.php 에 다음 소스를 저장한다.
    <?php  
    if (!defined('BASEPATH')) exit('No direct script access allowed');
     
    class Layout
    {
        var $obj;
        var $layout;
     
        function Layout($layout = "layout_main")
        {
            $this->obj =& get_instance();
            $this->layout = $layout;
        }
     
        function setLayout($layout)
        {
            $this->layout = $layout;
        }
     
        function view($view, $data=null, $return=false)
        {
            $loadedData = array();
            $loadedData['content_for_layout'] = $this->obj->load->view($view,$data,true);
     
            if($return) {
                $output = $this->obj->load->view($this->layout, $loadedData, true);
                return $output;
            } else {
                $this->obj->load->view($this->layout, $loadedData, false);
            }
        }
    }
    ?>
  2. 라이브러리 로딩은 2가지 방법이 있는데, 첫번째는 컨트롤러의 생성자에서
    $this->load->library('layout', 'layouts/default');
    // 위에서 layout 라이브러리를 로딩할 때, 두번째 인자가 적용되지 않으므로,
    // 아래와 같이 별도로 default layout 을 설정해주어야 한다.
    $this->layout->setLayout("layouts/default");
    와 같이 적어주는 방법과 두번째는 /application/config/autoload.php 에
    $autoload['libraries'] = array('layout');
    를 적어주어서, 매번 컨트롤러 생성자에 적어주지 않게 하는 방법이 있다. 그리고 나서, 컨트롤러에서 아래와 같이 해주면, 레이아웃과 내용이 로딩 될 것이다.
    // layout 을 적용하지 않고 출력하고자 할 때
    // $this->load->view('admin/list');
     
    // 다른 layout 을 적용하고자 할 때
    // $this->layout->setLayout("layouts/default");
     
    $this->layout->view('admin/list');
  3. /application/views/layouts/default.php
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko" dir="ltr">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <title>CI 레이아웃</title>
    </head>
    <body>
    <?= $content_for_layout ?>
    </body>
    </html>

Hook을 이용한 Layout 처리

  1. HOOK 사용 설정
    • config/config.php
      $config['enable_hooks'] = TRUE;
    • config/hooks.php
      $hook['display_override'][] = array(
          'class'    => 'Yield',
          'function' => 'doYield',
          'filename' => 'Yield.php',
          'filepath' => 'hooks'
      );
  2. HOOK 파일 추가
    • hooks/Yield.php
      <?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
       
      class Yield
      {
          function doYield()
          {
              global $OUT;
              $CI =& get_instance();
              $output = $CI->output->get_output();
              $CI->yield = isset($CI->yield) ? $CI->yield : TRUE;
              $CI->layout = isset($CI->layout) ? $CI->layout : 'default';
              if ($CI->yield === TRUE) {
                  if (!preg_match('/(.+).php$/', $CI->layout)) {
                      $CI->layout .= '.php';
                  }
                  $requested = APPPATH . 'views/layouts/' . $CI->layout;
                  $layout = $CI->load->file($requested, true);
                  $view = str_replace("{yield}", $output, $layout);
              } else {
                  $view = $output;
              }
              $OUT->_display($view);
          }
      }
      ?>
      디펄트 레아이웃 파일은 default.php, 레이아웃 폴더위치는 view/layouts 또는 입맛대로 변경
  3. default.php 레이아웃 파일 추가
    • views/layouts/default.php
      <html>
      <header>
      </header>
      <body>
        <div>
        </div>
        {yield}
        <div>
        </div>
      </body>
      <html>
  4. 컨트롤러에서 레이아웃 사용법
    class Test extends Controller {
     
        //레이아웃 파일 설정
        var $layout = 'my_layout_file';
     
        function Test()
        {
            parent::Controller();
        }
     
        function index()
        {
            // 로드되는 view 파일들은 레이아웃 파일안에 {yield} 와 항상 replace  됨.
            $this->load->view('main');
            $this->load->view('sidebar');
        }
     
        function ajax_call()
        {
            // 레이아웃 파일을 사용하지 않을시
            $this->yield = FALSE;
     
            echo json_encode($array);
        }
     
        function need_another_layout()
        {
            $this->layout = 'another_layout';
        }
    }
  5. 참고
    layout 파일안에 데이타를 넘겨줘야 할 경우, 다른 view파일을 로드할때 데이타를 같이 넘겨주거나,
    $this->load->vars($data);
    위처럼 글로벌로 넘겨주면 됩니다.