Quick and Clean CCK teasers Via PHPtemplate

If you are like me, you've been pulling your hair out trying to make teasers work in CCK. Well, as it so happens, I figured out a crazy simple phptemplate method of making CCK body fields act like any other node's body. Observe:

Template.php

<?phpfunction _phptemplate_variables($hook, $vars) {global $user;    switch ($hook) {        case 'node':            if ($vars['field_body'][0]['value']) {            /* Believe it or not, all you have to do is pass the field through             the existing node.module function node_teaser()! */                $vars['cck_teaser'] = node_teaser($vars['field_body'][0]['value'], $format = NULL);            }            break;    }    return $vars;}?>

Drop this in the appropriate node.tpl.php file:

<div class="content"> <?php //for teasersif ($page == 0) {    print $cck_teaser;} //for fullpageselse {    print $node->field_body[0]['value'];?>} ?></div>

Comments

My content type story have

My content type story have just 'body' field. And there are no tag. So I got empty teaser. What I need to do in this case?

error

There is a mistake in your node-template code:

<?php

//for teasers
if ($page == 0) {
   print
$cck_teaser;
}
//for fullpages
else {
   print
$node->field_body[0]['value'];<em><strong>
?>


}
?>

..you ended php before the curly bracket.

JR

non-programmer question

Nick - I'm not a programmer, but I'd really like to use this hack and I have a couple of questions. - what exactly does the code that gets inserted into template.php mean, and can it be dropped into template.php without any modification? - Where does one add in customization? (i.e. html markup and variables?) An example would be really helpful Thanks!!

Read more via Excerpt Module

Very nice - this is also exactly what I was looking for :) I find that I can get the "read more" link via the "excerpt" module - so I strip out the template "read more" snippet and get a standardized "read more" link at the bottom. Alex

you made my day!

For those of us who were already theming teasers with: <?php print node_teaser($node->field_description[0]['view']); ?> ...this addition to template.php seamlessly restores the 'read more' link in existing themes. Thanks for the sanity.

Apply filters

Thanks for your tip, this as helped me a lot! There is some things that can be inproved:

The teaser should take care of filters that may be enabled for the field used for teaser. In my case, inline images where not rendered.

It's up to you guys, but usualy the "read more" link is only diplayed if teaser if different of the node body..

here are the snippet I use (my CCK node name is "content-album" and my body field is "field_corps"):

<?phpfunction _phptemplate_variables($hook, $vars) {        switch ($hook) {        case 'node':        // Create CCK teasers hack        if ($vars['page'] == 0) {            switch ($vars['node']->type) {            case 'content-album':                              /* Believe it or not, all you have to do is pass the field through                the existing node.module function node_teaser()! */                $vars['cck_teaser'] = node_teaser($vars['field_corps'][0]['value']);                if ($vars['cck_teaser'] != $vars['field_corps'][0]['value']){                    $vars['links'] .= ($vars['links'] ? ' | ' : '') . l(t('Read the rest of this posting.'), 'node/'.$vars['node']->nid);                }                                break;            }        }        break;    }    return $vars;}?> and in my template: <?php//for teasers        if ($page == 0) {          print check_markup($cck_teaser, $field_corps[0]['format']);        }?>

This might be simpler, no

This might be simpler, no need to mess with node.tpl.php: <?phpfunction _phptemplate_variables($hook, $vars) {    switch ($hook) {    case 'node':        // Create CCK teasers hack        if ($vars['page'] == 0) {            switch ($vars['node']->type) {            case 'content-case_study':            case 'content-white_paper':                                /* Believe it or not, all you have to do is pass the field through                the existing node.module function node_teaser()! */                $vars['content'] = node_teaser($vars['field_description'][0]['value']);                $vars['links'] .= ($vars['links'] ? ' | ' : '') . l('Read more...', 'node/'.$vars['node']->nid);                break;            }        }        break;    }    return $vars;}?>

So where do I put this code?

Is this for the modules/cck/theme/template.php file?

No, it will go in

No, it will go in themes/[the name of your theme
]/template.php file

Nice and clean! It could

Nice and clean! It could even cover all cck node types with if (substr($vars['node']->type, 0, 8) == 'content-') instead of cases.

That is in fact simpler. I

That is in fact simpler. I like it, and I will start using it! Thanks!

N00b question

sorry about this i am no coder at all: is the 'field_body' you guys are talking about just an example variable that i have to replace with my own variable name, and enter another row for each field type i have on my own CCK content type? am i on the right path or totally off? thanks for helping out

I think field_body is the

I think field_body is the standard variable in CCK for the body. I might be wrong though. I tell you what, slap this PHP snippet into your node.tpl.php file and find out which field_(what you named the fields) their are:

<pre> 

<?php print_r(get_object_vars($node));?>

</pre>

 Sorry for the vague response... running on empty right now...

Nice. I had been fighting

Nice. I had been fighting with a similar solution, but without template.php, and using an additional "field_teaser" which I displayed alternatively. It kinda worked... but I was also frustrated with the disappearance of "read more". I noticed that if you test for $page==0 you see only the teaser in the preview while if you test for $teaser you see only the full node in the preview. Well, you can't have both but you have a choise... I also substituted ['value'] with ['view'] in the node's tpl.php, because there was such advice in the readme and it happened to work too. So, after applying your template.php hack I did the following: if ($teaser) {  print $cck_teaser;  $readmore_link = '<a href="' . $node_url . '" title="' . $title.'">' . t('read more') . '</a>' . ' | ';}else {  print $node->field_body[0]['view'];  $readmore_link = "";}// more stuff here...<?php if ($links) { ?><div class="links">&raquo; <?php print $readmore_link . $links ?></div><?php }; ?>

Some problem

Hi, Wonderful stuff, but it still leads to some issues, as for example if we use other input contents such as bbcode, the bbcode tags are kept...

Hmmm… I don’t use

Hmmm... I don't use bbcode... I'll take a look tomorrow (mostly because this is curious...).

Wow, thanks for that post.

Wow, thanks for that post. I'd been working on this all week. I started trying to patch CCK myself, then moved on to using Contemplate to take the 'body' field and manually tear it down to just one paragraph for teasers. Your solution is a little more elegant. I have one suggestion: it should be a way to display a "Read More..." link after the teaser. Put this in your node.tpl.php:   <?php if ($page == 0): ?>    <p><a href="<?php print $node_url ?>" title="<?php print $title ?>">Read More...</a></p>  <?php endif; ?>I'm sure that there's a better way, but that seems to work for now.

That’s funny! I’ve been

That's funny! I've been using the same solution myself -- for the code I blogged doesn't take care of the "read more..." problem. However, that code you provide does. Its crude, yet crude by practicallity (what alternative is their?). This is like a bug report sent first class mail.

After a short hiatus, I

After a short hiatus, I resumed working on my project last night. Here's the code I'm using in my node.tpl.php:<div class="content"><?php  if ($page == 0) {    print $cck_teaser;  }  else {    print strip_tags($node->field_body[0]['view'], '<i>, <b>, <p>, <em>, <a>');}  ?>    <?php if ($page == 0): ?>      <p><a href="<?php print $node_url ?>" title="<?php print $title ?>">Read More...</a></p>    <?php endif; ?></div>It's still got the same ghetto fabulous "Read More..." code (if for no other reason than it doesn't support multiple languages). But now it outputs the teaser with Drupal's auto line-breaks intact as well as selected HTML tags. Text specific tags like italics and links are preserved, but tags that may disrupt the main page's CSS or layout (like DIVs, images, or Javascript) are stripped out. Again, it may not be elegant, but it's the best I can do with my limited knowledge of PHP. (BTW, CCK was finally updated the other day, with no sign of a patch for teasers being included. Arg!)