Hello people, is there any way how to change to order how the $links are displayed? I would like to have the "read more" as the first, then the other links. Any solution working in Drupal 5.1? Thanks.

Comments

dldege’s picture

You can only alter the order by writing some code as far as I know.

You can either alter it in hook_link_alter http://api.drupal.org/api/HEAD/function/hook_link_alter

before they go to the theme engine

or in your theme by providing your own version of

theme_links http://api.drupal.org/api/HEAD/function/theme_links

dLd

kimangroo’s picture

Would be really helpful for php dunces like me. I don't have a clue how to even start reordering the links with php... :(

alix’s picture

Sample code for theme_links would be very helpful. Anyone feel like becoming a hero by sharing some code?

VM’s picture

There is sample code on the api page

function theme_links($links, $attributes = array('class' => 'links')) { 
  $output = ''; 

  if (count($links) > 0) { 
    $output = '<ul'. drupal_attributes($attributes) .'>'; 

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

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

      // Automatically add a class to each link and also to each LI 
      if (isset($link['attributes']) && isset($link['attributes']['class'])) { 
        $link['attributes']['class'] .= ' '. $key; 
        $class = $key; 
      } 
      else { 
        $link['attributes']['class'] = $key; 
        $class = $key; 
      } 

      // Add first and last classes to the list of links to help out themers. 
      $extra_class = ''; 
      if ($i == 1) { 
        $extra_class .= 'first '; 
      } 
      if ($i == $num_links) { 
        $extra_class .= 'last '; 
      } 
      $output .= '<li class="'. $extra_class . $class .'">'; 

      if (isset($link['href'])) { 
        // Pass in $link as $options, they share the same keys. 
        $output .= l($link['title'], $link['href'], $link); 
      } 
      else if (!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']); 
        } 
        $output .= '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>'; 
      } 

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

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

  return $output; 
} 
kimangroo’s picture

I was kinda hoping for sample code of a custom written theme_links being used to change the order of the $links... ;)

tille’s picture

hi,

I was looking for the same thing - originally actually wanted split the links-array into pieces and then put the different parts into different variables so I could use them wherever..

After some browsing and trying out this and that I finally have this working 'code snippet'.. Might be that it's a bit dirty but it does exactly what I want it to do.. (it even hides the page-counter a.k.a. 'statistics_counter' from people who're not allowed to view it)

What came out was then the following code - an override of the theme_links function - digging out the 'add_to_cart' and the 'forward_links' and the 'statistics_counter' from the array $links and making it available for the node.tpl.php files.. - ..can probably also give out whatever parts from the $links..

this goes in the phptemplate:


function phptemplate_links($links, $attributes = array('class' => 'links')) {
  $output = '';
  
  // the variable for 'add_to_cart'
  global $cart_output;
  // the variable for 'forward_links'
  global $forw_output;
  // the variable for 'statistics_counter'
  global $stat_output;
  
  if (count($links) > 0) {
    $output = '<ul'. drupal_attributes($attributes) .'>';

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

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

      // Automatically add a class to each link and also to each LI
      if (isset($link['attributes']) && isset($link['attributes']['class'])) {
        $link['attributes']['class'] .= ' ' . $key;
        $class = $key;
      }
      else {
        $link['attributes']['class'] = $key;
        $class = $key;
      }

      // Add first and last classes to the list of links to help out themers.
      $extra_class = '';
      if ($i == 1) {
        $extra_class .= 'first ';
      }
      if ($i == $num_links) {
        $extra_class .= 'last ';
      }
	  
	  // this adds the 'class' to the $output so you get to know the 'names' of the different links:
          $output .= "class:".$class." ";
	  $output .= '<li class="'. $extra_class . $class .'">';
	  
	  $my_class = $class;
	  
      // Is the title HTML?
      $html = isset($link['html']) && $link['html'];

      // Initialize fragment and query variables.
      $link['query'] = isset($link['query']) ? $link['query'] : NULL;
      $link['fragment'] = isset($link['fragment']) ? $link['fragment'] : NULL;

      if (isset($link['href'])) {
        $output .= l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html);
		
		if($my_class=="add_to_cart") {
		  $cart_output = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html);
		}
		if($my_class=="forward_links") {
		  $forw_output = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html);
		}
		if($my_class=="statistics_counter") {
		  $stat_output = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html);
		}
		
      }
	  
      else if ($link['title']) {
	  
        //Some links are actually not links, but we wrap these in <span> for adding title and class attributes
        if (!$html) {
          $link['title'] = check_plain($link['title']);
        }
		
		if($my_class=="add_to_cart") {
          $cart_output = '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>';
		}
		if($my_class=="statistics_counter") {
          $stat_output = '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>';
		}
		if($my_class=="forward_links") {
		  $forw_output = '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>';
		}
		  
        $output .= '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>';
		
      }
	 $i++;
      $output .= "</li>\n";
    }

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

  return $output;

}

and then this goes into the node.tpl.php respectively the node-my_content_type.tpl.php wherever you want to display the different links:


	global $cart_output;
	global $forw_output;
	global $stat_output;
		
	  if($cart_output) {
		echo("<div>");
		echo($cart_output);
		echo("</div>");
	  }

	 if($forw_output) {
		echo("<div>");
		echo($forw_output);
		echo("</div>");
	  }

	 if($stat_output) {
		echo("<div>");
		echo($stat_output);
		echo("</div>");
	  }

hope it helps..:]

greetz, t..

___________________________
my pictures: www.bilderbook.org

___________________________

momper’s picture

hello tille

this should be moved into the handbook! great!

thanks and greetings
momper

thinkyhead’s picture

I found the simplest way to change link order was to merge the links array into a pre-ordered but blank set of links in hook_links_alter as follows. This works because when you merge a new array into an existing one, the original order prevails.

  // Preset the order of the links (empty will be removed)
  $ord = array('item_buy'=>'', 'item_permalink'=>'', 'forward_links'=>'', 'node_read_more'=>'', 'edit'=>'', 'comment_add'=>'');
  $links = array_merge($ord, $links);
  foreach ($links AS $module => $link) {
    if (empty($link)) {
      // remove empty links
      unset($links[$module]);
    } else {
      // or customize as desired
      switch ($module) {
        case 'forward_links':
          $links[$module]['title'] = t('send to a friend');
          break;
      }
    }

• scott lahteine, thinkyhead.com

Summit’s picture

Subscribing, still struggeling with this, greetings, Martijn

NoRandom’s picture

Hi

I don't know much about php, two questions:

1.- Where do you put this php code for ordering the links?

2.- Where do you find the "name" of the links (i.e. "item_buy", "item_permalink", "forward_links", etc...)?

Thanks in advance.

bjacob’s picture

Macarro, you've to create a new module or use an existing module. Make use of hook_link_alter(). If created a new module with the name 'custom_kit'. Therefore the name of the hook is 'custom_kit_link_alter(). Here is an working example:

function custom_kit_link_alter(&$node, &$links) {
  $ord = array('node_read_more'=>'', 'comment_add'=>'', 'comment_comments'=>'', 'comment_new_comments'=>'', 'edit'=>'', 'privatemsg_write_to_author'=>'', 'statistics_counter'=>'',);
  $links = array_merge($ord, $links);
  foreach ($links as $module => $link) {
    if (empty($link)) {
      unset($links[$module]);
    } else {
      unset($links['forward_links']);
    }
  }
}

If you want to get the names you've to enter then include the following lines right after function custom_kit_link_alter(&$node, &$links) {

  print "<pre>";
  print_r($links);
  print "</pre>";

It'll print you the links array and shows you the names. That's it.

My site: TRITUM - Björn Jacob
Check out: AJAX PARTNER

NoRandom’s picture

Thanks for your help, bjacob. It worked perfectly.

Now I'm on Drupal 6 and I create a mini-module to re-order the links. My PHP skills are not enough to create a good configurable module but I want to share the code because it can help others.

For Drupal 6.x:

  1. Create a folder in your modules directory called "movereadmore" (cheesy name... I know)
  2. Create a file called "movereadmore.info" inside with this content:
  3. ; $Id$
    name = Move read_more
    description = A test module wich moves read_more link at the last position.
    core = 6.x
    
  4. Create a file called "movereadmore.module" inside with this content:
  5. <?php
    function movereadmore_link_alter (&$links, $node) {
      /*print '<pre style="background:#fff;color:#000;">';
      print_r($links);
      print '</pre>';*/
    
      $first_keys = array();                              // Here you can select the link keys you want first
      $last_keys = array('comment_add', 'node_read_more'); // ...and here the link keys you want at the end.
    
      $first_links = array();
    
      foreach ($first_keys as $key) {
        if (isset($links[$key])) {
          $first_links[$key] = $links[$key];
          unset($links[$key]);
        }
      }
    
      $links = array_merge($first_links, $links);
    
      $last_links = array();
        foreach ($last_keys as $key) {
          if (isset($links[$key])) {
            $last_links[$key] = $links[$key];
            unset($links[$key]);
          }
        }
    
      $links = array_merge($links, $last_links);
    }
    
  6. Upload the module to your site and activate it

...and that's all, now you'll have your links in this order ??? | ... | ??? | comment_ad read_more

Maybe someone can convert this into a "real" module with configurable menus and such kind of things.

FINAL NOTE: hook_link_alter uses the parameters in different order in Drupal 5, so, the only change you should make to use this code in Drupal 5 would be:

DRUPAL 6: function custom_kit_link_alter(&$node, &$links) {
DRUPAL 5: function custom_kit_link_alter(&$links, &$node) {
asb’s picture

Unbelievable! There is no module for the management of $links in D7!

However, if you're still on D6, Link Weights, might come in handy sometimes.

Jaypan’s picture

Unbelievable! There is no module for the management of $links in D7!

Sounds like it would be a good module for you to develop and share with the community then.