Adding keywords might be useful for search results perhaps if we include synonymous however there is not just yet a way to include Metatag keywords out of the box into Search API index then guess what, it turns out that I was asked to do that. So far it seems like I've been really busy with custom Search implementation lately.
I know, there are different ways to solve this particular requests, but I choose to create a search api processor plugin into my `keboca_search`. This pluging should live into `src/Plugin/search_api/processor` folder.
<?php
namespace Drupal\keboca_search\Plugin\search_api\processor;
use Drupal\node\Entity\Node;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;
/**
* Adds the item's Metatag keywords to the indexed data.
*
* @SearchApiProcessor(
* id = "add_metatag_keywords",
* label = @Translation("Metatag keywords field"),
* description = @Translation("Adds the item's Metatag keywords to the
* indexed data."),
* stages = {
* "add_properties" = 0,
* },
* locked = true,
* hidden = true,
* )
*/
class AddMetatagKeywords extends ProcessorPluginBase {
/**
* {@inheritdoc}
*/
public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) {
$properties = [];
if (!$datasource) {
$definition = [
'label' => $this->t('Metatag keywords'),
'description' => $this->t('The Metatag keywords defined on content.'),
'type' => 'string',
'processor_id' => $this->getPluginId(),
];
$properties['search_api_metatag_keywords'] = new ProcessorProperty($definition);
}
return $properties;
}
/**
* {@inheritdoc}
*/
public function addFieldValues(ItemInterface $item) {
/** @var \Drupal\node\Entity\Node $node */
$node = $item->getOriginalObject()->getValue();
if ($node instanceof Node && $node->hasField('field_metadata')) {
/** @var \Drupal\metatag\MetatagManager $metatag_manager */
$metatag_manager = \Drupal::service('metatag.manager');
$tags = $metatag_manager->tagsFromEntity($node);
// Check description tags.
if (!array_key_exists('keywords', $tags)) {
return;
}
// Find fields based on property path.
$fields = $this->getFieldsHelper()
->filterForPropertyPath($item->getFields(), NULL, 'search_api_metatag_keywords');
// Walk-through fields to setup value.
foreach ($fields as $field) {
// Check data source id.
if (!$field->getDatasourceId()) {
// Add value.
$field->addValue($tags['keywords']);
}
}
}
}
}
After I flushed all caches, then I can browse to fields inside search index in order to include a new `Metatag keywords field` inside general section:
That said, I hope it helps you at some point somehow!
Happy coding!
Comments1
483
Thank your for posting this, I found it extremely useful and exactly what I was looking for. It appears that Drupal and Meta Tag have change a few things. For those following your guidance, they will need to update the addFieldValue function like that starts with:
if ($node instanceof Node && $node->hasField('field_metadata')) {
and update it to
if ($node instanceof \Drupal\node\NodeInterface && $node->hasField('metatag')) {
Then it worked for me.
Thanks again!