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
  • Just a guess: if (is_null($link->getUrl()->getUri())) { $link_value = \Drupal\Core\Url::fromUri($link); } – 100pic Dec 26 '18 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/… – 4k4 Dec 27 '18 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 – usernameabc Dec 27 '18 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. – 4k4 Dec 27 '18 at 19:18
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,
  ];
}
  • 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. – usernameabc Dec 27 '18 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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