Creating a bulk action plugin

by Gisle Hannemyr

This tutorial explains how to create a custom module with a plugin to add a 'Accept request' bulk action to the manage content page.

Table of contents

Introduction

Drupal provides a menu to let you carry out certain bulk actions on the site's contents, such as publishing or unpublishing. You'll find this menu by navigating to Manage » Content and inspect the pulldown-menu below "Action".

In this tutorial, I am going to to create a bare bones custom module that contains a plugin that change the value of a booean field in a bulk export action for selected nodes. To keep it simple, it will not be configurable.

Add a custom field to the Basic page content type

[TBA]

Create a custom module

To create a module, create a directory to hold it in modules/custom/ below the webroot. Then create an .info.yml file that contains the metadata for the module.

In this tutorial, the module shall be called "hnm_accept". Start out by creating the directory and in it: hnm_accept.info.yml. Then put the following content in this file:

name: 'HNM Accept'
description: 'Example of how to create a custom action by code.'
package: 'Custom'
core_version_requirement: ^9.0
type: module

When the folder and file has been created, you shall be able to go to Manage » Extend, locate the custom module and enable it.

This custom module is just going to require two subdirectories:

Go ahead and create them in the module's top directory.

Provide a configuration

In the config directory, create a new subdirectory named install.

The configuration file for this plugin is named system.action.accept_action.yml. Create it in the install directory with the following content:

langcode: en
status: true
dependencies:
  module:
    - node
id: accept_action
label: 'Accept request'
type: node
plugin: accept_action
configuration: {  }

Some of the key elements of the plugin configuration are:

Provide a schema

In the config directory, create a new subdirectory named schema.

The schema file must start with the name of the custom module, followed by .schema.yml, so the full name should be: hnm_accept.schema.yml.

hnm_accept.configuration.hnm_accept_request:
  type: mapping
  label: 'Accept request'

The top level key refers to the configuration object (system.action.accept_action.yml).

The nested levels describe what is in the file:

Create the plugin

Now, create the actual plugin. First create the required directories below src:

$ cd src
$ mkdir -p Plugin/Action

Then, in the Action directory, create AcceptRequest.php with the following content:

<?php

namespace Drupal\hnm_accept\Plugin\Action;

use Drupal\Core\Action\ActionBase;
use Drupal\Core\Session\AccountInterface;

/**
 * Provides a an Update node title action.
 *
 * @Action(
 *   id = "accept_action",
 *   label = @Translation("Accept request"),
 *   type = "node",
 *   category = @Translation("Custom")
 * )
 *
 */
class AcceptRequest extends ActionBase {

  /**
   * {@inheritdoc}
   */
  public function access($node, AccountInterface $account = NULL, $return_as_object = FALSE) {
    /** @var \Drupal\node\NodeInterface $node */
    $access = $node->access('update', $account, TRUE)
      ->andIf($node->title->access('edit', $account, TRUE));
    return $return_as_object ? $access : $access->isAllowed();
  }

  /**
   * {@inheritdoc}
   */
  public function execute($node = NULL) {
    /** @var \Drupal\node\NodeInterface $node */
    $node->set('field_accepted', TRUE)->save();
  }

}

This plugin simply extends the ActionBase class and overrides its two main methods:

You will notice in the Annotations of the Plugin, its identifier, the same one declared in the plugin configuration file, as well as the entity type on which the plugin applies.

Test it

Navigate to Manage » Content and verify that "Accept request" now appears in the pulldown-menu below "Action".

Final word

There exists three custom modules to create custom action plugins:

  1. hnm_accept: Set a boolean "Accept" field to TRUE.
  2. hnm_exportnodes: Export nodes.
  3. hnm_settitle: Set the node title. This also show how to make the execute() override configurable by extending ConfigurableActionBase.

Last update: 2022-05-05 [gh].