1

I am trying to override node links by using hook_node_view_alter(), so my code looks like:

$cancel_link = 'admin/some_path/'.$found_id.'cancel';

$build['links']['node']['#links']['cancel'] = array(
        'title' => t('Cancel'),
        'href' => $cancel_link,
        'html' => TRUE,
        'attributes' => array(
          'title' => 'Cancel',
        ),
      );

and it works fine. But I also need to add "?destination=URL" to links and unfortunately, trying several different approaches didn't work for me. In particular:

I copied the whole Good Example code from https://www.drupal.org/docs/7/theming/overriding-themable-output/how-to-add-a-destinationurl-to-the-request-new-password and replaced my code with:

$build['links']['node']['#links']['cancel'] = l(t('Request new password'), 'user/password', array('query' => array('destination' => 'homepage', 'foo' => 'bar'), 'attributes' => array('title' => t('Request new password via e-mail.'))));

but the link didn't show up at all.

Example on https://www.zyxware.com/articles/5195/how-to-set-destination-as-the-link-value-in-the-l-in-case-of-urls-with-parameters didn't work.

Tried to adapt the accepted answer on use URL with query as URL destination as:

  $query_string = array('destination' => 'service/922');
  $url = url($cancel_link, array('query' => $query_string));
  $build['links']['node']['#links']['cancel'] = array(
    'title' => t('Cancel'),
    'href' => $url,
    'html' => TRUE,
    'attributes' => array(
      'title' => 'Cancel',
    ),
  );

unfortunately, it is also giving %3Fdestination%3Dservice/922 in the browser address bar. What I am doing wrong here?

Addition: Using dpm() I've figured out the above examples all output ready to use links like <a href="/user/password?destination=homepage&amp;foo=bar" title="Request new password via e-mail.">Request new password</a>

However, if I dpm the link in my function it still gives raw array:

(Array, 4 elements)
title (String, 6 characters ) Cancel
href (String, 33 characters ) admin/some_path/id/cancel
html (Boolean) TRUE
attributes (Array, 1 element)
title (String, 6 characters ) Cancel

And I wonder is it possible to add destination at this stage at all or do I have to intercept the link at a later steps like for example while themeing?

1 Answer 1

0

You are doing it correctly but the theme_links() function is called after you create the link. That function calls the l() function, which in turn calls the url() function, which in turn calls drupal_encode_path(), and it's here your Url is getting encoded.

If you override the theme_links() function, you can undo the encoding. Copy the theme_links() function from theme.inc into the template.php of your theme. The function should be named mytheme_links() or, if you want it to apply only to nodes, you can name it mytheme_links__node(). The original theme_links() function has this:

if (isset($link['href'])) {
  // Pass in $link as $options, they share the same keys.
  $output .= l($link['title'], $link['href'], $link);
}

You can replace it with this to undo the encoding:

if (isset($link['href'])) {
  // Pass in $link as $options, they share the same keys.
  $link_html = l($link['title'], $link['href'], $link);
  // Decode the link HTML before adding it to the output
  $link_html = rawurldecode($link_html);
  $output .= $link_html;
}

This is just a basic explanation. There are good reasons for encoding links, so you might want to restrict the links you decode.

1
  • I thought so. Thank you very much Frank, works like a charm!
    – Nick
    Mar 3, 2018 at 23:11

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.