Skip to main content
T

here are two kind of filters in Drupal, Text format filters and Views field filter. In this article we will discuss Views field filter in details.

We will create a filter that filters a node which is the latest one created. This is interesting when used in connection with other filters especially taxonomy term for a specific vocabulary. For example show me all articles with term Backend except the latest one with any term in the vocabulary. 

Let's explain it further, I have a vocabulary Articles which contains terms (Backend, Frontend & DevOps). When I create a new article I can assign one or more terms to it since some articles may belong to multiple terms like both Backend & Frontend and so on.

Now I want to show the latest article on front page which is easy to achieve using the existing Views filters (Authored on field) and limit result to one. But I don't want to show this latest article in any list of Backend, Frontend or DevOps since this has been already shown on front page and I don't want a duplicate link/article.

Now a million dollar comment is that the Backend list doesn't know if the latest article on front page is selected from this list or not and so are Frontend & DevOps lists. They are simply filtered on corresponding taxonomy terms (backend, frontend, devops). 

In simple words and yet in simple SQL this is the problem of sub-query i.e first we find the latest article with a sub-query and then filter it in the main query like nid != latest article id.

A pseudo code would look something like the following: 

SELECT * FROM CONTENT_TYPES
WHERE field_tags  = Backend
AND NID != ( SELECT NID FROM CONTENT_TYPES ORDER BY authored_on DESC LIMIT 1);

 

Views Filter

A filter determines what items to include in the final results. In Drupal they are equivalent of WHERE clause of SQL. Drupal Views module provides  filter plugins that can handle filtering on core fields and generic data like string and numbers. But in some situations these filters don't meet our requirements like the one explained in the Description of this article. 

I want the list of all articles belonging to term Backend, except the latest one which has been chosen for the front page.

What to do ?

In this article we will learn:

  1. How to create a View filter plugin
  2. How to associate it with a field type
  3. How to use it in Views GUI

1. Define a new plugin

Create a directory articles and add the following files as usual:

structure

2. Implement hook_views_data

Use hook_views_data() (or hook_views_data_alter()) to associate the custom filter with one or more fields that it can be used on. To d so we implement the hook_views_data in articles.module and the configuration array.

3. Using a hook

An alternative easier way is to implement the hook_views_query_alter in a modulename.module file:

<?php

use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_query_alter().
 */
function articles_views_query_alter(ViewExecutable $view, QueryPluginBase $query)
{
    if ($view->id() == 'try_field_token_plugin') {
        // Filter out latest article
        $q = \Drupal::entityQuery('node')
            ->condition('type', 'landing_page')
            ->sort('created', 'DESC')
            ->range(0, 1)
            ->accessCheck(FALSE);
        $ids = $q->execute();

        $query->addWhere('', 'node_field_data.nid', reset($ids), '!=');
    }
}

 

Demo

Live demo on this site, observe than main content area and sidebar lists, the Article showing in content area is not shown in any link:

https://blog.softhem.net/