エントリ一覧のサブナビゲーションには、常に「すべてのエントリ」リンクが表示されます。
「直近で更新されたエントリがあるか?」を確認するのに便利ではあるものの、セクションを跨いだ情報なこともあり、あまり利用しないケースがほとんどです。
そこで、Craft Generator が生成したひな形から「すべてのエントリ」リンクを非表示にするカスタムモジュールを作成してみたいと思います。
これは Craft CMS Advent Calendar 2022 24日目の記事です。
モジュールのひな形を作成
はじめに、モジュールのひな形を生成します。Craft Generator をインストールした状態で、次のコマンドを実行します。
./craft make module
モジュールに必要なの3つの項目を入力します。
項目 | 説明 | 入力サンプル |
---|---|---|
Module ID | モジュール ID(ケバブケース) | sample-module |
Module location | モジュールの生成先 | modules/sampleModule |
Should the module be loaded during app initialization? | Craft の初期化時にモジュールを読み込むようにするか? | yes |
Module location
が生成先のパスと同時にモジュールの名前空間として利用されるため、Module ID
にハイフンを含める場合は Module location
をキャメルケースで記述しましょう。
config/app.php の確認
Should the module be loaded during app initialization?
で yes
と答えた場合、自動的にアップデートされます。
<?php
use craft\helpers\App;
use modules\sampleModule\Module;
return [
'id' => App::env('APP_ID') ?: 'CraftCMS',
'modules' => [
'my-module' => \modules\Module::class, 'sample-module' => Module::class,
],
// (中略)
'bootstrap' => ['sample-module'],
];
sampleModule
または sample-module
を含む3箇所が、Craft Generator によって書き加えられています。カスタムモジュールが不要になった場合は、これらの除去と modules/sampleModule/
ディレクトリの削除が必要です。
「すべてのエントリ」を非表示にする
先に完成形のコードを貼っておきます。
<?php
namespace modules\sampleModule;
use Craft;
use yii\base\Module as BaseModule;
use craft\elements\Entry;
use craft\events\RegisterElementSourcesEvent;
use yii\base\Event;
/**
* sample-module module
*
* @method static Module getInstance()
*/
class Module extends BaseModule
{
public function init()
{
// Set the controllerNamespace based on whether this is a console or web request
if (Craft::$app->getRequest()->getIsConsoleRequest()) {
$this->controllerNamespace = 'modules\\sampleModule\\console\\controllers';
} else {
$this->controllerNamespace = 'modules\\sampleModule\\controllers';
}
parent::init();
// Defer most setup tasks until Craft is fully initialized
Craft::$app->onInit(function() {
$this->attachEventHandlers();
// ...
});
}
private function attachEventHandlers(): void
{
Event::on(
Entry::class,
Entry::EVENT_REGISTER_SOURCES,
function (RegisterElementSourcesEvent $event) {
if ($event->context === 'index') {
foreach ($event->sources as $i => $source) {
if (isset($source['key']) && ('*' == $source['key'])) {
unset($event->sources[$i]);
}
}
}
}
);
}
}
このサンプルで、実際に追記したのは次の2箇所です。
必要なクラスの読み込み
今回は「エントリ一覧のソース(サブナビゲーションの表示項目)の登録イベント」を操作したいため、次のクラスが必要です。
use craft\elements\Entry;
use craft\events\RegisterElementSourcesEvent;
use yii\base\Event;
公式ドキュメントの Event Code Generator
で source
と入力すると表示される候補から、目的のものを選択してサンプルコードを確認するとよいでしょう。
Events | Craft CMS Documentation | 4.x
https://craftcms.com/docs/4.x/extend/events.html
なお、craft\elements\Category::EVENT_REGISTER_SOURCES
を選択し、カテゴリ一覧を対象にするといったカスタマイズも可能です。
イベント処理
ここでは、サブナビゲーションの表示内容が確定する EVENT_REGISTER_SOURCES
イベントのソース($event->sources
の配列)から、「すべてのエントリ」を除去しています。
Event::on(
Entry::class,
Entry::EVENT_REGISTER_SOURCES,
function (RegisterElementSourcesEvent $event) {
if ($event->context === 'index') {
foreach ($event->sources as $i => $source) {
if (isset($source['key']) && ('*' == $source['key'])) {
unset($event->sources[$i]);
}
}
}
}
);
なお、Ray での $event
の出力結果のキャプチャも貼っておきます。
これを見ると「isset($source['key'])
で見出しを除外」し、「'*' == $source['key']
ですべてのエントリのみ対象」としているのが判りますね。
あとは、管理画面でエントリ一覧を表示して「すべてのエントリ」リンクが非表示になっていることを確認できれば OK です。(コード変更直後は反映までに数秒かかる場合があります。)
最後に
今回は Craft Generator で簡単なカスタムモジュールを作成してみました。
ベースとなる部分を簡単に用意できると、必要な処理をどう実装するかに集中できるのでやはり便利ですね。
とはいえ、標準機能や既成プラグインの組み合わせで賄えることも多いため、実際に自分でカスタムプラグインやモジュールを用意する必要性がないかもしれませんが。。。