How to Create a Solr-Compatible Search API Processor Plugin in Drupal 10

solr, drupal and custom plugin

In Drupal, integrating with Solr for powerful search functionality is common. Sometimes, you might need to combine information from multiple fields to create a new custom field for Solr search. This guide shows you how to create a Solr-Compatible Search API Processor Plugin in Drupal 10. This guide is also compatible with Drupal 8 and 9.

Prerequisites

  1. A functioning Drupal 8, 9, or 10 installation
  2. Solr search engine integrated with Drupal
  3. A custom content type named Club with a custom field field_cl_district_name. (Note: The title field is a default property for any Drupal content type. For the purpose of this article, a custom field for the district name is added to the content type. You should create or use an actual content type relevant to your project.)
  4. Drupal’s Search API module installed and enabled
  5. Search API Solr module installed and enabled
  6. Custom module named my_custom_module (you can name it as you wish)

Solr Compatibility

This guide is designed to be compatible with Solr, one of the most popular search backends used with Drupal. The custom Search API Processor Plugin you’ll be creating can be configured to work seamlessly with Solr, enhancing your site’s search capabilities.

Creating the Search API Processor Plugin

Step 1: Prepare Your Custom Module

If you haven’t already created a custom module, you need to set it up first. Create a folder under modules/custom named my_custom_module. Inside it, you’ll need a my_custom_module.info.yml file with the following content:

name: 'My Custom Module'
type: module
description: 'A custom module to extend Drupal functionalities.'
core_version_requirement: ^8 || ^9 || ^10
package: Custom

Step 2: Create the Plugin Class

Create a PHP file named FullClubName.php inside modules/custom/my_custom_module/src/Plugin/search_api/processor.

Here’s how the FullClubName.php file would look like:

<?php

namespace Drupal\my_custom_module\Plugin\search_api\processor;

use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorProperty;

/**
 * @SearchApiProcessor(
 *   id = "full_club_name",
 *   label = @Translation("Full Club Name"),
 *   description = @Translation("Combine Title and District fields for clubs."),
 *   stages = {
 *     "add_properties" = 0,
 *   },
 *   locked = true,
 *   hidden = true,
 * )
 */
class FullClubName extends ProcessorPluginBase {

  public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) {
    $properties = [];

    if (!$datasource) {
      $definition = [
        'label' => $this->t('Full Club Name'),
        'description' => $this->t('Combines the Title and District fields for clubs.'),
        'type' => 'string',
        'processor_id' => $this->getPluginId(),
      ];
      $properties['full_club_name'] = new ProcessorProperty($definition);
    }

    return $properties;
  }

  public function addFieldValues(ItemInterface $item) {
    $entity = $item->getOriginalObject()->getValue();
    if ($entity->bundle() === 'club') {
      $title = $entity->get('title')->getString();
      $district = $entity->get('field_cl_district_name')->getString();

      $combined_value = $title . ' (' . $district . ')';
      $fields = $this->getFieldsHelper()
        ->filterForPropertyPath($item->getFields(), NULL, 'full_club_name');
      foreach ($fields as $field) {
        $field->addValue($combined_value);
      }
    }
  }
}

Annotation Explained

  • @SearchApiProcessor: This annotation declares the class as a Search API Processor Plugin.
  • id = "full_club_name": The internal machine name for the plugin, which must be unique.
  • label = @Translation("Full Club Name"): The human-readable label for the plugin, which can be translated.
  • description = @Translation("Combine Title and District fields for clubs."): Provides more information about what this processor plugin does.
  • stages = { "add_properties" = 0 }: Specifies that this plugin operates at the “add_properties” stage with a weight of 0.
  • locked = true: The processor is locked to the index and cannot be removed through the admin UI.
  • hidden = true: The processor is hidden from the admin UI.

This annotation is essential as it defines how Drupal should treat the class that follows. It specifies everything from the plugin’s ID and label to more nuanced behavior like the stages it participates in and whether it’s locked or hidden in the UI.

Methods Explained

After defining the plugin annotation, the core of your plugin lies in the methods you implement. Here are the essential methods you’ll typically need in a Search API Processor Plugin and what each does:

getPropertyDefinitions(DatasourceInterface $datasource = NULL)

This method is responsible for defining new properties that the plugin will add or manipulate. It is invoked during the “add_properties” stage as specified in our plugin annotation. If your plugin needs to create new fields for the search index, this is where you define them.

preprocessIndexItems(PreprocessIndexItemsEvent $event)

This method is invoked for populating the values of the fields you’ve defined in getPropertyDefinitions(). If you’re manipulating existing fields or adding new ones, you specify the logic here. It receives an event object that contains all items about to be indexed, allowing you to change their properties before they get sent to the search index.

Step 3: Enabling the Plugin and Clearing Cache

After you’ve written the code for your custom Search API Processor Plugin, you need to make sure it’s recognized by Drupal and the Search API.

If the module is not yet enabled

If your custom module isn’t enabled yet, navigate to the Extend page (/admin/modules) in your Drupal admin interface, find your custom module, and enable it.

If the module is already enabled

If your custom module containing the plugin is already enabled, Drupal won’t automatically detect the new plugin. You’ll need to clear the cache for the changes to take effect. You can clear the cache via the admin interface by navigating to Configuration > Development > Performance (/admin/config/development/performance) and clicking “Clear all caches.”

Alternatively, you can clear the cache using Drush with the following command:

drush cr

Step 4: Configure the Search API Index

After you enable the module and clear the cache, navigate to your Search API index field settings by going to /admin/config/search/search-api/index/your-index/fields.

  1. Click on the “Add fields” button, usually found at the top of the page. This action will reveal a list of available fields.
  2. In this list, you should find your newly added custom field labeled Full Club Name.
  3. Select this field and then click on the “Add” button next to the field name to include it in your index.
  4. Click on Done.
  5. Finally, re-index your content to ensure that the new custom field is populated and becomes searchable.
Custom fields added to the index

Utilizing the Custom Field in Views and Search

Once you’ve enabled your custom module and cleared the cache, your custom Search API Processor Plugin should be activated. What this means for you:

Index View Field Availability

Your new custom field Full Club Name will be available in the list of fields when you’re creating or editing an index view in Drupal. This gives you the ability to include this aggregated data as part of your search results or views listings.

Full-Text Search Filters

If you’ve defined the custom field as a ‘Full Text’ type in your Search API settings, you can also use this field as a filter criteria within the index view. This allows users to perform full-text search queries specifically on this combined field, potentially improving the accuracy and relevance of search results.

Conclusion

This guide has walked you through the process of creating a custom Search API Processor Plugin in Drupal 8, 9, and 10. The plugin, named FullClubName, combines the title and field_cl_district_name fields from the Club content type into a single searchable field. This enhances your search capabilities and is a perfect example of how flexible and extensible Drupal can be.

Happy Debugging!


Posted

in

,

by

Tags: