I'm not sure what's going on but I can't for the life of me set node link weight using hook_node_view_alter().

Here's how I'm currently trying to set the weight of specific links... Which obviously doesn't work.

 function newslink_node_view_alter(&$build) {
// dpm($build);	 
  $build['links']['comment_news']['#weight'] = -1;
  $build['links']['comment']['#weight'] = -2;
}

I should also note that keying the individual links doesn't work either.

  $build['links']['comment_news']['#links']['comment-update']['#weight'] = -1;
  $build['links']['comment']['#links']['comment-add']['#weight'] = -2;

Comments

walker2238’s picture

I'm starting to think that this isn't possible.

Jaypan’s picture

The example on the manual page seems to indicate that it should be possible. Are you sure you are adding the weights to the correct element? Try dumping the $build array to see how it is organized:

debug($build, 'Build array', TRUE);

Also, have you cleared your cache after creating this function? I'm not sure if this hook is cached or not, but it may be.

walker2238’s picture

Thanks for the reply.

I'm using the devel module to get the structure so I'm fairly certain that I'm using the correct elements.

I have read the page that you are referring to and it isn't clear if this applies to individual links.

And yes, I cleared cache after creating the function.

walker2238’s picture

So far the only progress I've made was to sort the grouping of links.

// Sort links by weight.
$weight = array();

foreach ($build['links'] as $key => $link) {
  if ($key == 'comment') {
    $links[$key]['weight'] = -3;
  }
  elseif ($key == 'node') {
  $links[$key]['weight'] = -2;
  }
  else {
  // rest of the links will have weight 0
  $links[$key]['weight'] = 0;
  }
  // an array to use in array_multisort
  $weight[$key] = $links[$key]['weight'];
  }

array_multisort($weight, SORT_ASC, $build['links']);

How could I take this one step further and mix the links groupings to the a node link (read more) could be weighted between links generated by the comment module?

// Comment link, a.
$build['links']['comment']['#links']['comment-comments']

// Node link.
$build['links']['node']['#links']['node-readmore']

// Comment link, b
$build['links']['comment']['#links']['comment-add']
walker2238’s picture

Has anyone been able to order node links? I still can't figure this out.

I'm starting to think that this isn't possible but hope to be proved wrong.

Sansui’s picture

I am currently looking for a solution to re-ordering node links as well

Sansui’s picture

Well, from what I can tell, it would seem that links are definitely rendered in the order they appear in the array. Cannot simply add or specify a weight.

So, if you want to reorder these links, you will have to remove them from the array then re-add them at the point you want them. Not exactly elegant...

walker2238’s picture

Yeah seems to be a dead end. You can change the order of links that are contained in a group (Node for example). But still can't figure out a way to mix in match... Like have a comment link between two node links and so on.

I had previously been able to do this in D6 but so many functions have changed.

Sansui’s picture

Maybe you could mix and match in a node preprocess function to change the render array for the links, since I guess that's the only level you'd be able to alter their order in such a way now (once rendered content is available). I'm looking at possibilities in setting up a configurable module per content type for a drag and drop reordering - it's a reasonably high priority for me since I have links I add and reorder on most drupal sites I create. If I go this route I will try to make a sandbox to share or post at the d6 module for link weight

walker2238’s picture

Hey Sansui any progress on this?

MrHaroldA’s picture

I used this to set the 'flag' node link as first link:

/**
 * Implements hook_node_view_alter().
 */
function MODULE_node_view_alter(&$build) {
  $build['links'] = array(
    'flag' => $build['links']['flag'],
  ) + $build['links'];
}
f4nt0m’s picture

I spent almost 2 hours looking at all the options including the discussed $build...['weight'] method and also manipulating the $links array. I ended up using the following which helps me move my 'Log in or Register to post comments' (content -> link -> comment) link to the bottom of the list below my other links i.e. ShareThis etc.

Very simple, chuck the following into your template.php:

function [template]_preprocess_node(&$variables) {
	
	if (isset($variables['content']['links']['comment'])) {
		$comment = $variables['content']['links']['comment'];
		unset($variables['content']['links']['comment']);
		$variables['content']['links']['comment'] = $comment;
	}

Replace 'comment' with whatever your link machine-name is (do a dsm($variables['content']['links'] to get a list). As always, be sure to CTFC!

Hope this helps. :)

jncruces’s picture

I think that the best way is with theme_links hook:

Place this content in your template.php of your theme and replace the variables['links'] for your custom links:

function THEME_links($variables) {

  //Custom order
  if(!empty($variables['links'])) {
    $aux=array();
    if(!empty($variables['links']['flag-commons_follow_node'])) {      
      $variables['links']['flag-commons_follow_node']['weight']=0;
    }
    if(!empty($variables['links']['comment-add'])) {
      $variables['links']['comment-add']['weight']=1;
    }
    if(!empty($variables['links']['flag-inappropriate_node'])) {
      $variables['links']['flag-inappropriate_node']['weight']=2;
    }
    if(!empty($variables['links']['node-readmore'])) {
      unset($variables['links']['node-readmore']);
    }
    uasort($variables['links'], 'drupal_sort_weight');
  }
  //END custom order
  

  $links = $variables['links'];
  $attributes = $variables['attributes'];
  $heading = $variables['heading'];
  global $language_url;
  $output = '';

  if (count($links) > 0) {
    // Treat the heading first if it is present to prepend it to the
    // list of links.
    if (!empty($heading)) {
      if (is_string($heading)) {
        // Prepare the array that will be used when the passed heading
        // is a string.
        $heading = array(
          'text' => $heading,
          // Set the default level of the heading.
          'level' => 'h2',
        );
      }
      $output .= '<' . $heading['level'];
      if (!empty($heading['class'])) {
        $output .= drupal_attributes(array('class' => $heading['class']));
      }
      $output .= '>' . check_plain($heading['text']) . '</' . $heading['level'] . '>';
    }

    $output .= '<ul' . drupal_attributes($attributes) . '>';

    $num_links = count($links);
    $i = 1;

    foreach ($links as $key => $link) {
      $class = array($key);

      // Add first, last and active classes to the list of links to help out themers.
      if ($i == 1) {
        $class[] = 'first';
      }
      if ($i == $num_links) {
        $class[] = 'last';
      }
      if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))
         && (empty($link['language']) || $link['language']->language == $language_url->language)) {
        $class[] = 'active';
      }
      $output .= '<li' . drupal_attributes(array('class' => $class)) . '>';

      if (isset($link['href'])) {
        // Pass in $link as $options, they share the same keys.
        $output .= l($link['title'], $link['href'], $link);
      }
      elseif (!empty($link['title'])) {
        // Some links are actually not links, but we wrap these in <span> for adding title and class attributes.
        if (empty($link['html'])) {
          $link['title'] = check_plain($link['title']);
        }
        $span_attributes = '';
        if (isset($link['attributes'])) {
          $span_attributes = drupal_attributes($link['attributes']);
        }
        $output .= '<span' . $span_attributes . '>' . $link['title'] . '</span>';
      }

      $i++;
      $output .= "</li>\n";
    }

    $output .= '</ul>';
  }

  return $output;  
}