カスタムエンティティの正規ページのアクションボタンを考えてみます。
mymodule.actions.yml:
entity.item.action:
route_name: entity.item.action
title: 'Do something'
appears_on:
- entity.item.canonical
mymodule.routing.yml:
entity.item.action:
path: '/item/{item}/action'
defaults:
_controller: '\Drupal\mymodule\Controller\ItemController::action'
_title: 'Do something'
requirements:
_permission: 'edit items'
エンティティのいくつかのフィールドの値に応じて、アクションボタンを表示または非表示にしたいと思います。
どうすればこれを達成できますか?これにカスタムアクセスチェックを追加するのは賢明でしょうか?
コントローラにカスタムアクセスメソッドを追加できます。 このページ によると、アクセス方法でitem
引数にアクセスできる必要があるため、その項目の値に基づいてアクセスを制限できるはずです。ユーザーがルートにアクセスできない場合、つまりカスタムアクセス方法がアクセスを拒否する場合、アクションは非表示にする必要があります。
私はhook_menu_local_tasks_alter
。現在のエンティティ(ノードなど)はパラメーターとしてこのフックに渡されないため、個別にクエリする必要があることに注意してください。
このようなもの:
function XXX_menu_local_tasks_alter(&$data, $route_name) {
$routes = ['entity.node.canonical'];
if (in_array($route_name, $routes)) {
foreach ($data['tabs'][0] as $task_name => &$task_array) {
if ($task_name == 'entity.node.canonical') {
$node = \Drupal::routeMatch()->getParameter('node');
if ($node instanceof \Drupal\node\NodeInterface) {
Drupal 8ガイド/モジュール定義のアクションの提供 には、2つの有用なアプローチの概要が示されています。これらは:
アプローチ1で問題をほぼ解決しました。しかし、私はまだキャッシュに苦労しています。これはこれまでの私の解決策です:
namespace Drupal\mymodule\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\mymodule\Entity\ItemInterface;
use Drupal\mymodule\Entity\Item;
/**
* Defines dynamic actions.
*/
class ItemLocalActions extends DeriverBase {
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
// Implement dynamic logic to provide values for the same keys as in example.links.task.yml.
$id = \Drupal::routeMatch()->getRawParameter('item');
$item = Item::load($id);
if ($item instanceof ItemInterface) {
switch($item->getStatus()) {
case ItemInterface::STATUS_NEW:
$this->derivatives['entity.item.action'] = $base_plugin_definition;
$this->derivatives['entity.item.action']['title'] = t('Do something');
$this->derivatives['entity.item.action']['route_name'] = 'entity.item.action';
break;
// add more derivative definitions here, depending on the item's state
}
}
return $this->derivatives;
}
}
そしてmymodule.links.action.ymlで:
entity.item.state_actions:
deriver: '\Drupal\mymodule\Plugin\Derivative\ItemLocalActions'
cache_tags:
- item_list
appears_on:
- entity.item.canonical
上記のように、キャッシングは依然として問題です。適切なキャッシュタグを設定しても、アクションはキャッシュからレンダリングされます。
関連する質問: