この記事を読むのに必要な時間は約 16 分です。
CakePHP で開発している際に、CSS や JavaScript でも PHP 処理を利用したい場合があるかと思います。
よくある例で言えば、CSS の背景画像指定の際の URL などがあります。他にも、HTML の class 名を、PHP の定数等を利用することで、HTML、CSS、JavaScript の間でずれないようにする等といったケースが考えられます。
当記事では、各 CSS や JavaScript を、Controller や View を通して配信する方法をご紹介します。
[pn-box color=”lgray”]
CakePHP 関連記事は、以下よりご覧下さい。
[pn-box-close]
CSS を配信するための作業全体像
まずは、CSS の場合について紹介します。
以下の条件の元で実装したいと思います。
- /path/to/cake/CSS/hoge.css の URL でアクセスすることとする。
- デフォルトでは、/path/to/cake/css/hoge.css
- /path/to/cake/CSS/fuga.css など、複数の CSS を用意できるようにする。
作業は以下の通りです。
- アクションを 1つ固定にするため、app/Config/routes.php に Routing 設定を追加します。
- CSS ファイル配信用に、CSSController クラスを用意します。CSSController では、リクエストされた各 CSS に対応した View を読み込むようにします。
- 各 CSS を View の ctp ファイルとして用意します。
- hoge.css に対応する hoge.ctp、fuga.css に対応する fuga.ctp という具合
- 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 を動的に生成・配信する方法
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 ファイル) を指定する方法
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 に変わります。
(*) 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]