Xem qua 1 số chức năng Drupal 8, Plugins, Guzzle, CMI, Caching

Xem qua 1 số chức năng Drupal 8, Plugins, Guzzle, CMI, Caching

Drupal 8, Plugins, Guzzle, CMI, Caching... If those buzzwords trigger your interest, you should keep reading this article. We will cover those topics as we are building one of our first Drupal 8 modules. Recently one of our clients requested a solution to integrate a custom feed called IBP Catalog. The IBP Catalog is a filterable XML feed, which enable to easily collect web component like banners, documents or even audio files. Those components are selected by the broker through a dedicated website.

So to recap, each broker has its own feed which can be filtered to return a list of web component urls. Those components could be injected into blocks through iframes for example.

How did we build our IBP catalog module? Let's start with the main ideas:

  1. Create a HTTP client to fetch the XML feed
  2. Implement a custom block
  3. Define a caching strategy
  4. Store and retrieve some config values

HTTP Client API

Drupal 7 provides its own - but quite minimal - outgoing HTTP capability through the drupal_http_request() method. Well, in Drupal 8, it's all gone away and replaced by \Drupal::httpClient(). Behind the static function you will find the very powerful and flexible Guzzle framework. Guzzle is a PHP HTTP client that makes it very easy to consume web services. Luckily Drupal 8 has already adopted its latest version (version 4), so you can enjoy all its trimmings. Guzzle has many advantages over the old drupal_http_request(). It's well documented, full of awesome features and very well supported. It's a huge step forward when it comes to consume external web services. Anyway enough talking and on with some code. For a full and workable version of the module, check out the contrib module called IBP Catalog on drupal.org.

// Create a HTTP client.
$client = \Drupal::httpClient();

// Set default options for our HTTP request.

// Define a 2 secondes timeout.

$client->setDefaultOption('timeout', 2);

// Create a GET request.

$request = $client->createRequest('GET', 'http://path_to_xml_feeds');
// Add a few query strings.
$query = $request->getQuery();
$query->set('key', 'value');
 
// Clients will only throw exceptions that are a subclass of GuzzleHttp\Exception\RequestException.
try {
  $response = $client->send($request);
} catch (RequestException $e) {
  // Do some stuff in case of the error.
}
 
// If successful HTTP query.
if ($response->getStatusCode() == 200) {
  // We are expecting XML content. Yeah Guzzle can parse it!
  try {
    $xml = $response->xml();
  } catch (ParseException $e) {
    // Do some stuff in case of the error.
  }
  $xml = $response->xml();
  // Do some stuff with the xml object.
}

This is it. This is the only code you need to call the web service and convert the response into a SimpleXMLElement object, which is easy to manipulate. Of course, Guzzle can do much more. To list a few, it can run requests in parallel, manages cookies, and nevertheless it also provides an events system. In fact, we are planning to use the event system to replace our (bad) blocking HTTP requests.

Block API

In Drupal 8, blocks are now plugins. Plugins are the object oriented paradigm of an info hook combine with a number of related implementation hooks, which put all together provide some reusable and specific functionality.

Defining a block is straight forward. First we need to create a class. For the IBP Catalog module, we called it IBPCatalogBlock and it's located undersrc/Plugin/Block/IBPCatalogBlock.php to follow the PSR-4 pattern. Blocks always implement the BlockPluginInterface interface. If you extend the abstract BlockBase class, you are only required to implement the build()method. Of course other methods can be overridden based on your requirements.

Next thing on the list is to define the specially formatted comments calledannotations. Annotations are meta information describing classes that can be read at runtime. People tend to love or hate them. What do you think ? In Drupal 8, block annotations enable your components to be discovered. They provide, in this case, useful metadata like an ID, a human label and a category.

Check our code on drupal.org for a full working example of our block implementation. Really, it's not that difficult, and it's kind of cool to have the whole implementation sitting in a single file/class.

 
/**

 * Provides an 'IBP Catalog' block with the selected items from the feed.

 *

 * @Block(

 *   id = "ibpcatalog_block",

 *   admin_label = @Translation("ibpcatalog Block"),

 *   category = @Translation("Custom")

 * )

 */

class IBPCatalogBlock extends BlockBase {


  /**

   * {@inheritdoc}

   */

  public function build() {

    // build your items list....

    $items = ...

    return array(

      '#theme' => 'ibpcatalog',

      '#items' => $items,

    );

  }

}

Caching API

As we are calling an external service, it's really important to cache the response. Not doing so will result in a sluggish website that will not only be a hassle for your visitors, but could also impact your search ranking. For those familiar with the Drupal 7 Cache API, picking up caching in Drupal 8 will not be a problem. Alongside an object oriented lifting, the caching APIoffers news features which make it more powerful and flexible:

  • Cache storage is separated into "bins", each containing various cache items. Common bins are "data", "bootstrap", "render"...

  • Cache tags makes cache invalidation better and smarter. Cache tags will improve your cache hit ratios and therefore your site performance.

  • New methods to permanently delete or invalidate the cache entries.

The example below is very easy. It uses the "data" bin and will cache the compiled data for one hour.

// Try to get block from the cache.

if ($cache = \Drupal::cache()->get($cid)) {

  // Get cache.

  $items = $cache->data;

}

else {

  // Build cache and do you time consuming task.

  $items = $this->getItems();

  // Only store cache if valid.

  if ($items) {

    $expire = time() + 3600;

    \Drupal::cache()->set($cid, $items, $expire);

  }

}

Configuration API

Drupal 8 comes with an API to read and write configuration values. The simplest way to use this is to call the Drupal::config() static method.

/ Get module configuration.

$module_config = \Drupal::config('ibpcatalog.settings');

$this->key = $module_config->get('key');
 

Conclusion

The IBP Catalog is a very specific module. Brokers websites, which might use it, are definitely a small niche market. But the module implements a lot of new or inhanced features of Drupal 8. Feel free to dig into the code and contribute if you can. It's the best way to learn "the soon to be released" Drupal 8. You will find a practical example of how to create a config form, add a new admin page, play with the caching API and much more...

Bạn thấy bài viết này như thế nào?: 
No votes yet
Ảnh của Tommy Tran

Tommy owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy

Tìm kiếm bất động sản

 

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Không nên cloning database, dev-stage-production workflow

Không nên cloning database, dev-stage-production workflow

However, in a dev-stage-production workflow, the database is often still periodically cloned back upstream:

Học Drupal Seo qua 11 khái niệm của www.litado.com

Học Drupal Seo qua 11 khái niệm của www.litado.com

Với gần 400 khái niệm, kỹ thuật, thuật ngữ kinh điển về Seo, Adwords, Analytics, Webmasters Tool, Hosting, Domain....được cập nhập mới nhất cùng với các phần mềm

Chúng ta có thể kiếm tiền từ Drupal Appstore

Chúng ta có thể kiếm tiền từ Drupal Appstore

Presently the drupal community is in an uproar, triggered by Robert Douglass' announcement of his session at the Drupal Dev Days in Brussels

Công ty diệt chuột T&C

 

Diet con trung