簡易 CodeIgniter Layout Library for Template

在 Web 開發網站,最重要的就是切割版面 CSS 化,制定共同部份 header 跟 footer…等,如果是用在 CodeIgniter Controller 裡面,呼叫 Views 的時候,如底下程式碼:
$data = array(
    "title" => "Welcome to Test"
);
$this->load->view("header");
$this->load->view("welcome", $data);
$this->load->view("footer");
大家可以發現只要任何一個 Controller 的函式都必須寫上面的程式碼,這樣是不是重複率太高了呢?在 CodeIgniter Wiki 裡面發現一個不錯用的簡易 layout library,他的作法就是利用 $this->load->view 裡面的第三個參數來達成,可以參考線上文件 – Views 最後一個段落 Returning views as data,我們參考看看底下官網提供的程式碼:
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);
        }
    }
}
?> 
注意裡面制定了 layout_main.php 這個 Template PHP 檔案,所以大家需要在 application/views 資料夾產生此檔案,或者是可以透過程式 setLayout 函式去修改,至於我們怎麼傳變數到 Template 裡面呢,作者的作法是建立一個 config 檔案,裡面把不會變動的變數都寫在裡面,比如說是網站 site_name site_description site_keywords 等資料寫到 application/config/site_settings.php,接下來修改 layout library 裡面的 view function:
$loadedData = array(
    "content" => $this->obj->load->view($view, $data, true),
    "site_name" => $this->obj->config->item('site_name') . $title,
    "site_description" => $this->obj->config->item('site_description'),
    "site_keywords" => $this->obj->config->item('site_keywords'),
); 
可以自己變化看看,我想應該是不難的。如果有任何問題,歡迎到討論區留言
  • Azi

    今天在看CI,先裝了layout library後,想要有權限控管。結果一裝上去,發現layout是外掛的,ion_auth也是外掛的照著CI原本的寫法是沒有$this->layout->view(‘XXX’);這東西。
    所以得整個auth裡的$this->load->view();都改成$this->layout->view(”);
    有種自已挖洞給自已跳的感覺。>///<

  • appleboy48
  • azi

    謝謝!
    試了一下有個錯誤訊息Message: array_merge() [function.array-merge]: Argument #1 is not an array
    Filename: libraries/Template.php
    Line Number: 275

    我看了一下,似乎是array_merge(),只吃array,但在render參數進去時預設是null導致。我自已改了一下也就ok了。

    但是這個library,也是一樣無法解決我的問題,我也再去找了幾個library試,看來不管怎樣,要是加了layout功能後,再去加其他會用到view的外掛,都是得去手動修改$this->load->view()這一行?!

    anyway,謝謝您!

  • appleboy48

    Hi, 感謝你回報問題,我已經修正該 Library。另外你提到的問題,可以詳細說明功能性嗎?我不太瞭解您的需求。

  • azi

    我的需求是,有layout可以用。
    但希望不是這種用法 –>$this->xxx->view();之類的語法。(xxx是各個外掛元件名稱,ex:layout or template)
    我想要直接可以使用$this->load->view();跟原本的一樣就好。

    大概像cakePHP一樣的功能。可以在controller裡設定好,指定的layout,然後其它用法不用。

  • azi

    其它用法不變,才對。打錯字:P

  • appleboy48

    您的需求只有底下:

    1. 可以指定自己建立的 layout
    2. 可以使用類似原本的 $this->load->view(); 功能

    ===========================

    你說的這兩個功能在我提供的 library 都可以做到

    1. 可以透過 $this->template->set_layout(‘template/home’);

    2. $this->template->render(‘view_path’, array(‘key’ => ‘value’));

    layout template 可以參考 https://github.com/appleboy/CodeIgniter-Template/blob/master/template/layout.php 來修改

  • azi

    sorry,我表達的不是很明確

    我的意思是,假設我先用了你提供的library後。之後我寫的所有method都要使用$this->template-render()來輸出view了,對吧?
    但我不想要用$this->template-render()來輸出view,我希望仍夠可以用原來的 $this->load->view(); 。(但是有layout可以用)

    因為這樣,才不用每次要外掛別的功能,都要改外掛功能的view。

  • appleboy48

    $this->load->view(); 也可以 load layout,只是就看你要的格式是哪一種了。

  • azi

    謝謝您跟我討論!!

    我找到我想要的用法了,是這個(開心)
    http://www.syahzul.com/blogs/item/codeigniter-layout-without-using-additional-library

    謝謝您!!!

  • appleboy48

    不錯,感謝您提供解法,如果有任何問題也可以到論壇發問 http://www.codeigniter.org.tw/forum/

  • Pingback: [CodeIgniter] layout安裝 « 東次草之谷工作室()