PHP
CakePHP
cakephp3

【cakephp3】prefixを用いてフロントと管理画面でerror.ctpを分ける

cakephp3におけるerror.ctp

存在しないURL(ページ)にアクセスしたときに表示される共通のページのレイアウトです。
ページが存在しませんというページです。

その際に、レイアウトがフロントと管理画面で二種類あるケースでcakephp3においてerror.ctpをどのように二つに分けるかをまとめました。

要件と修正前の状態

現在は下記のように二つのレイアウトが存在するとします。

app/src/Template/Layout/front.ctp
app/src/Template/Layout/admin.ctp

テンプレートではfrontのレイアウトを呼んでいます。

app/src/Template/Error/error.ctp
(中略)
    $this->layout = 'front';
(中略)

今回は、新しく、管理画面のページ(/admin/以下の存在しないURL)に読み込ませるレイアウトを変更したいとします。
※現在は、フロントも管理画面(/admin以下)も、通常通りフロントのerror.ctpが出てしまいます。

存在しないURLを叩くと、本来フロントではなく、管理画面のヘッターやフッターが出て欲しいところですが、これがフロントのレイアウトが出ている状態です。

ex /admin/hoge_not_exit

そのため、判定が必要です。

悪い修正例(文字列で判定)

app/src/Template/Error/error.ctp
(中略)
if (strstr(Router::url(), 'admin') === false):
    $this->layout = 'front';
else:
    $this->layout = 'admin';
endif;
(中略)

なぜダメなのか

『admin』という文字列で判定してしまうと、
/aaaaadmin でも管理画面用のレイアウトが出てしまうからです。

要件としては、/admin/以下の存在しないURLの場合のケースにadmin用のレイアウトを出したいからです。

そのためprefixでの判定が望ましいです。

速さを比較するとstrstr関数よりもstrpos関数を使うべき

http://php.net/manual/ja/function.strstr.php

良い修正例(prefixで判定)

prefixの判定を使うのがベターなようです。
https://book.cakephp.org/3.0/ja/controllers/request-response.html#id3

app/src/Template/Error/error.ctp
(中略)
if ($this->request->param('prefix') === 'admin'):
    $this->layout = 'admin';
else:
    $this->layout = 'front';
endif;
(中略)

prefixとは

ちなみに、prefixは、config/routes.phpで設定してあるものです。
そのため、prefixで、adminの設定をして、trueが返却されるようにします。
https://book.cakephp.org/3.0/ja/development/routing.html#prefix-routing

フロント画面では、設定していないためfalseが返ります。

デバック方法

デバックモードを切る

app.phpの一番上のデバックモードをfalseにしないと、まずローカル環境でテストができないので、error.ctp系の開発するときは一回切ります。そして存在しないURL(存在しないコントローラーやアクション)を叩いて何が表示されるか確認します。

prefixのデバック

prefixをdebugする方法としては下記の通り

$passedArgs = $this->request->param('prefix');
debug($passedArgs);

※cakephp3.4以降であれば getParamが使えます。

https://github.com/tyrellsys/jsh/blob/develop/app/config/routes.php#L50