19
19

More than 5 years have passed since last update.

Cakephp3でPluginとThemeをつかってモバイルとPCのリソースやテンプレートを分ける

Last updated at Posted at 2016-06-06

綺麗にわけられます。綺麗だね。

Cakephp3とmobiledetectのバージョンはこれです。

composer.json
"cakephp/cakephp": "~3.2",
"mobiledetect/mobiledetectlib": "2.*",

モバイルかどうかの分岐のライブラリ

Cakephp3では、Mobile Detectを標準で利用するようになっていて、すぐに使えるようになっている。
Mobile Detectの本体は、Packagistでここにあって、これが本体。
mobiledetect/mobiledetectlib

githubでソースコードがあるこちら。
serbanghita/Mobile-Detect

このMobile Detectは、cakephpのアプリではbootstrap.phpで既に読み込まれてあります。

config/bootstrap.php
/**
 * Setup detectors for mobile and tablet.
 */
Request::addDetector('mobile', function ($request) {
    $detector = new \Detection\MobileDetect();
    return $detector->isMobile();
});
Request::addDetector('tablet', function ($request) {
    $detector = new \Detection\MobileDetect();
    return $detector->isTablet();
});

Request::addDetectorちゅうのは、Controllerの中で触れる$this->request->is('XXXXX')を動かすための宣言です。
Controllerの中での利用方法は、こんな感じ。

if ($this->request->is('mobile')) {
    if ($this->request->is('tablet')) {
        debug("タブレットです");
    } else {
        debug("タブレットじゃないモバイルです");
    }
} else {
    debug("PCです");
}

タブレットはモバイルの一部であるってところには気をつけてください。

プラグインThemeってものは、Controller内でtemplateの切り替えができる

Cakephp3にデフォルトで入っているプラグインであるところの「テーマプラグイン」を利用してテンプレートの切り替えをします。

参考:テーマ|CakePHP 3.2 Red Velvet Cookbook

こんな風にアプリのsrcの中にテンプレートが宣言されているとして、

src/Template/
├── Common
├── Element
│   ├── Flash
│   │   ├── default.ctp
│   │   ├── error.ctp
│   │   └── success.ctp
│   ├── footer.ctp
│   └── header.ctp
├── Email
│   ├── html
│   │   └── default.ctp
│   └── text
│       └── default.ctp
├── Error
│   ├── error400.ctp
│   └── error500.ctp
└── Layout
    ├── Email
    │   ├── html
    │   │   └── default.ctp
    │   └── text
    │       └── default.ctp
    ├── ajax.ctp
    ├── default.ctp
    ├── error.ctp
    └── rss
        └── default.ctp

Mobileという名前のPluginに上書きするようにファイルを用意すると

plugins/Mobile/src/Template/
├── Element
│   ├── footer.ctp
│   └── header.ctp
└── Layout
    ├── default.ctp
    └── error.ctp

ControllerのbeforeRenderでこれを呼べば、テンプレートが呼び替えられplugin/Mobile/...側のテンプレートファイルを参照するようになります。モバイルの方にテンプレファイルがなかったらPCのほうが読まれます。

$this->viewBuilder()->theme('Mobile');

では実際に切り替えの例を

いままでのを組み合わせると素敵にモバイルとPCのリソースを切り分けられます。

モバイル用のテーマプラグインを用意

plugins/Mobile/src/Template/
├── Element
│   ├── footer.ctp
│   └── header.ctp
└── Layout
    ├── default.ctp
    └── error.ctp
plugins/Tablet/src/Template/
├── Element
│   ├── footer.ctp
│   └── header.ctp
└── Layout
    ├── default.ctp
    └── error.ctp

モバイル用のテーマプラグインをロードする

テンプレート自体がロードされていないと動かないので、このようにロードしておいてください。

generic/config/bootstrap.php
Plugin::load('Mobile');
Plugin::load('Tablet');

AppControllerで、mobiledetectをつかって自動的にThemeを切り替え

src/Controller/AppController.php
// 省略

class AppController extends Controller
{
    // 省略

    public function beforeRender(Event $event)
    {
        if ($this->request->is('mobile')) {
            if ($this->request->is('tablet')) {
                $this->viewBuilder()->theme('Tablet'); 
            } else {
                $this->viewBuilder()->theme('Mobile');
            }
        }
    }
}

テーマを指定しない場合は、applicationのsrc/Templateがデフォルトです。

モバイル用画像、JS、CSSなどの置き場所

プラグインテーマには、プラグインアセットってのがあって、
アプリと同じように、plugin/プラグイン名のディレクトリの下に、webroot/というディレクトリが置けます。

plugins/Mobile/webroot/
├── css
│   └── application.css
├── images
│   ├── close.png
│   ├── logo.png
│   ├── next.png
│   └── prev.png
└── js
    └── application.js

ほんでこのプラグインディレクトリのリソースへのリンクは、普通にこう ↓ 書くと、指定されたテーマ内にファイルがあるかチェックして、あったらプラグイン内のwebrootのパスを出力。なかったら通常のwebrootのパスを出力してくれるみたいです。

<?= $this->Html->script('application.js') ?>

ってやっておくと、パスを解釈してくれます。

<script src="/mobile/js/application.js"></script>

本体に同じ名前のものwebroot/js/application.jsがあっても、mobile側が優先されてパス展開されます。

一方で、mobileのplugin/webroot/js/application.jsにこのファイルがなかったら、/mobileを抜いてパス展開されます。

<script src="/js/application.js"></script>

「モバイル用だけロゴをちっちゃくして欲しいんだよね…。」とか言われた時のために、こんなふうに書いておけば、

<?= $this->Html->image('logo.png');?>

こんなふうに出力されます。

<img src="/mobile/img/logo.png"/>

でも画像はテンプレにimgタグで書いて起きたさ溢れますね。
コーダーの方々はHTMLでわたしてくれますし。
最初っからmobileのパスを付けて用意してもらうようにするのもいいかもしれません。

最後に

あと、プラグインアセットのリンクのコマンドがcakeのコマンドに用意されていて、本番のパフォーマンスアップ用の設定なのですが、実稼働でもテストでも先に、以下のコマンドは開発中もやっといたほうが無難です。本番リリースの時にわすれないので。

bin/cake plugin assets symlink

実際はシンボリックリンクが張られます。

$ cd cakeapp
$ ls -l webroot/mobile 
lrwxr-xr-x  1 me  staff  46  5 31 12:17 webroot/mobile -> /var/www/cakeapp/plugins/Mobile/webroot

以上でした。

参考にしたドキュメント

http://book.cakephp.org/3.0/en/views/themes.html
http://book.cakephp.org/3.0/ja/plugins.html#id10
http://book.cakephp.org/3.0/ja/plugins.html#plugin-assets
http://book.cakephp.org/3.0/en/views/helpers/html.html#linking-to-images
http://book.cakephp.org/3.0/ja/deployment.html#symlink-assets

mobile detectとcakeのプラグイン
https://github.com/chronon/CakePHP-MobileDetectComponent-Plugin

19
19
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
19
19