LoginSignup
0
1

More than 3 years have passed since last update.

【CraftCMS】ElementAPIでフロントエンドにjsonだけ返す

Posted at

スコープの切り分け問題

CraftCMSではCPで定義したsectionやfieldのhandleをtwigでモリモリ書いて出力する、
いわばオーソドックスなMVCデザインパターンに則った構成です。

他のCMSをディスるわけではないですが某何とかPressとかは
テンプレートに<?php 〜 ?>みたいな記述がそこかしこで必要なもんで
個人的に可読性の低下を感じてしまい、あんまり好きじゃない得意じゃないです。
(´-`)oO( Timberとか使えばWord何とかもTwig使えるんだったかな… )

一方デフォルトでテンプレートエンジンを積んだCMSは(ある程度ですが)元のソースを大きく崩すことなく動的なアウトプットが可能であり、
それこそCraftやDrupalなんかはそこそこ見やすい&書きやすいのが取り柄の1つじゃないでしょうか。

そういう経験からこう考えていたもんです。
「CMSとかFrameworkのView部分はSmartyとかTwigとか使うのがセオリー。
 テンプレートはフロントの人が作るから、データのアウトプットはバックエンドに任せて
 じゃとりあえずテンプレートはダミーテキスト入れといて、あとで埋め込んどくから――」

ところが最近というかもう結構前からですが、
フロントエンドだけでViewを完結するような思想がウチの会社では主となってしまいました。

しまいましたって別に悪いこっちゃなくて、むしろデータこねこねはバックエンド、ドバドバはフロントエンドという切り分けが明確になったため、
余計なことを考えずに最後にecho $json;すれば完結するようになったのがとても楽。

ElementAPIとは

ということで本題ですが、まさに前述の実装を実現してくれる公式のプラグインがElementAPIです。
リポジトリはこちら

Endpointを定義して返却するjsonを設計,実装する & フロントエンドで叩いてもらう

これだけでデータを簡単に展開出来るAPI、だいぶお気に入りです。
スクリーンショット 2019-07-23 21.51.26.png

プラグインの実モジュール部分は割愛しますが、element-api.phpだけをイジればよいので
非常に楽。とにかく楽。

実装方法

プラグインの入れ方は単純にcomposerなりで導入するので端折ります。

element-api.php

<?php
use Craft;
use craft\elements\Entry;
use craft\elements\Asset;
use craft\elements\Category;
use craft\helpers\UrlHelper;
use League\Fractal\TransformerAbstract;

return [
    "endpoints" => [
        "api/news/archives.json" => 
        [
            "elementType" => Entry::class,
            'criteria' => [
                'section' => 'News',
                'orderBy' => 'postDate DESC',
            ],
            'paginate' => $_GET['size'],
            'elementsPerPage' => 9,
            'pageParam' => 'size',
            'transformer' => function (Entry $entry){
                return [
                    'id'        => $entry->id ,
                    'title'     => $entry->n_title,
                    'main_img'  => $entry->n_image->one()->url,
                    'time'      => $entry->postDate->format("Y.M.d"),
                    'article'   => preg_replace('/<p.*?>|<\/p>/mis', '', $entry->n_detail),
                ];
            }
        ],
        "api/news/<news_id:\d+>.json" => function($news_id){
            return [
                "elementType" => Entry::class,
                'criteria' => [
                    'news_id' => $news_id,
                    'section' => 'News'
                ],
                ~ 省略 ~
            ];
        }
    ];

ものすごいreturnします。
リストを取得したい場合は上のエンドポイント、詳細を取得したい場合はIDを付与して下のエンドポイントを実行すると
それぞれに対応した結果が取得出来ます。
ちょっと実ソースがものすごい長いのですいませんが省略します…。
上の大事な項目(全部大事だけど)は以下。

キー 役割
endpoints アクセスするURLを定義
elementType 取得したいデータの型を定義
criteria 取得したいデータの基準(条件)を定義
transformer データを加工したい場合はこのスコープで

結果としてtransformer内でreturnしている内容がjsonとして出力されます。
フロントエンド側の人にはjs側で
https://morimorigohan.jp/api/news/archives.json
https://morimorigohan.jp/api/news/12.json
のようにアクセスしてもらえば
上記で予め設計した形のjsonが受け取れるというスンポーです。

おわり。

0
1
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
0
1