プラグインで Flex を使う
はじめに
このページの目的は、 twig やコード中の Flex objects の利用方法を解説するところまでです。
Flex のパワーや柔軟性を理解するために、ぜひ Flex のドキュメント もお読みください。
Flex により、カスタムのオブジェクトを、ひとつのオブジェクトやコレクションとして CRUD 処理することができるようになります。
また、プラグインのコードやテンプレートから使える、幅広い API を提供してくれます。
管理パネルの UI も簡単に追加でき、標準的なテンプレートを使ったり、独自にカスタマイズされた一覧表示やフォーム(やその他)を使ったりできます。
利用要件
Grav 1.7 以降が必要要件です。
このドキュメントの目的のため、以下の各手順を確実に実行したいので、管理パネル付きの Grav をインストールします。
準備方法は、 インストールの解説 をご覧ください。
プラグインの作成
プラグインを作った時のように、 flex をスクラッチで作るかどうかに関わらず、すべての最新の変更をひとつの場所にまとめるため、 devtools でスケルトンと基本的な機能を生成することを、強くおすすめします。
そのために、 devtools CLIを使いましょう:
bin/gpm install devtools
detools を使って新しくプラグインを作成する ため、以下のコマンドを入力します。
プラグイン名は、myflexplugin
としましょう:
bin/plugin devtools new-plugin
以下のように質問に答えてください。
重要なのは、 Please choose an option:
で flex を選ぶことです。
Enter Plugin Name:
> myflexplugin
Enter Plugin Description:
> A little Flex plugin test
Enter Developer Name:
> grav@example.com
Enter GitHub ID (can be blank):
> gravcms
Enter Developer Email:
> grav@example.com
Please choose an option:
[blank] Basic Plugin
[flex ] Basic Plugin prepared for custom Flex Objects
> flex
Enter Flex Object Name:
> book
Please choose a storage type:
[simple] Basic Storage (1 file for all objects) - no media support
[file ] File Storage (1 file per object)
[folder] Folder Storage (1 folder per object)
> folder
SUCCESS plugin myflexplugin -> Created Successfully
Path: /home/pierre/project/grav/grav-admin/user/plugins/myflexplugin
Please run `cd /home/pierre/project/grav/grav-admin/user/plugins/myflexplugin` and `composer update` to initialize the autoloader
無事成功したら、依存関係をインストールしておきましょう:
cd /home/pierre/project/grav/grav-admin/user/plugins/myflexplugin
composer update
成功すると、次のように出力されるはずです:
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Writing lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
Generating autoload files
No installed packages - skipping audit.
Grav をインストールしたルートフォルダに戻ってください:
cd -
DevTools は、名前と説明からなる、とても基本的な flex objects を生成します。
管理パネル UI は、1行もコードを書かずに、これらの books objects を一覧リスト化し、作成や編集、削除できるようになっています。
管理パネルプラグインの、左のサイドメニューに新しいエントリーが追加されています:
デフォルトの編集フォームは、このような見た目です:
‘book’ という flex object と、それに関わる多様なフォルダやファイルが作られていることがわかると思います。
どこで何が行われるか
プラグインフォルダは、次のようになっています:
../grav-admin/user/plugins/myflexplugin
├── CHANGELOG.md
├── LICENSE
├── README.md
├── blueprints
│ └── flex-objects
│ └── book.yaml
├── blueprints.yaml
├── classes
│ └── Flex
│ └── Types
│ └── Book
│ ├── BookCollection.php
│ └── BookObject.php
├── composer.json
├── composer.lock
├── languages.yaml
├── myflexplugin.php
├── myflexplugin.yaml
└── vendor
├── autoload.php
└── composer
├── ClassLoader.php
├── InstalledVersions.php
├── LICENSE
├── autoload_classmap.php
├── autoload_namespaces.php
├── autoload_psr4.php
├── autoload_real.php
├── autoload_static.php
├── installed.json
├── installed.php
└── platform_check.php
Flex Object の定義
重要なファイルは、 blurprints の定義です。
flex object のスキーマを、たくさんのカスタマイズオプションとともに、定義するところです。
今回のプラグインでは、 book blueprints が、user/plugins/myflexplugin/blueprints/flex-objects/book.yaml
ファイルに入っています。
[!Note]
重要 それぞれの flex object の blueprint は、blueprints/flex-objects/
フォルダ内に入っていなければいけません。
スキーマは、この blueprints の Form セクションを使って定義されます。
管理パネルプラグインの UI を使うかどうかに関わらず、このセクションはこの flex object のプロパティを定義します。
ここでは、すべてのオプションを説明することはできません。
まずは book オブジェクトを実装することに集中しましょう。
詳しい Flex blueprints のドキュメント では、より深くカスタマイズ方法をガイドします。
以下のようなスキーマで、2つのプロパティを定義しています:
form:
validation: loose
fields:
published:
type: toggle
label: Published
highlight: 1
default: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
required: true
name:
type: text
label: Name
validate:
required: true
description:
type: text
label: Description
validate:
required: true
プラグインのフック
myflexplugin.php
は、プラグインの実装や、フックなどを定義する中心となるものです。
以下のようなパーツが、 flex を有効化するのに必要です:
public $features = [
'blueprints' => 0,
];
/**
* @return array
*
* The getSubscribedEvents() gives the core a list of events
* that the plugin wants to listen to. The key of each
* array section is the event that the plugin listens to
* and the value (in the form of an array) contains the
* callable (or function) as well as the priority. The
* higher the number the higher the priority.
*/
public static function getSubscribedEvents(): array
{
return [
'onPluginsInitialized' => [
// Uncomment following line when plugin requires Grav < 1.7
// ['autoload', 100000],
['onPluginsInitialized', 0]
],
FlexRegisterEvent::class => [['onRegisterFlex', 0]],
];
}
その他のファイルは、標準的で、これまでのプラグインのセクションでも解説してきたようなファイルです。
ここでは、それらには触れません。
classes フォルダには、 book flex object と、book flex collection で使う class が入っています。
ここにある class には、すべての object や collection で使えるカスタムメソッドを追加できます。
flex object にカスタムメソッドを追加する を見てください。
flex object のスキーマを修正する
object に、フィールドを追加してみましょう。
本の出版日をあらわす datetime フィールドを追加するなら、シンプルに pub_date
フィールドを blueprints に追加するだけです:
form:
validation: loose
fields:
published:
type: toggle
label: Published
highlight: 1
default: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
required: true
name:
type: text
label: Name
validate:
required: true
pub_date:
type: datetime
label: Description
validate:
required: true
デフォルトの編集フォームに、出版日のフィールドのための日付入力欄が、表示されました。
フィールドタイプは、 ここ にその全体のリストがあります。
flex object にカスタムメソッドを追加する
現在の book flex object は、 user/plugins/myflexplugin/classes/Flex/Types/Book/BookObject.php
に、GenericObject という trait を使用した class しか実装されていません。
<?php
declare(strict_types=1);
/**
* @package Grav\Common\Flex
*
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Plugin\Myflexplugin\Flex\Types\Book;
use Grav\Common\Flex\Types\Generic\GenericObject;
/**
* Class BookObject
* @package Grav\Common\Flex\Generic
*
* @extends FlexObject<string,GenericObject>
*/
class BookObject extends GenericObject
{
}
概要のためのデリミタ(区切り)を使って、本の概要を取得するメソッドを追加してみましょう。
<?php
declare(strict_types=1);
/**
* @package Grav\Common\Flex
*
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Plugin\Myflexplugin\Flex\Types\Book;
use Grav\Common\Flex\Types\Generic\GenericObject;
/**
* Class BookObject
* @package Grav\Common\Flex\Generic
*
* @extends FlexObject<string,GenericObject>
*/
class BookObject extends GenericObject
{
public function getSummary() {
$delimiter = \Grav\Common\Grav::instance()['config']['site']['summary']['delimiter'] ?? '===';
$summary = explode($delimiter, $this->content);
return $summary[0] ?? '';
}
}
これで、book flex object を利用する場所ならどこからでも、このメソッドを呼び出せます。
たとえば、テンプレート中でも可能です:
{% set books = grav.get('flex').collection('book') %}
{% for book in books %}
<h1>{{ book.header.title}}</h1>
<p>{{ book.getSummary()}}</p>
{% endfor %}
::getSummary
メソッドは、 PHP コードでも使えます。
同じことが、 collection class (user/plugins/myflexplugin/classes/Flex/Types/Book/BookCollection.php
)でも行えます。
たとえば、複雑なクエリを利用して検索する親切なメソッドを追加できます。
実際、コレクション class は、すでにすべての一般的なコレクションメソッドを提供しています。
オブジェクトに多くの異なるフィールドがあり、標準的なコレクションメソッドではエラーが出るような場合は、ヘルパーメソッドを追加すると便利です。