CakePHP 2.x で CSS や JavaScript を動的に生成・配信する方法

この記事を読むのに必要な時間は約 16 分です。


CakePHP で開発している際に、CSS や JavaScript でも PHP 処理を利用したい場合があるかと思います。

よくある例で言えば、CSS の背景画像指定の際の URL などがあります。他にも、HTML の class 名を、PHP の定数等を利用することで、HTML、CSS、JavaScript の間でずれないようにする等といったケースが考えられます。

当記事では、各 CSS や JavaScript を、Controller や View を通して配信する方法をご紹介します。

 

[pn-box color=”lgray”]

CakePHP 関連記事は、以下よりご覧下さい。

tag : CakePHP

[pn-box-close]


cake-logo

 

CSS を配信するための作業全体像

まずは、CSS の場合について紹介します。

以下の条件の元で実装したいと思います。

  • /path/to/cake/CSS/hoge.css の URL でアクセスすることとする。
    • デフォルトでは、/path/to/cake/css/hoge.css
  • /path/to/cake/CSS/fuga.css など、複数の CSS を用意できるようにする。

 

作業は以下の通りです。

  1. アクションを 1つ固定にするため、app/Config/routes.php に Routing 設定を追加します。
  2. CSS ファイル配信用に、CSSController クラスを用意します。CSSController では、リクエストされた各 CSS に対応した View を読み込むようにします。
  3. 各 CSS を View の ctp ファイルとして用意します。
    • hoge.css に対応する hoge.ctp、fuga.css に対応する fuga.ctp という具合
  4. Layout ファイルにて、用意した CSS を読み込むようにします。

 

 

1. Routing 設定の追加

各 CSS ファイルは、アクションではなく View として用意します。

Controller で行うべき処理は、各 CSS で共通かと思いますので、アクションは 1つに固定します。

各 CSS 毎に異なる処理が必要であれば、View ではなく、アクションとして実装し、View は共通にする等の方法があるかと思います。ここでは、アクション 1つの場合の方法をご紹介します。

 

URL の構成としては、通常では /path/to/cake/CONTROLLER/ACTION/PARAMETER となりますが、ACTION は固定ですので不要です。/CSS/index/hoge.css 等よりも、/CSS/hoge.css の URL の方がスマートですよね。

そのため、app/Config/routes.php に設定を以下のように追加します。

Router::connect("/CSS/*",
  array( "controller" => "CSS", "action" => "index" )
);

これで、action は index 固定となり、URL 中の /path/to/cake/CSS/ 以降の部分をパラメーターとして受け取れるようになります。

 

2. CSS 配信用の CSSController クラスを用意

CSS Controller で行う処理

CSS Controller では、以下の処理を行います。

  • パラメーターを元に、各 CSS に対応する View を読み込みます
  • ブラウザに向けて、CSS ファイルの MIME type を指定します

 

実装例

例えば、こんな形で実装してみました。

<?php
class CSSController extends AppController{
  public function index(){
    $this->layout = false;
    $this->response->type( "text/css" );
    echo "@charset \"UTF-8\"; " . PHP_EOL;

    $fileName = pathinfo( $this->request->params["pass"][0], PATHINFO_FILENAME ) ;
    $this->render( $fileName );
  }
}
?>

4行目で、Layout の読込を中止しています。これを行わないと、Layout/default.ctp 等の Layout が読み込まれて、<html> タグだの <head> タグだのが入ってしまいます。

5行目で、MIME type の指定を行っています。

[pn-box color=”lgray”]

CakePHP での MIME type の指定については、以下の記事にて解説しています。
CakePHP 2.x で MIME type (Content-Type) を指定する方法

CSS を PHP で自動生成する際の、MIME type 指定の必要性については、以下の記事にて解説しています。
PHP で CSS や JavaScript を動的に生成・配信する方法

[pn-box-close]

6行目は、CSS の文字コード指定をここで出力しています。各 CSS で行うならば不要です。

8行目は、$this->request->params[“pass”][0] で、URL の /CSS/ 以降の部分を受け取ります。そこから、pathinfo( xxx, PATHINFO_FILENAME )  によって、拡張子を除いた部分を取り出しています。/CSS/hoge.css であれば、hoge が取り出されます。

9行目で、$this->render()  により、8行目で取り出したファイル名の View を読み込んでいます。

[pn-box color=”lgray”]

CakePHP で、読み込む View を指定する方法は以下の記事にて紹介しています。
Cake PHP 2.x で 読み込む View (ctp ファイル) を指定する方法

[pn-box-close]

 

3. 各 CSS に対応した View の用意

通常の HTML の View と同様な要領で、CSS 用の View を作成します。

例えば、app/View/CSS/hoge.ctp で以下のように用意します。

.body{
  background-color: <?php echo BACKGROUND_COLOR ; ?>;
}

<?php 〜 ?>  で PHP 処理を行えます。APP  や DS  などの CakePHP 定数を使えます。

また、View ですので、Html ヘルパー等も使うことができます。(Controller で $helpers を指定しましょう)

 

4. Layout 等で、CSS を読み込むように

3. までで、リクエストされた CSS を配信する準備はできました。

後は、リクエストしてもらえるように、CSS を利用する HTML や Layout に、<link> タグなどの記載を追加します。

 

全体で共通の CSS であれば、デフォルトの Layout として読み込まれる app/View/Layouts/default.ctp に、以下のように CSS 読込の指定を行います。

<html>
<head>
...
<?php echo $this->Html->css( "/CSS/hoge.css" ); ?>
...
</head>
...
</html>

URL 中の、/path/to/cake の部分は、自動的に補完してくれます。

“/path/to/cake/CSS/hoge.css” のように指定すると、”/path/to/cake/path/to/cake/CSS/hoge.css” と二重になってしまいます。

 

各 View で個別に CSS を指定する場合

一部の View で個別に CSS を指定する場合は、以下のように記述します。

<?php
  $this->Html->css( "/CSS/hoge.css", null, array("inline" => false) );
?>
...

inline は、その場で出力するかの指定になりますので、false にしておけばバッファされ、Layout で以下の記載で読み込まれて実際の出力が行われます。( つまり、Layout で以下が記載されている必要あり )

<html>
<head>
...
<?php
  $this->fetch("css");
?>
...
</head>
</html>

 

以上で、CSS については完成です。好きなだけ処理し放題です。

 

JavaScript の場合

JavaScript の場合も CSS の場合と同様に、行っておけば OK です。違いとしては、以下の点になります。

  • JSController で指定する MIME type が text/css ではなく text/javascript に変わります。
  • JSController では、文字コード指定は省略します。 (*)
  • Layout 等で呼び出す処理が、 $this->Html->css から $this->Html->script に変わります。
[pn-box color=”lgray”]

(*) CakePHP での JavaScript の文字コード指定

JavaScript の文字コード指定は、HTTP Header の Content-Type で指定、読込元 HTML の <script charset=””> で指定、といった方法がありますが、CakePHP の場合、後者は $this->Html->script() では指定できず、前者は自動的に UTF-8 が付与されてしまうので、難易度が高そうです。

よっぽどの理由がない限り、おとなしく UTF-8 で作成するのが無難そうです…。

[pn-box-close]

 

実装例

解説は、CSS とほぼ同様ですので、省略させていただきます。

app/Config/routes.php

Router::connect("/JS/*",
  array( "controller" => "JS", "action" => "index" )
);

app/Controller/JSController.php

<?php
class JSController extends AppController{
  public function index(){
    $this->layout = false;
    $this->response->type( "text/javascript" );
    // charset の指定は省略します

    $fileName = pathinfo( $this->request->params["pass"][0], PATHINFO_FILENAME ) ;
    $this->render( $fileName );
  }
}
?>

app/Layouts/default.ctp

<html>
...
<?php echo $this->Html->script( "/JS/hoge.js" ); ?>
...
</html>

<header> で出力するか、<body> の最後で出力するか、等は要件に合わせて適宜対応しましょう。

各 HTML 用の View で、個別の JS を呼び出す際には、以下の記述になります。

<?php
  $this->Html->js( "/JS/hoge.js", array("inline" => false) );
?>
...

 

公式ドキュメントへのリンク

[pn-box color=”lgray”]

CakePHP Cookbook 2.x  > コアライブラリ > ヘルパー > HtmlHelper > HhtmlHelper::css()

CakePHP Cookbook 2.x  > コアライブラリ > ヘルパー > HtmlHelper > HhtmlHelper::script()

[pn-box-close]

 

 

ひとこと

CSS や JS を CakePHP の処理の流れに載せることで、自由度が広がるかと思います。

ルールを上手に設定すれば、単純なミスを防ぐことができ、効率が上がるかも知れません。

活用の仕方は色々とあるかと思いますので、何かしらお役に立てば幸いです。

 

[pn-cakephp-env]

今回は以上です。


[pn-amzn-cakephp]

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です