MooLog

CodeIgniter3でcssとjsを読み込む時のベストプラクティス

2020-02-02 08:45:07 CodeIgniter

CodeIgniter3でcssやjsのファイルを読み込むで、どの手法がベストなのかを色々調べたのでまとめていく。

結論から言うと、「cssやjs等の静的ファイルの読み込みは、独自helperを作る」と言うのが良い。

以下は、詳しく解説していく。

開発環境

CodeIgniterが用意したhelperを使う方法

一番オーソドックスな方法は、CodeIgniterがhelperとして用意しているlink_tag()関数を使う方法だろう。

link_tag([$href = ''[, $rel = 'stylesheet'[, $type = 'text/css'[, $title = ''[, $media = ''[, $index_page = FALSE]]]]]])

参考:HTML ヘルパー — CodeIgniter 3.2.0-dev ドキュメント

link_tag()を使う場合には、application/configs/config.php内にある$config['base_url']変数を以下のように変更しておく。

<?php
$config['base_url'] = 'http://localhost:8000/';

次にContorllerの__constructメソッド内で、 $this->load->helper('html'); としてhelperを読み込む。(別に__constructである必要はない)

<?php
// controllers/UserController.php
class UserController extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->helper('html'); 
    }

最後にviewファイル内でlink_tag関数を使えばOK.

<html>

<head>
    <title>signup</title>
    <?php echo link_tag("style.css"); ?>
</head>

最終的には以下のようなlinkタグを出力してくれる。

<link href="'http://localhost:8000/style.css" rel="stylesheet" type="text/css" />

linkタグを直書きした場合は自分で絶対パスの処理を書く必要があるが、link_tag関数を使うことでCIが自動で絶対パスに置き換えてくれる点では、link_tag関数は便利と言える。

CodeIgniterのlink_tag関数の問題点

上記の例ではlink_tag関数は便利に思えるが、以下の2点に不満が残る。

cssやjsファイルをrootディレクトリに書くことはほとんどなく、おそらく多くの人は、application/assets/cssディレクトリを作成して、その中にあるcssファイルを読み込ませたいだろう。

もし、link_tagを使う場合はlink_tag("application/assets/css/style.css")と書かなければならず、すごく面倒な作業が待っている。

それにlink_tagは柔軟な関数かと思いきや、javascriptが使えない等の致命的な欠点もある。

link_tagの独自helperを作る

上記の点からlink_tagを使うのは得策とは言えず、cssとjsファイルを簡単に読み込むための独自helperを作るのが良い。

具体的には、application/helpersディレクトリにMY_html_helper.phpファイルを作り、そこに独自helper関数を書いていく。

また、CodeIgniterは$this->load->helper("html")とhelperをロードした時は、system/helpers/html_helper.phpだけでなく、application/helpers/MY_html_helper.phpも読み込むことができるかもチェックしてくれる。

独自helperのソースコード

僕が書いた独自helperは以下の通り。

<?php

defined('BASEPATH') or exit('No direct script access allowed');

if (!function_exists("stylesheet_link_tag")) {
    function stylesheet_link_tag($href = '',  $index_page = FALSE)
    {
        if (is_array($href)) {
            $result = "";
            foreach ($href as $h) {
                $result .= stylesheet_link_tag($h, $index_page);
            }
            return $result;
        } else {
            $CI = &get_instance();

            $css_path = "application/assets/css/";
            $href = $css_path . preg_replace("#(\.css)$#", "", ltrim($href, "/")) . ".css";

            if ($index_page === TRUE) {
                $link = '<link href="' . $CI->config->site_url($href) . '" ';
            } else {
                $link = '<link href="' . $CI->config->base_url($href) . '" ';
            }

            $link .= 'rel="stylesheet" type="text/css"';
            return $link . "/>\n";
        }
    }
}

if (!function_exists("javascript_link_tag")) {
    function javascript_link_tag($src = '', $index_page = FALSE)
    {
        if (is_array($src)) {
            $result = "";
            foreach ($src as $s) {
                $result .= javascript_link_tag($s, $index_page);
            }
            return $result;
        } else {
            $CI = &get_instance();

            $js_path = "application/assets/js/";
            $src = $js_path . preg_replace("#(\.js)$#", "", ltrim($src, "/")) . ".js";

            if ($index_page === TRUE) {
                $link = '<script src="' . $CI->config->site_url($src) . '" ';
            } else {
                $link = '<script src="' . $CI->config->base_url($src) . '" ';
            }

            $link .= 'type="text/javascript"';
            return $link . "></script>\n";
        }
    }
}

使い方は超簡単で、まずはapplication/assets/cssディレクトリとapplication/assets/jsディレクトリを作成して、その中にcssやjsファイルを書いていく。

そして、Contorller内で$this->load->helper("html")として後に、viewファイル内で以下のように使えばOK。

<html>
<head>
    <?php echo stylesheet_link_tag("style"); ?>
    <?php echo javascript_link_tag("index"); ?>
</head>

上記のコードは以下のように出力される。

<link href="http://localhost:8000/application/assets/css/style.css" rel="stylesheet" type="text/css">
<script src="http://localhost:8000/application/assets/js/index.js" type="text/javascript"></script>

また、独自ヘルパーは以下の様に書いてもOK.

<?php echo stylesheet_link_tag("style"); ?>
<?php echo stylesheet_link_tag("/style"); ?>
<?php echo stylesheet_link_tag("style.css"); ?>
<?php echo stylesheet_link_tag("/style.css"); ?>
// 全て<link href="http://localhost:8000/application/assets/css/style.css" rel="stylesheet" type="text/css">と出力

また、複数のファイルを読み込む場合は引数を配列にすると良い。

<?php echo stylesheet_link_tag(["style", "foo.css", "fizz/bazz.css"]); ?>

/*
<link href="http://localhost:8000/application/assets/css/style.css" rel="stylesheet" type="text/css">
<link href="http://localhost:8000/application/assets/css/foo.css" rel="stylesheet" type="text/css">
<link href="http://localhost:8000/application/assets/css/fizz/bazz.css" rel="stylesheet" type="text/css">
 */

kenjis/codeigniter-composer-installerでCodeIgniterをインストールした時の注意点

もし、kenjis/codeigniter-composer-installer(kenjis/codeigniter-composer-installer: Installs the offical CodeIgniter 3 (or 4) with secure folder structure via Composer)でCodeIgniterをインストールした場合は、ファイル構造を少し変える必要がある。

なぜなら、kenjisではpublicディレクトリがrootディレクトリになっており、publicディレクトリ内にcssやjsファイルを書かないと、上手く読み込んでくれないからだ。(websサーバーは、rootの親ディレクトリに戻ることができないため)

具体的には、application/public/ディレクトリに.htaccessindex.phpがあると思うが、この2つのファイルをcodeigniterディレクトリに移動させる。

次にcodeigniter/bin/server.sh内にある以下の記述を変更する

php -S "$ADDR_PORT" -t "$DOC_ROOT/" -f bin/router.php

#以下に変更

php -S "$ADDR_PORT" -f bin/router.php

最後に先ほど移動したapplication/index.phpの記述を以下の様に変更する。

$system_path = '../vendor/codeigniter/framework/system';

$application_folder = '../application';

#以下に変更
$system_path = 'vendor/codeigniter/framework/system';

$application_folder = 'application';

これで上手く動くはず。