Skip to main content
Remove tags from title
Link
norman.lol
  • 19.1k
  • 6
  • 75
  • 129

Pager How can I implement paging for a custom view query plugin which displays data from an external api Drupal 8API?

added hooks to tags
Link
Kanna
  • 29
  • 2
Source Link
Kanna
  • 29
  • 2

Pager for custom view query plugin which displays data from external api Drupal 8

Hi I have a requirement to display the data from external api but should not be imported into any entities. What I did is I have written a custom view query plugin which displays the data from external api. What I did is I have used the GuzzleHttp Client to get the data. Here is how my service looks like

 namespace Drupal\***_services; use Drupal\Component\Serialization\Json; class NewsBlogsClient { /** * @var \GuzzleHttp\Client */ protected $client; /** * NewsBlogsClient constructor. * * @param $http_client_factory \Drupal\Core\Http\ClientFactory */ public function __construct($http_client_factory) { $this->client = $http_client_factory->fromOptions([ 'base_uri' => 'https://****************/', ]); } /** * Get all the news. * * @return array */ public function getNews() { $response = $this->client->get('****'); $data = Json::decode($response->getBody()); return $data; } /** * Get all the blogs. * * @return array */ public function getBlogs() { $response = $this->client->get('****'); $data = Json::decode($response->getBody()); return $data; } } 

I called the service into my plugin query and mapped it to the view fields that I have created using hook_views_data(). Here is how my plugin query looks like.

namespace Drupal\****\Plugin\views\query; use Drupal\views\ViewExecutable; use Drupal\views\ResultRow; use Drupal\views\Annotation\ViewsQuery; use Drupal\Core\Annotation\Translation; use Drupal\views\Plugin\views\query\QueryPluginBase; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Datetime\DrupalDateTime; /** * Views query plugin which wraps calls to the *** API in order to * expose the results to views. * * @ViewsQuery( * id = "news", * title = @Translation("News"), * help = @Translation("Query against the API.") * ) */ class News extends QueryPluginBase implements ContainerFactoryPluginInterface { /** * @var \Drupal\*****\NewsBlogsClient */ protected $newsBlogsClient; /** * FeaturedNews constructor. * * @param array $configuration * @param $plugin_id * @param $plugin_definition * @param $newsBlogsClient \Drupal\****\NewsBlogsClient */ public function __construct(array $configuration, $plugin_id, $plugin_definition, $news_blogs_client) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->newsBlogsClient = $news_blogs_client; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('news_blogs_client') ); } /** * * {@inheritdoc} */ public function execute(ViewExecutable $view) { $index = 0; if ($news_items = $this->newsBlogsClient->getNews()) { foreach ($news_items as $news_item) { $row['title'] = $news_item['title']; $row['link'] = $news_item['view_node']; $date = $news_item['field_published_date']; $dateTime = new DrupalDateTime($date); $timestamp = $dateTime->format('U'); $row['pubdate'] = $timestamp; $row['summary'] = $news_item['field_short_description']; $row['thumbnail'] = $news_item['uri']; // 'index' key is required. $row['index'] = $index++; $view->result[] = new ResultRow($row); } } } /** * Ensures a table exists in the query. * * This replicates the interface of Views' default SQL backend to simplify * the Views integration of the API. Since the API has no * concept of "tables", this method implementation does nothing. If you are * writing API-specific Views code, there is therefore no reason at all * to call this method. * See https://www.drupal.org/node/2484565 for more information. * * @return string * An empty string. */ public function ensureTable($table, $relationship = NULL) { return ''; } /** * Adds a field to the table. In our case, the API has no * notion of limiting the fields that come back, so tracking a list * of fields to fetch is irrelevant for us. Hence this function body is more * or less empty and it serves only to satisfy handlers that may assume an * addField method is present b/c they were written against Views' default SQL * backend. * * This replicates the interface of Views' default SQL backend to simplify * the Views integration of the API. * * @param string $table * NULL in most cases, we could probably remove this altogether. * @param string $field * The name of the metric/dimension/field to add. * @param string $alias * Probably could get rid of this too. * @param array $params * Probably could get rid of this too. * * @return string * The name that this field can be referred to as. * * @see \Drupal\views\Plugin\views\query\Sql::addField() */ public function addField($table, $field, $alias = '', $params = array()) { return $field; } } 

Everything is working great. I can display and control the data through views. The only missing thing is paging. The API is also from another Drupal application which supports pagination. I also need to setup a pager for this query. Tried lot of things but didn't work. I don't know how actually a view pager works. Can anyone explain and provide me any example snippet or code to work with.