Convert existing links to data-entity
Some editors might want existing links added prior to installing Linkit to be stored as Drupal URLs, with <code>data-entity</code> metadata. This feature request was originally documented in #3008159: Convert existing links to data-entity.
The maintainers feel this should not automatically happen in the Linkit module. Therefore, developers wishing to perform this conversion can use an update hook to target specific entities. A solution by wweibel is shown below.
Note that the use of Url::fromUri() can cause memory issues if called in a loop, as per #3132913: Allow different uri protocols for more effecient url generation. If running this code in a loop, you may also want to considering using \Drupal::service('entity.memory_cache')->deleteAll() or \Drupal::service('entity_type.manager')->getStorage('...')->resetCache();
<?php
/**
* Convert hyperlinks to entity links.
*/
protected function convertHyperlinks(FieldableEntityInterface &$entity, $content, $field) {
$doc = Html::load($content);
foreach ($doc->getElementsByTagName('a') as $element) {
$href = parse_url($element->getAttribute('href'));
if (!(empty($href['host']) || str_contains(strtolower($href['host']), 'YOUR-SITE-HOSTNAME'))) {
// Not the healthcare site.
continue;
}
if (!empty($href['scheme']) && $href['scheme'] == 'mailto') {
// Content still using `mailto` links.
continue;
}
if (empty($href['path']) || $href['path'] === '/' || str_starts_with($href['path'], '#')) {
// Nothing, link to the homepage, or anchor.
continue;
}
$path = $href['path'];
if (!str_starts_with($path, '/')) {
$path = '/' . $path;
}
try {
// Would prefer not to use try-catch but 'bad' href could sneak through.
$url = Url::fromUri("internal:" . $path);
}
catch (InvalidArgumentException $e) {
continue;
}
if (!($url->isRouted() && str_starts_with($url->getRouteName(), 'entity.'))) {
// Not an entity route.
continue;
}
$route = $url->getRouteParameters();
$entity_type = key($route);
if (!in_array($entity_type, ['node', 'media'])) {
// Not an entity type to link.
continue;
}
$linked_entity = $this->entityTypeManager->getStorage($entity_type)->load($route[$entity_type]);
if ($entity) {
// Add data attributes same as when created in CKEditor.
// Linkit.
$element->setAttribute('data-entity-type', $entity_type);
$element->setAttribute('data-entity-substitution', 'canonical');
$element->setAttribute('data-entity-uuid', $linked_entity->uuid());
// Custom.
$element->setAttribute('data-entity-id', $linked_entity->id());
$element->setAttribute('data-entity-bundle', $linked_entity->bundle());
$element->setAttribute('data-internal-href', $this->pathAliasManager->getPathByAlias($path));
// Update to Drupal aware path.
$element->setAttribute('href', $this->pathAliasManager->getAliasByPath($path));
}
}
$content = $doc->saveHTML();
$content = Html::decodeEntities(Html::serialize($doc));
$entity->$field->value = $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