Menu views field plugin

I need to show which menus content is found in, so I'll create a views field plugin so we can add a field that lists menus for a node.

I found \Drupal\user\Plugin\views\field\Roles to be a good example to follow.

This extends the PrerenderList abstract class, which provides default configuration for the list type and separator.

Roles loads the database service for a query, which is the same source we'll want to use.

In preRender(), Roles uses a database query and massages the results to use in render_item(). I'll change this in my class and keep the rest of the Roles class.

Init() and Query() ensure the nid field is available in the view. See how $this->additional_fields are loaded by FieldPluginBase::addAdditionalFields().

The meat of this is in preRender(), where I use this database query to fetch from the menu_link_content_data table, extracting the node ID from the link__uri column so we can join the table. The link__uri column stores data as entity:TYPE/ID. The substr in the where filters links to node content, and the replace fetches the nid value. The results of this query list nid and menu_name. The foreach formats the results to be consumed by the render_item() function.

  public function preRender(&$values) {
    $nids = [];
    $this->items = [];

    foreach ($values as $result) {
      $nids[] = $this->getValue($result);
    }

    if ($nids) {
      $result = $this->database->query("select replace(link__uri, 'entity:node/', '') nid, menu_name from menu_link_content_data where substr(link__uri, 1, 12) = 'entity:node/'");
      foreach ($result as $menu_link) {
        $this->items[$menu_link->nid][$menu_link->menu_name]['menu_name'] = t($menu_link->menu_name);
      }
    }
  }

  public function render_item($count, $item) {
    return $item['menu_name'];
  }

 

There are a few more functions in Roles - documentSelfTokens() and addSelfTokens() which can be implemented as needed.

 

Next you need to tell views about this field in hook_views_data():

function hook_views_data() {
  $data = [];

  $data['node_field_data']['menu_name'] = [
    'field' => [
      'id' => 'menu',
      'title' => t('Menu name'),
      'help' => t('Name of the menu')
    ]
  ];
}

 

Tags
Views