I would like to re-order the links that appear at the bottom of the content nodes, the "read more" and "email this page" and "unsubscribe" stuff.

Currently, there are a couple of links in the way of the "read more" link, which on our site is more important than the others.

I would also like to shorten the vocabulary on some of the links, so "email this page" becomes "email" or some such nonsense.

View my page so you can see what I mean: http://www.cctvcambridge.org

Does anyone have any tips? Thanks!

Sean

Comments

tclineks’s picture

Override theme_links in your theme's template.php or smartytemplate.php (PHPTemplate and Smarty theme engines, respectively).

Initially just copy the current code to a custom function named {theme_name_here}_links.

http://drupaldocs.org/api/head/function/theme_links

(code in template.php or smartytemplate.php -- depending on your theme-engine -- within your theme directory)

function seanstheme_links($links, $delimiter = ' | ') {
  if (!is_array($links)) {
    return '';
  }
  return implode($delimiter, $links);
} 

You can put your own sorting logic in there.

seaneffel’s picture

I understand how to copy and paste the code, but not sure where that code should be stuck in my template files. I'm using xtemplate.

Also, how do I set parameters for sorting the links - I don't speak PHP!

Thanks for your help so far!

Sean

kimangroo’s picture

From what I can work out in Drupal 5 you can use theme_links. Can anyone give an example of the php and logic you could use to reorder the links?

Would be really, really helpful!!

venkat-rk’s picture

Changing the vocabulary is pretty easy with the locale module. Here is a nice post that explains it in detail:
http://drupal.org/node/43791#comment-81553

seaneffel’s picture

Thanks for this link, it hit the spot!

venkat-rk’s picture

You're welcome:-)

Guru’s picture

I ended up here while doing a search as I wanted to achieve the exact same thing. However, the solution given above doesn't fit what I want.

Here's the solution I came up with (quite simple, yet had to dig into how PHP deals with arrays):

	// first check if the $links array contains the 'array_key' (name of the link/module you want to move)
	if( isset( $links['array_key'] ) ) {
		// then create a temporary array (I don't know whether this is required or optional)
		$temp_arr = array();
		
		// assign the existing array (of the link) to the temporary array
		$temp_arr = $links['array_key'];

		// delete the existing array, so that you don't get duplicates, and only one instance of the array (link) is published
		unset( $links['array_key'] );
		
		// this does the magic, as it prepends the $links with the temporary array, thus moving your link to be the first one
		array_unshift( $links, $temp );

		// finally unset ... i think this is necessary for performance
		unset( $vote );
	}

Woohoo! My first post here finally!

--
Jhoom.com

Baker’s picture

This is a bone of contention with regards to Drupal flexibility and user friendliness with me. This page reads like hieroglyphics to anyone who's not a coder. There should be a module that simply allows us to drag and drop reorder and rename the links, assign icons, etc. at the bottom of any node, specific to the theme that I'm in/setting up at the moment.

I know it would be one incredibly challenging module to write, but I know coders that eat that stuff like a good chess game, so I'm throwing down the challenge. Any takers?

drinkdecaf’s picture

Nice snippet of code - very useful GuruJi! I've modified it slightly to be a little easier to customize...

This should work in Drupal 5.x - simply rename the function from "yourtheme_links" and paste in your template.php file.

add any keys for links you want to appear first in a list. For myself, I used

"$searchkeys = array('comment_add', 'comment_forbidden');"


<?php

// a function to reorder links before passing them to default link theme function
function yourtheme_links($links, $attributes = array('class' => 'links')) {

  
  //simply add any link keys here that you wish to appear first in a list of links
  $searchkeys = array('key_one', 'key_two');
  
  $searchkeys = array_reverse($searchkeys);
  foreach ($searchkeys as $key) {
      if( isset( $links[$key] ) ) {
            $temparray = array();
            $temparray[$key] = $links[$key];
            unset( $links[$key] );
            $links = array_merge($temparray, $links);
            unset( $temparray );
      }
  }
  
  return theme_links($links, $attributes = array('class' => 'links'));
} 

?>
seaneffel’s picture

Am I right, did I read that this is now handled on the theme layer by Drupal 6?

hargobind’s picture

Here's a slightly better and more flexible version of the above code:

Reorder Function:

/**
 * Reorder links before passing them to default link theme function.
 * Original idea taken from http://drupal.org/node/44435
 *
 * @param $links
 *   A keyed array of links to be themed.
 * @param $first_keys
 *   An array of keys which should be sorted to the beginning of the $links array.
 * @param $last_keys
 *   An array of keys which should be sorted to the end of the $links array.
 * @return
 *   A string containing an unordered list of links.
 *
 * Usage Note: The order in which you specify $first/last_keys is the order in which they will be sorted.
 */
function reorder_links($links, $first_keys = array(), $last_keys = array()) {
	$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);
	
	return $links;
}

Usage:

/**
 * Override theme_links() so we can reorder the $links array.
 */
function phptemplate_links($links, $attributes = array('class' => 'links')) {
	// Reorder the links however you need them.
	$links = reorder_links($links, array('first-link', 'second-link'), array('last-link'));
	
	// Use the built-in theme_links() function to format the $links array.
	return theme_links($links, $attributes);
}
mpaler’s picture

Great snippett. However, you need a conditional statement in the phptemplate_links function as follows:

if($links){
     $links = reorder_links($links, array('edit_node', 'comment_add'), array('quote'));
}

Otherwise, if the node/comment doesn't have links the reorder_links function will throw an error.

Mike

Veneer | Crack-proof Creative
http://www.veneerstudio.com

Jerimee’s picture

This worked. I just pasted the function into my template.php and then added this to my theme_links function (I'm using the permalink and sharethis modules):

if($links){
     $links = reorder_links($links, array('node_read_more', 'comment_add', 'permalink'), array('sharethis_link'));
}
puppetmast0r’s picture

It took me a while to understand where to put what (especially where to insert my keys) but in the end it worked. :)

To other visitors as thick as myself: put the keys (which in this case is the same as the css class, so easy to find) of the list items where 'first-link', 'second-link', 'last-link' are in the example.

Thanks a lot to all contributors to solve this problem, and of course especially to Linxor.

porter235’s picture

This has worked nicely for me. (I added it to template.php, but would have liked to have it live somewhere else, to help prevent accidental hammering)

miki_nl’s picture

The same reordering can be done also in hook_link_alter(). It is easier to reorder in hook_link_alter() if you want the same order of links in multiple themes and/or if you do not want to implement new theme (or change an existing one).

summit’s picture

Hi,

Could with this solution also the $links stuff be placed on more than one line:
So you get:

"read more"
 "email this page" 
"unsubscribe"
etc..

Thanks a lot in advance for your reply!

greetings,
Martijn

theohawse’s picture

You could just use css to put these on multiple lines. Something like: li.links {float:left} for all of them or clear:right to break it spmewhere specific.

nick.dap’s picture

Here is how:

/*
 * Reorder node links to show the edit link first
 */
function hook_link_alter(&$links, &$node) {

  if( isset($links['node_edit_link']) ) {
    
    $node_edit_link = $links['node_edit_link'];
    unset($links['node_edit_link']);
    $links = array_merge(array('node_edit_link' => $node_edit_link), $links);
  }
}
ressa’s picture

This being Drupal, there is now a module for that 8o)
http://drupal.org/project/linkweights

Joe Vallender’s picture

you could tweak this or the reorder_links function - this is probably the best place though

function phptemplate_links($variables) {
  if($variables['links']) {
    $links = reorder_links($variables['links'], array('comment-reply', 'quote', 'flag-thanks', 'comment-edit', 'comment-delete', 'flag-report'), array('last-link'));
    $variables['links'] = $links;
  }  
  return theme_links($variables);
}