One of the most common questions in Drupal is "How do I get rid of / change / etc etc" the 'read more' bit.

Sometimes it's quite problematic; it's stuck down there with the 'add comment', 'add to my wishlist', etc etc links. And it can be easy to lose, because it's not really in the flow with what is actually being read. I know that I, myself, have missed its existence on more than one occasion, when it's not clear if there is actually meant to be more text or not.

There's a couple of typical ways to do this.

One looks like this:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas consectetuer. Fusce eros. Aliquam consequat urna eget risus. Donec a orci sit amet risus imperdiet fringilla. Sed non leo. Proin a massa nec nisl eleifend auctor. Nulla a mi. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec sodales commodo libero. Proin semper purus et sapien.

Nunc molestie ligula sit amet quam. Integer nunc. Quisque aliquam purus ut tellus. Donec at diam et arcu euismod mattis. Integer massa. Integer magna. Praesent ac velit. Nulla venenatis venenatis purus. Vivamus et urna et mauris bibendum tincidunt. Pellentesque cursus eleifend libero. Vivamus ligula pede, bibendum eu, ornare in, adipiscing nec, felis. Quisque mi justo, placerat a, venenatis eget, fringilla eu, tortor. Duis vel libero id dolor rutrum dignissim. Duis id tellus. Praesent metus nisi, blandit non, ornare sit amet, lobortis et, augue. Phasellus quis eros sit amet turpis vulputate mattis. Duis pede libero, condimentum vel, congue nec, dictum vel, nulla. Mauris eget enim. Aliquam pharetra enim vitae neque. Nulla tincidunt auctor justo.

read more

And method #2 looks like this:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas consectetuer. Fusce eros. Aliquam consequat urna eget risus. Donec a orci sit amet risus imperdiet fringilla. Sed non leo. Proin a massa nec nisl eleifend auctor. Nulla a mi. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec sodales commodo libero. Proin semper purus et sapien. read more »

To do both of these, you need similar snippets. This is a custom module, which I have oh-so-creatively named 'custom'. Every site should have a custom module, because hook_nodeapi and hook_form_alter can do a LOT. Though what this module is named is completely up to you. I often name it after the site; other times I just name it custom.

Anyway, method #1:

<?php
function custom_nodeapi(&$node, $op, $teaser, $page) {
  if (
$op == 'view' && $teaser && $node->readmore) {
   
$node->readmore = false;
   
$node->teaser .= "<div class='read-more'>" . l(t('read more'), "node/$node->nid", NULL, NULL, NULL, TRUE) . "</div>";
  }
}
?>

Method #2:

<?php
function custom_nodeapi(&$node, $op, $teaser, $page) {
  if (
$op == 'view' && $teaser && $node->readmore) {
   
$node->readmore = false;
   
$read_more = "<span class='read-more'>" . l(t('read more &raquo;'), "node/$node->nid", NULL, NULL, NULL, TRUE, TRUE) . "</span>";
   
$node->teaser = substr_replace($node->teaser, $read_more, strrpos($node->teaser, '</p>'), 0);
  }
}

Note that I'm using a lot of arguments to l() -- I'm telling it to provide an 'absolute' path, because these teasers often go out to RSS, and providing an absolute path is much, much safer.
?>

Neat!

I've been following the progress of JQuery in 5.0 and have been daydreaming about an AJAX/PHPTemplate theme that displays headlines/teasers/node body in the form of popups. I find myself wondering, lately, if the days of all-php themes haven't become numbered.

Thanks for the ah-ha moment!

I never really thought of setting up a custom module to tap into hook_form_alter and hook_nodeapi. What a great idea. Thanks!

How to use the snippet?

It's a good idea to place "read more" in a better place. But I am not sure how I could use the snippet. Shall I copy & paste the snippet in a text editor and save it into xxx.module and then upload it to my /module directory and enable it? Or just put it somewhere in the page.tpl.php file? Thanks a lot!

custom.module (??)

Hi there,

I have the same question as Walker just above... how do I actually use this code-snipplet. I first tried to create a file called readmore.module and pasted the snipplet #2 into it using a normal text editor (and of course then enabling the module in my drupal installation) - but apparently this is not enough to enable it. So once again: do I have to actually create such a .module file? I assume I'd have to alter node.tpl.php too to make it actually working, but how? What do I have to add?
Or is the solution much simpler?

Sorry, I'm obviously not the very experienced php-programmer ;) But thanks for a little hint...

hQuadrat

Using this snippet

To use this snippet:

cut & paste the entirety of the code into a file named 'custom.module' and drop this into your modules directory. Ideally you should also make a directory. (If using Drupal 5 you'll need to make a custom.info as well).

Then go to admin/modules and enable the 'custom' module.

Naming convention

If you wish to name your module something other than 'custom' module, you need to do a little editing of the code.

Note that all the function names begin with the word 'custom'. That's the name of the module, and it's how Drupal knows to call your functions. If you want to name the module 'readmore', for example, search and replace 'custom_' into 'readmore_'.

Code Snipplet #2 did not work in PHP4 - strrpos()

Hi again,

Thanks for the hint Merlin, but I then realised that myself with trying a little more around ;) But it still might be a useful information for other users that might first encounter the same little problem if they just rename the module without adjusting the funcion name. :)

But then I encountered the next Problem: the result of the code-snipplet #2 looked more like If I had used code snipplet #1. This, as a good friend gave hints to me, happened because the function strrpos() searches in PHP4 just for the first character supported "<" and not for the whole string "</p>" (as this obviously works in PHP5). So it just looked where the last "<" sign appears and pastes our link there - the link therefore lands in the next paragraph again as if we hadn't changed snipplet #1.
So we tried to find another solution and my friend came to the following: (I actually omit the ?> Tag at the end of the code as to the drupal coding standards: http://drupal.org/node/545)

My "readmore.module":

<?php
/* $Id$ */

function readmore_nodeapi(&$node, $op, $teaser, $page)
{
  if (
$op == 'view' && $teaser && $node->readmore)
  {
   
$node->readmore = false;
   
$read_more = "&nbsp;<span class=\"read-more\">" . l(t('[...]&nbsp;Weiterlesen'), "node/$node->nid", NULL, NULL, NULL, TRUE, TRUE) . "</span>";
   

   
$rev_teaser = strrev ($node->teaser);
   
$rev_ptag strrev ('</p>');
   
$position = strlen($rev_teaser) - strpos($rev_teaser, $rev_ptag) -  strlen($rev_ptag);

   
$node->teaser = substr_replace($node->teaser, $read_more, $position, 0);
   
  }
 
}
?>

This should now work under PHP4 and PHP5, though the code is not as short and compact as the above ;) Maybe one of you finds a better code that works under PHP4 too - nevertheless this should work. A running example under PHP4 using "my" code might be found at my Homepage: hQuadr.at. :)

Sorry for this long post and my bad English, but I thought it might be helpful...
hQuadrat

Drop-in module available for download

I've posted my version of this module on my website, for those who aren't interested in making their own module.

It also provides options to enable/disable the tweak, and control placement of the read more link as shown in method 1 and 2 of the article.

You can download it here:
http://exodusdev.com/drupal/4.7/modules/ed_readmore.module

Hope this helps.

no need for custom_nodeapi()

I think a custom_nodeapi() is to much just for this functionality.
I can do this with my node.tpl.php, too:

replace

<?php
print $content;
?>

with
<?php
if ($page == 0 && $node->readmore) {
  print
$content. "<div class='read-more'>" . l(t('read more'), "node/$node->nid", array('title' => t('Read the rest of this posting.')), NULL, NULL, TRUE) . '</div>';
} else {
  print
$content;
}
?>

read more about the node.tpl.php and phptemplate: http://drupal.org/node/11816

what speaks against this?

btw. thanks for this idea in general, it's a real usability enhancement

There are 2 reasons to do

There are 2 reasons to do this in nodeapi and not in node.tpl.php:

1) if you have several node.tpl.phps this'll catch all of them
2) by unsetting the readmore flag here, you actually get RID of the readmore link in the links section; to do that in node.tpl.php is much more complex.

Sweet!

As always, your insights and solutions are much appreciated - this is by far the best solution I've found.

Drupal 5.0

I had to alter $node->content[body]['#value'] instead of $node->teaser, to get this to work in Drupal 5.0.

Drupal 5.0

I'm working with 5.0 beta 2. Could you show your resulting code after you "alter $node->content[body]['#value'] instead of $node->teaser"? I'm not a PHP guy & I don't know exactly what changes to make just from that description.
Thx!

I think he means simply

I think he means simply replace "$node->teaser" with "$node->content[body]['#value']"

Aha! Yes! *tears of joy*

OK, replacing each instance of "$node->teaser" with "$node->content[body]['#value']" in example #2 succeeded in moving my "read more" link, at last, to a sensible spot.

Good grief why is this not a standard feature? The ridiculousness of this one little thing was fast becoming a Drupal dealbreaker for me.

Thanks much!

Thank you!

Not only is this snippet just what I needed, I had an ah-ha moment just like Michael above. A custom module with little site-specific fixes is such a great idea.

Just to save future Googlers some time, here are the two files you need for Drupal 5.0. Put them in sites/all/modules/custom, then go enable your new custom module.

custom.info

; $Id$
name = Custom
description = Custom functions for this site.

custom.module

<?php
/* $Id$ */
function custom_nodeapi(&$node, $op, $teaser, $page) {
  if (
$op == 'view' && $teaser && $node->readmore) {
   
$node->readmore = false;
   
$read_more = " <span class='read-more'>" . l(t('Read more &raquo;'), "node/$node->nid", NULL, NULL, NULL, TRUE, TRUE) . "</span>";
   
$node->content[body]['#value'] = substr_replace($node->content[body]['#value'], $read_more, strrpos($node->content[body]['#value'], '</p>'), 0);
  }
}
?>

Great ideas, but how does

Great ideas, but how does one then fix this in the post? Is there any sort of HTML I should put in the post itself to make the "read more" link appear?

the right filter

Just in case someone else runs into this issue...if the input type for your entry/node is something that strips HTML tags, specifically the </p> the "read more" link will be inserted before the end of the teaser. So, make sure you are using an input format that allows p tags (or look for and use for another string at the end of the teaser, and replace the </p> with that in the snippet).

Can this method be used to

Can this method be used to place other items from $links inline as well? For example:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas consectetuer. Fusce eros. Aliquam consequat urna eget risus. Donec a orci sit amet risus imperdiet fringilla. Sed non leo. Proin semper purus et sapien. Read More | 3 Comments...

It can, roughly; instead of

It can, roughly; instead of using $node->readmore you'd probably need to play with $node->links. It could be kind of tricky because your node.tpl.php expects to be the one presenting the links. It would take some work but the basic technique should do the trick.

Not removed from links

I just uploaded the module and info file posted by Katherine, and while 'read more' is added to the end of the teaser, it is not removed from the links. I then tried the second of the original snippet above, and it simply didn't work at all. I am on dpl 5.1. Any suggestions?

Thanks,
Maria

thanks for this!

I just installed this on my site and it works a treat- will make things much easier for my less technically inclined readers. Just a note, I initially downloaded this file and it prepended my admin page with a large portion of this website! Careful with that....

missing "read more" link

this is all well and good, but I can't seem to get the "read more" link to display at all! I've tried adding the custom module but nothing. If I view source, the only thing that shows below each post is the tag link.

If it helps, I am using a slightly customized Marvin theme, with comments disabled. I've looked in every setting I can possibly think of but I can't find any way to enable/disable the link. The only way to read the rest of the article is to click the title..

has anyone else come across this? am I just being blind and not seeing the solution?

thanks

I need the read more link to go away.

We are using full nodes in the view and the read more link still shows up. I think I need to adjust this code, found in my node.tpl.php file:

<?php
print $content;
?>

<?php
if (!$page):
?>

<?php
print $node_url
?>
">More...
<?php
endif;
?>

How can I get it to tell if the full node is displayed already??? I only want the "read more" link to show up if it's a teaser.

ok same problem of Kris

ok same problem of Kris Noble i have configuring Read More

here's what i did :

1- downloaded the module from drupal.org
2- uploaded the module folder into drupal via FTP
3- Enabled The module from Administer >> Modules

but still am not getting any link in the stories am adding

something else am wondering. isn't it supposed to have 2 boxes in Story section since Read More has to hide something !

Can't get this to work

with module Node Teaser installed, or when I use <!--break--> in body. It works great when I let Drupal control the teaser by default.

testing

testing

Still shows up when displaying full nodes in a view

I successfully installed Katherine's snippets as a 'Custom' module for Drupal 5x, and this worked a treat in terms of wrapping 'Read more' onto the end of my node text.

However it didn't remove 'Read more' links from nodes in views that are already displayed in full.

Anyone have a solution for this? Its annoying for users to read an item and click 'Read more' just to be presented with the same content...

Fix to keep 'Read more' hidden in full view

For me, the module worked to remove the 'read more' link from the teaser and the full view, but failed to remove it when people were leaving a comment (after clicking on 'add a comment').

I added an elseif statement to the end of the code that was already there. I'm not very familiar with php, but I believe it just removes the 'read more' link when it's in full view as well as in teaser view.

<?php
/* $Id$ */
function readmore_nodeapi(&$node, $op, $teaser, $page) {
  if (
$op == 'view' && $teaser && $node->readmore) {
   
$node->readmore = false;
   
$read_more = " <span class='read-more'>" . l(t('continue reading...'), "node/$node->nid", NULL, NULL, NULL, TRUE, TRUE) . "</span>";
   
$node->content[body]['#value'] = substr_replace($node->content[body]['#value'], $read_more, strrpos($node->content[body]['#value'], '</p>'), 0);
  }
 
 
/* Added code snippet */
 
elseif ($op == 'view' && $node->readmore) {
   
$node->readmore = false;
  }
 
/* end code snippet */
}
?>

The Fix Works

Ishmael you are a star - this fix works for me!

Incompatible with Node Teaser?

I've noticed that this is incompatible with Node Teaser - perhaps this one's hook is run first, and then Node Teaser's is run, replacing the teaser entirely and overwriting the link?

Module also incompatible with Excerpt-Module

The readmore-Module also seems incompatible with the excerpt module... The readmore-links disappear on most entries but not on all of them, so there are some blogposts left WITH the link. I have no Idea how this came. But even worse: uninstalling the excerpt-module did not solve this problem, but I am sure that it caused it. If I activate the readmore-tweak-module, the links still disappear... Re-editing the posts did not help either.

Maybe anyone got an idea?? I want to have my inline-readmore-links back.... :(

The same problem I have.

The same problem I have. Everything worked fine until I installed Node Teaser. Deleting the module and even dropping the Node Teaser table from the database didn't help. What am I supposed to get that read more link back inline?

Drupal 6?

I just tried this on my Drupal site, and it just gave me an error, as if it won't work on Drupal 6.2.

Has anything changed in

Has anything changed in Drupal 6 related to this?

Working with Drupal 5 and Excerpt

I got it working fine in Drupal 5.7 with excerpt module (latest 5.x release) and the latest read more tweak module. In node.tpl.php I used an "if (($page == 1)" (not the front page) to display the default read more, comment, etc. links only on full pages, and an "if ($page == 0)" to display a separator between teasers on the front page. It looks good now - a nice "read more >>" link following each teaser. Thanks so much for this module!

Post new comment

The content of this field is kept private and will not be shown publicly.