Implementing a New Freelinking Plugin
Freelinking provides an API so that you can create your own indicator plugins.
The following documentation requires some knowledge of PHP, how to create a Drupal module and the Drupal Core Plugin API.
For this example, we will try to create a plugin to allow users to create freelinking links words on locale.drupal.org based on the user's language. We will call the module freelinking_drupal_localize.
The goal is to return a direct link to localize.drupal.org's page for a translated string. This is fictitious example because we have to link by string id so no one would use this anyway.
- Scaffold the following new directories inside your module project structure:
src/Plugin/freelinking. - Create a new PHP Class file inside this directory with the file name
DrupalLocalize.php, class nameDrupalLocalizeand the namespace\Drupal\freelinking_drupal_localize\Plugin\freelinking.
Freelinking Plugin Attribute
The Freelinking plugin PHP Attribute has properties described in the table below. Add the plugin annotation following this example:
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Freelinking localize.drupal.org lookup link plugin.
*/
#[Freelinking(
id: "freelinking_drupal_localize",
title: new TranslatableMarkup("localize.drupal.org Link"),
weight: 0,
hidden: false,
settings: [],
])
class DrupalLocalize extends FreelinkingPluginBase {| Property Name | Description | Example |
|---|---|---|
| id | The unique plugin ID to use. | freelinking_drupal_localize |
| title | A translatable title that will be displayed to users with administration privileges. | new TranslatableMarkup("Localize.drupal.org Link") |
| weight | An integer that is used to sort the plugins on the Text format page. | 0 |
| hidden | A boolean value used to hide the plugin from the Text format page. This should not normally used and is an internal property. | false |
| settings | An associative array of default configuration. | [] |
Explanation of methods to implement
getIndicator()
This method expects us to the Regular Expression pattern used to match the “indicator” that users will need to use the plugin. It is nice to provide a short hand as well.
public function getIndicator() {
// Allows [[ldo:]] or [[localizedrupalorg]] or [[localizedo]] among other possibilities.
return '/^l(ocalize)?d(rupal)?o(org)?$/';
}getTip()
This method expects us to return a translatable string to use as the link “tip”, which is displayed to users viewing the content when hovering over the anchor link.
buildLink()
The buildLink method is the main method of our plugin. It will return a render array to display as a link or a render array to display an error. The method argument $target is an associative array that describes the text. At this point, the Freelinking module has already determined that the text should be rendered using our plugin, and so no additional check is necessary.
| Key | Description | Example |
|---|---|---|
| text | The text that the user has input or the dest string. This is prefilled for you. | sets |
| indicator | The indicator string used. | ldo |
| dest | The target string which could be a node id, node title, etc.. In this case the string id. | 6 |
| tooltip | Unused. getTip should be used instead. | N/A |
| language | The object to use for the Url object. This would allow the anchor link to be translatable. | See \Drupal\Core\Language\LanguageInterface |
public function buildLink(array $target) {
return [
'#type' => 'link',
'#title' => $target['text] ? $target['text'] : $target['dest'],
'#url' => Url::fromUri(
'https://localize.drupal.org/translate/languages/es/translate',
[
'absolute' => TRUE,
'language' => $target['language'],
'query' => [
'sid' => $target['dest'],
],
]
),
'#attributes' => [
'title' => $this->getTip(),
],
];
}Now when the plugin is activated on a Text Format users can type [[ldo:6|sets]] to create external anchor links similar to <a href="https://localize.drupal.org/translate/languages/es/translate?sid=6">sets</a>.
What else can we do to improve this?
- If our mythical external link provided an API to lookup string ids, we could inject the http_client service into our plugin and do a lookup. This is fairly expensive as each freelink using this indicator would do so on an uncached node.
- We could provide a settings form to allow choosing which languages can be looked up.
You should now be able to write your own freelinking plugins that expand and allow your users to create wiki-like markup to link to other sites or internal content.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion