Theming the Drupal 7 Read More links

16/04/2011 -- dreamleaf

When I'm theming Drupal I like to have lots of variables available to use. The finer grained the element the better in my opinion. There are several annoyances with how Drupal outputs some sections, such as the $content variable - which I would prefer were broken down to a specific field level from the start. Another bug bear of mine is the read more link that you find in node teasers, you click it and it leads to the full node view. Drupal however, spits it out along with the node links (login or register to post comments/post a comment). Grrr.

This solution could be used if you are aiming to strip the logic from your tpl files, placing the grunt work in template.php instead. If you want a D7 solution that is done JUST in the node.tpl.php file, then check the "other solutions" down at the bottom of this post. If you're comfortable editing tpl's and messing around in template.php, then here's a quick and dirty way to provide the read more link as a new variable. If you don't really understand what I'm talking about... best to leave it alone!

Step 1: SET UP A PREPROCESS FUNCTION In template.php you need to add a node level preprocess function... Remember to replace YourThemeName with ... your theme name :-)

<?php // Preprocess variables for node.tpl.php. 
function YourThemeName_preprocess_node(&$variables) { } 
?>

Step 2: REMOVING READ MORE:

<?php // Preprocess variables for node.tpl.php. 
function YourThemeName_preprocess_node(&$variables) { 
// Let's get that read more link out of the generated links variable!
unset($variables['content']['links']['node']['#links']['node-readmore']); } ?>

Step 3: CREATE A NEW READ MORE VARIABLE

Note: I've used the $node_url variable here as the read more link, this pulls the relevant URL from the node. You'll notice I called it !title though for outputting, this is so it can be easier to read (personally I hate underscores when you can use 1 word instead!)

The new variable will be called $newreadmore to avoid any confusion.

<?php // Preprocess variables for node.tpl.php.
function YourThemeName_preprocess_node(&$variables) {

// Let's get that read more link out of the generated links variable!
  
unset($variables['content']['links']['node']['#links']['node-readmore']);

// Now let's put it back as it's own variable! So it's actually versatile!
    
$variables['newreadmore'] = t('<span class="newreadmore"> <a href="!title">Read More</a> </span>',
      array(
        
'!title' => $variables['node_url'],
      )
);
}
?>

That ends the template.php work. Now you just need to open up node.tpl.php and place the newreadmore variable where you want it to go.
<?php print $newreadmore?>

One additional step you will want within your node.tpl.php is to tell the variable to ONLY display if it's the teaser (as opposed to the full node view).

<?php if ($teaser == true): ?>
<?php print $newreadmore?>
<?php endif; ?>

Other Solutions

Just using node.tpl.php... To remove the read more link: <?php hide($content['links']['#links']['node-readmore']); ?>
To show it again somewhere else:

<?php
if($teaser){
      print 
l(t('Read more'), '../' $node_url, array('attributes' => array('class' => t('newreadmore'))));
  }
?>

This method is tecnically easier, but puts the logic into the tpl file - which I don't really like doing.
For Drupal 5&6 the masterful @toddross released a module which added the read more link to the end of the article. There isn't currently a Drupal 7 version of the module, but it's being worked on HERE

Comments

Submitted by Web Design Adelaide (not verified) on

Thank you for writing this resource on your website.

Submitted by jameskent582 (not verified) on

I can see that you are an expert at your field! I am launching a website soon, and your information will be very useful for me.. Thanks for all your help and wishing you all the success.

Submitted by Martin (not verified) on

I think your code has changed slightly!
It's showing:
(&amp;$variables)
which looks incorrect...
Surely it should be
(&$variables)
?

Submitted by dreamleaf on

Thanks for pointing that out, not sure why it changed - very weird and now corrected!

Submitted by cara1940 (not verified) on

in modal box, if I use that snippet in my node--.tpl. You would totally save my life if you gave me a pointer. For example:

a href="?q=node/1?format=simple" rel="lightframe">click here to see node content /a

(removed the opening and closing tags because of your HTML filter)

Submitted by dreamleaf on

For example, if you use the colorbox module @ http://drupal.org/project/colorbox then you should be able to just add a class to the node.tpl code above.

So it would look something like...

array('class' => t('newreadmore colorbox-inline'))));

Where colorbox-inline is the class required by the colorbox module...

The instructions above helped me change the Read More links on a website I'm designing. Thank you for writing the post.