You can do this automatically by creating your own text filter in a custom module.
Note that the /** @Filter ... */
in front of the class is not a comment, but an annotation, it has to be included in the file. Replace all fancy uppercase stuff with your own code.
src/Plugin/Filter/MYFANCYFILTER.php
<?php
namespace Drupal\MY_MODULE\Plugin\Filter;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\Component\Utility\Html;
/**
* @Filter(
* id = "MY_FANCY_FILTER",
* title = @Translation("My fancy filter"),
* description = @Translation("Makes HTML even more fancier"),
* type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE
* )
*/
class MYFANCYFILTER extends FilterBase {
public function process($text, $langcode) {
$result = new FilterProcessResult($text);
$dom = Html::load($text);
$xpath = new \DOMXPath($dom);
// to select all links you have to create a XPath query
// the example query below selects all <a> tags which have a "href" attribute
// see https://www.w3schools.com/xml/xpath_syntax.asp
foreach ($xpath->query("//a[@href]") as $element) {
// the example logic below accepts all links starting with "http://" or "https://" or "//"
if (preg_match('|^(https?:)?//.+|', $element->getAttribute('href')) === 1) {
// see https://www.php.net/manual/de/class.domelement.php
// for docs about manipulating HTML markup
$element->setAttribute('MY_ATTRIBUTE', 'MY_VALUE');
}
}
$result->setProcessedText(Html::serialize($dom));
return $result;
}
}
Then enable your new text filter for the corresponding text format in
Configuration > Content authoring > Text formats and editors