0

Currently the Linkit module delivers the link's title attribute by pulling the related node's title field.

We would like it to point to another field in the node.

How can we achieve this?

I looked into Editor Advanced Link module, but I need this to be automatic, and my custom field changes based on content type.

Maybe someone has a hook idea?

0

1 Answer 1

3

There are (at least) 2 options:

  1. Write a custom filter plugin, basing it on the LinkitFilter plugin included with the Linkit module. In the process() method, where the title is currently set, introduce you own logic to set the title field instead of the existing $entity->label().

    This method has the benefit of auto-updating when a referenced node's title changes, but does mean you'll have to maintain your filter alongside the Linkit module's releases. The process() method does a lot more than just setting the title, and new features/bug fixes in the module will need to be incorporated into your code.

  2. Alter the link dialog form (like Editor Advanced Link does), and get the title into the markup while it's still in the editor. This method is a bit easier, and less maintenance, but the title attribute won't update when the node title does. It will only update when the link dialog form is saved again.

    If that's acceptable, this is a rough but working example to get started:

    use Drupal\Core\Form\FormStateInterface;
    use Drupal\node\NodeInterface;
    
    function custom_module_form_editor_link_dialog_alter(&$form, FormStateInterface $form_state, $form_id) {
      array_unshift($form['#validate'], '_custom_module_link_dialog_validate');
    }
    
    function _custom_module_link_dialog_validate(array &$form, FormStateInterface $form_state) {
      $attributes = $form_state->getValue('attributes');
    
      if (isset($attributes['data-entity-type']) && $attributes['data-entity-type'] == 'node') {
        $node = \Drupal::service('entity.repository')
          ->loadEntityByUuid('node', $attributes['data-entity-uuid']);
        if ($node instanceof NodeInterface) {
          $override_title = '';
          switch ($node->getType()) {
            case 'page':
              $override_title = $node->field_title_override->value;
              break;
            case 'foo':
              // ...
              break;
          }
          if (strlen($override_title)) {
            $form_state->setValue(['attributes', 'title'], $override_title);
          }
        }
      }
    }
    
3
  • Thanks for these!
    – MastaP
    Feb 18, 2022 at 14:34
  • Thanks for these! And for editing my question to make it clearer. We would need this to only apply on the front end. And not all content type will have this field available. Is there a hook in the Linkit module that would allow for the filter to check if the node has a certain field existing and filled and replace it on the fly on the front end?
    – MastaP
    Feb 18, 2022 at 14:43
  • No, unfortunately it’s hard coded into the middle of the process method at the moment. You would need to replicate the whole filter for that approach
    – Clive
    Feb 18, 2022 at 15:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.