0

We have a Media type called Documents that has a Link field called field_link. We need to obtain the URL (external or internal) from the field so that we can use to wrap block elements inside of a <a> tag in our twig templates. All works fine when the link is an external URL, but when linking to an internal page, the following code does not work in our mymodule_preprocess_media hook.

How can I obtain both the internal and external link within the field_link field inside of the mymodule_preprocess_media hook?

This is what we have tried, but only works for external links.

function mymodule_preprocess_media(&$variables) {
  $media_entity = $variables['elements']['#media'];
  $link = $media_entity->get('field_link')->first();

  // This works for external, but not internal
  $link_value = $link->getUrl()->getUri();

  $variables['custom_var'] = [
    'link_value' => $link_value,
  ];
}

media--document.html.twig

<a href="{{ custom_var['link_value'] }}">
  <div>{{ name }}</div>
</a>

When using ksm($link->getUrl()), we find that the uri value is NULL when the link is internal.

Goals:

  1. Get the internal link (absolute) using hook_preprocess_media
  2. Get the external link using hook_preprocess_media
4
  • Just a guess: if (is_null($link->getUrl()->getUri())) { $link_value = \Drupal\Core\Url::fromUri($link); }
    – 100pic
    Commented Dec 26, 2018 at 23:07
  • 1
    Normally it doesn't matter if you have a field object or a field item, but for the Link field it does, use ->first() and then it should work, see drupal.stackexchange.com/questions/199262/…
    – 4uk4
    Commented Dec 27, 2018 at 9:50
  • @4k4 adding the ->first() did solve part of the issue, but it was still having an issue with internal links so i followed the solution provided by berramou Commented Dec 27, 2018 at 17:19
  • Yes, the key is the url object. Once you've got it from the field item all problems are solved. Then the possible solutions are countless, because all url handling in Drupal is built around this object. See the answers in the linked question and here.
    – 4uk4
    Commented Dec 27, 2018 at 19:18

1 Answer 1

1

Try the following:

/**
 * Implements hook_preprocess_media().
 */
function mymodule_preprocess_media(&$variables) {
  $media_entity = $variables['elements']['#media'];
  /**
   * @note: in case your field not multiple, otherwise loop through the field.
   */
  $link = $media_entity->get('field_link')->first();
  if ($link->isExternal()) {
    //- External.
    $link_value = $link->getValue()['uri'];
  }
  else {
    //- internal.
    $link_value = $link->getUrl()->toString();
  }
  $variables['custom_var'] = [
    'link_value' => $link_value,
  ];
}
1
  • this lead to my solution so it is being marked as such. if someone wants to get the absolute URL for internal links then they replace $link->getUrl()->toString() with URL::fromRoute($link->getUrl()->getRouteName(), $link->getUrl()->getRouteParameters(), ['absolute' => true])->toString();. Not sure if you want to update the answer to reflect this, but adding it just in case as a comment. Commented Dec 27, 2018 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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