LoginSignup
4
6

More than 5 years have passed since last update.

CodeIgniterにレイアウト層を追加してみる

Posted at

Railsに取り組んでからCodeIgniterもまた使うようになったのですが、Railsにあって便利そうなものをCodeIgniterにも取り入れて、快適に書けるよう進めていっています。今回は、そんなことをしたうちの1つ、レイアウト層の導入について取り上げてみます。

レイアウトって?

Railsをやっている人ならご存知だと思いますが、Railsで各コントローラーから呼び出すビューには、基本的に<body>の一部しか書かれていません。その外側の<!DOCTYPE>とか<html>とかは、別な「レイアウト」ファイルに書いてあって、ビューはその中に表示されることになります。

実際にサイトを作る上で、(JavaScriptとかCSSなどは別として)各ページごとにレイアウトが違うことはまずないですし、各個のビューからは決まりきった部分の描画をまったく省略できるので、すっきり書けるようになります。

描画を乗っ取る_output

それでは、このような機構をCodeIgniterに組み込むには、どうすればいいでしょうか。CodeIgniterには、ビューでの出力が終わった後、それを最終形にする前に呼び出される_outputというメソッドがあるので、ここに仕掛けてみることにします。

まずは、レイアウト制御用のLayoutクラスを用意します。

libraries/Layout.php
<?php

class Layout{
    private $_ci;
    private $_name = 'default';
    private $_parameters = array('title' => '', 'h1' => '');

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

    public function set_template($name){
        $this -> _name = $name;
    }

    public function set_parameter($key, $val){
        $this -> _parameters[$key] = $val;
    }

    public function __set($key, $val) {
        $this -> set_parameter($key, $val);
    }

    public function render($content, $return = FALSE){
        $this -> _parameters['_content'] = $content;
        return $this -> _ci -> load -> view('layouts/' . $this ->
_name, $this -> _parameters, $return);
    }
}

レイアウトのレンダリングにも通常のビューと同じ仕組みを使って、そしてレイアウトからは$_contentで中に出力すべき内容を取得できるようになっています。また、titleh1などレイアウトに渡すべき引数がいくつかあるので、マジックメソッドで制御できるようにしてあります。

そして、これを呼ぶMY_Controllerは以下のようになります。

core/MY_Controller.php
class MY_Controller extends CI_Controller{

    public function __construct(){
        parent::__construct();
        // オートロードで設定してもOK
        $this -> load -> library('layout');
    }

    protected $_use_layout = TRUE;

    public function use_layout($value){
        $this -> _use_layout = $value;
    }

    //出力ハンドラ
    public function _output($content){
        if($this -> _use_layout) {
            $content = $this -> layout -> render($content, TRUE);
        }
        echo $content;
    }

}

見ての通り、use_layoutがTRUEならレイアウトを挟んで出力している、それだけです。

検討課題

まだ作りかけなので、考慮すべきことがいくつかあります。

  • JavaScript、CSSのハンドリング
  • HTML以外を出力する場合、Content-typeを切り替えるだけでレイアウトを無効にする
4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6