Convert D7 input filter into D8 plugin for Graph API

Trivial Graph Format for Graph API
G FilterTrivialGraphFormat FilterTrivialGraphFormat @Filter @Filter FilterTrivialGraphFormat->@Filter FilterBase FilterBase FilterTrivialGraphFormat->FilterBase FilterInterface FilterInterface PluginBase PluginBase FilterBase->PluginBase FilterBase->FilterInterface

For Graph API the Trivial Graph Format submodule introduced into 7.x-1.x needed an upgrade to Drupal 8 lingo. My initial thought was to upgrade the sub module to discover hook_filter_info was gone.

Checking the filter.api.php there is more gone then kept.

Change Records

So what to do? Check for change records! Two items for hook_filter_info currently where

Plugin

Once you know it's a plugin it is almost trivial apart from the annotated part.

Being a plugin means you are building a class which resides into sites/all/graphapi/lib/Drupal/graphapi/ directory tree somewhere. (Note this is PSR-0 tree and probably will change into PSR-4 tree. See PSR-4: Putting it all together)

Thanks to almaudoh's remark I learned we have an enforced directory tree.

Plugins belong to the Plugin and filter plugins in the Filter so the full path is now lib/Drupal/graphapi/Plugin/Filter.

Let's make a copy of the core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtml.php and we have lib/Drupal/graphapi/Plugin/Filter/FilterTrivialGraphFormat.php ... almost that is as we need proper annotations.

Annotation

These were defined for FilterTrivialGraphFormat like this (still buggy)

/**
 * Provides a filter for rendering Trivial Graph Format.
 *
 * @Filter(
 *   id = "filter_tgf",
 *   module = "graphapi",
 *   title = @Translation("Trivial Graph Format"),
 *   type = FILTER_TYPE_TRANSFORM_IRREVERSIBLE,
 *   settings = {
 *     "formats" = "",
 *     "filter_html_help" = 1,
 *     "filter_html_nofollow" = 0
 *   },
 *   weight = -10
 * )
 */
class FilterTrivialGraphFormat extends FilterBase {

This class documentation is trying to tell the discovery mechanism build into Drupal 8 to use the @Filter as it's annotation template.

This is as we now have learned located in core/modules/filter/lib/Drupal/filter/Annotation/Filter.php

Reading that files documentation explains the existence of all attributes as seen above apart from type.

type

Checking for the word type leads to Filterbase.php which has a

  public function getType() {
    return $this->pluginDefinition['type'];
  }

Type is documented in FilterInterface. But what do these mean? And why are it's values documented that weird?

Digging further leads to WYSIWYG in core: round one — filter types

  1. FILTER_TYPE_MARKUP_LANGUAGE: The filter converts something that's not HTML to HTML in a way that is not compatible with WYSIWYG editing.
  2. FILTER_TYPE_HTML_RESTRICTOR: The filter restricts the HTML allowed, for example, to protect against XSS.
  3. FILTER_TYPE_TRANSFORM_REVERSIBLE: The filter performs a transform for which a WYSIWYG plugin exists to perform the same transformation (and its reverse) client-side. For example, may be (reversibly!) transformed to
    Druplicon
    .
  4. FILTER_TYPE_TRANSFORM_IRREVERSIBLE: The filter performs a transform for which a WYSIWYG plugin does not exist to perform the transformation client-side (especially, the reverse of it); instead, the WYSIWYG editor displays the unfiltered text. For example, Token Filter.

Trivial Graph Format (extended version)

The image above is generated by the following filter input

[tgf engine:graphapi_svg
FilterTrivialGraphFormat|http://drupalcode.org/project/graphapi.git/blob/refs/heads/8.x-1.x:/lib/Drupal/graphapi/Plugin/Filter/FilterTrivialGraphFormat.php
@Filter|https://api.drupal.org/api/drupal/core!modules!filter!lib!Drupal!filter!Annotation!Filter.php/class/Filter/8
FilterInterface|https://api.drupal.org/api/drupal/core!modules!filter!lib!Drupal!filter!Plugin!FilterInterface.php/interface/FilterInterface/8
FilterBase|https://api.drupal.org/api/drupal/core%21modules%21filter%21lib%21Drupal%21filter%21Plugin%21FilterBase.php/class/FilterBase/8
PluginBase|https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Component%21Plugin%21PluginBase.php/class/PluginBase/8
#
FilterTrivialGraphFormat @Filter
FilterTrivialGraphFormat FilterBase
FilterBase PluginBase
FilterBase FilterInterface
]

Next the resulting image done by Graph API (which is data encoded) is viewed (View image)

Finally it's SVG is copied into this blog.

A shorter version would without the links looks way shorter and easier to learn.

[tgf engine:graphapi_svg
FilterTrivialGraphFormat
@Filter
FilterInterface
FilterBase
PluginBase
#
FilterTrivialGraphFormat @Filter
FilterTrivialGraphFormat FilterBase
FilterBase PluginBase
FilterBase FilterInterface
]

Lessons learned

  1. Check the change notice @ https://drupal.org/list-changes/drupal
  2. Check the API as a whole @ https://api.drupal.org/api/drupal/8
  3. Search for the class name @ https://api.drupal.org/api/drupal/classes/8