It has been a constant source of irritation for many people that CCK nodes do not function properly with Teasers. The main reason for this limitation is the fact that CCK doesn't know which field in a custom node should be considered the $body field.

As I understand it, this limitation "may" be solved in 5.0 eventually, when the $body field type is added to CCK. But will this solution be offered for 4.7? A few people have offered solutions by using the contemplate module to create a teaser on the fly for each node, but this has a couple of limitations. First, the teaser must be processed every time the node is served up to the user. Second, because the teaser is not stored, it can't be used in Views.

After much trial and tribulation, I've finally managed to eke out a solution that allows Teasers to work as they should in CCK nodes:

1) First, you must install the computed_field module for CCK. We will use this module to create a computed field called "cckteaser" that will store the teaser text in the CCK table and make it available to Views. (see the computed field documentation for more information)

In the computed field definition, add the following code: (this assumes a computed field name of "cckteaser" and a custom CCK field of "body" to store your main body text)

$node_field[0]['value'] = node_teaser($node->field_body[0]['value']);

This uses Drupal core's node_teaser function to do the stripping for us. Therefore, it honors the Teaser length stored in the Drupal defaults and also honors the !<--break--> tag.

Add this to the Display Format field:

$display = $node_field_item['value'];

Choose to store the value and use a field type of varchar. Make sure to specify a length long enough to hold the trimmed text. (200 to 800 characters, depending on your defined teaser length)

Now, every time your custom CCK node is saved or revised, the teaser will be calculated and stored in the computed field exactly the same way standard nodes work.

2) Make sure you have the contemplate module installed. This will allow you to build a special template for teasers and main body nodes.

In the Teaser template, place your cckteaser field. In the Body Template, place your body field. Voila! You now have a custom CCK node that will display truncated Teasers just like standard nodes.

3) There remains one small glitch, however. CCK assumes that true teasers don't work, so it sets the $readmore value to FALSE. This is the value that tells Drupal to display a "Read More" link below the content. We can recreate the read more link however, by adding the following code to the end of your Contemplate teaser template:

 <?php
if (strlen($field_cckteaser[0]['value']) < strlen($field_body[0]['value']))
{ ?> 
<span class="readmore"><a href="node/<?php print $nid ?>" title="Read more on this article">... (read more)</span></p>
<?php } ?> 

This custom code will first test to see if the cckteaser field is shorter than the body field. If it is, then "read more" is appended directly to the end of the cckteaser content and points to the url of the full page. This is a bit different from the location of "read more" on standard nodes. (which are below the content, next to the "add comment" link) But I like this location for "read more" better, because it catches the reader's eye.

That's it! I sincerely hope that Teaser functionality becomes standard in CCK soon, but in the meantime this approach works.

Comments

zoon_unit’s picture

In my previous example, I used simple coding to construct the url of the node, this part specifically:

<span class="readmore"><a href="node/<?php print $nid ?>" title="Read more on this article">... (read more)</span></p>

This works fine unless one wants to use pathauto. What is really needed here is the value of the title url, which can be altered by pathauto. (I'm assuming this, but not sure if pathauto works with CCK nodes)

What is the variable that holds the node title url?

chrisfromredfin’s picture

The l() function will generate the correct link with pathauto (or without).

<span class="readmore"><?php print l('... (read more)', 'node/'.$nid, array('title' => 'Read more on this article')); ?></span>

.cw.

.cw.

zoon_unit’s picture

That works like a charm. :-)

venkat-rk’s picture

sounds great.

----
Previously user Ramdak.

zoon_unit’s picture

Per webchick's suggestion, I have added an edited version of this post with cwell's input to the Handbook:

http://drupal.org/node/106951

Please check it out and let me know if anything needs correcting.

Thanks!