Convert existing links to data-entity

Created on 21 October 2018, over 6 years ago
Updated 14 June 2023, over 1 year ago

The 5.x version uses data-entity-uuid and data-entity-type which has various advantages.

There are already hook_update functions to convert editor text formats from 4.x to 5.x. It would be useful if we could also convert existing fields. This would involve scanning field values for internal links and comparing to entity URLs, aliases or redirects. It could be a one-off migration (tricky?) or could be done next time the entity is saved.

✨ Feature request
Status

Closed: works as designed

Version

5.0

Component

Code

Created by

πŸ‡¬πŸ‡§United Kingdom adamps

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States wweibel

    I had the same need for this. IMHO this is not something I believe Linkit should manage - there may be cases where the link should not be converted. So, having this in a content (node, block, paragraph, etc) presave hook is what I ended up doing:

    <?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;
      }
    
    ?>
  • Status changed to Closed: works as designed over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States mark_fullmer Tucson

    I agree with the rationale that this is not something that the Linkit module should do automatically. The suggestion by wweibel for converting specific entities is great. I've added a documentation guide page to capture this suggestion at https://www.drupal.org/docs/extending-drupal/contributed-modules/contrib... β†’

    Closing this issue as "works as designed."

Production build 0.71.5 2024