Convert D7 input filter into D8 plugin for Graph API
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
- Filters are now annotated plugins instead of an info hook and callbacks
- Filters should now define their filter type; check_markup() can optionally skip filters of a certain type
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
- FILTER_TYPE_MARKUP_LANGUAGE: The filter converts something that's not HTML to HTML in a way that is not compatible with WYSIWYG editing.
- FILTER_TYPE_HTML_RESTRICTOR: The filter restricts the HTML allowed, for example, to protect against XSS.
- 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
.
- 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
- Check the change notice @ https://drupal.org/list-changes/drupal
- Check the API as a whole @ https://api.drupal.org/api/drupal/8
- Search for the class name @ https://api.drupal.org/api/drupal/classes/8