Last updated December 15, 2009. Created on December 14, 2009.
Edited by kdebaas. Log in to edit this page.

Description

The following snippet strips any tags from the body field of a node that is displayed as a teaser. That is to say, it strips the tags from the original teaser created from the body field, taking care not to strip the tags from extra fields added to the teaser by modules such as CCK.

Step 1 of 1

In your template.php, add the following to the node preprocess function:

<?php
function THEME_preprocess_node(&$vars, $hook) {
 
// Strip tags from teaser
 
if ($vars['teaser']) {
   
// $coreteaser is the teaser without extra cck fields
   
$coreteaser = $vars['node']->content['body']['#value'];
   
// Make sure there is content to strip tags from
   
if ($coreteaser) {
     
$teaser = $vars['content'];
     
// Calculate position of $coreteaser in $teaser
     
$start = strpos($teaser, $coreteaser);
     
// Calculate length of core teaser with tags
     
$length = strlen($coreteaser);
     
// Strip tags from $coreteaser
     
$replacement = strip_tags($coreteaser);
     
// Replace corresponding part of $teaser with stripped $coreteaser
     
$vars['content'] = substr_replace($teaser, $replacement, $start, $length);
    }
  }
}
?>

Notes

  • Be sure to replace THEME above with the name of your theme.
  • the strip_tags() function can be expanded to allow certain tags

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

tsssystems’s picture

Props to sheena_d for pointing me to this page and http://php.net/manual/en/function.strip-tags.php. By combining Steve's strip_only function from the php.net page with the code on this page, you can selectively remove html tags from teasers. I needed it to remove img tags. I have a long narrow graphic along the right border of a newsletter. It's much longer that the teaser copy and ended up bordering other teasers besides the one it was meant for. Here's the code that worked like a charm:

<?php

/* Strip only selcted tags in THEME_preprocess_node function below */
function strip_only($str, $tags) {
    if(!
is_array($tags)) {
       
$tags = (strpos($str, '>') !== false ? explode('>', str_replace('<', '', $tags)) : array($tags));
        if(
end($tags) == '') array_pop($tags);
    }
    foreach(
$tags as $tag) $str = preg_replace('#</?'.$tag.'[^>]*>#is', '', $str);
    return
$str;
}

/* Strip only selected tags from teasers - in this case, just img tags */
function THEME_preprocess_node(&$vars, $hook) {
 
// Strip tags from teaser
 
if ($vars['teaser']) {
   
// $coreteaser is the teaser without extra cck fields
   
$coreteaser = $vars['node']->content['body']['#value'];
   
// Make sure there is content to strip tags from
   
if ($coreteaser) {
     
$teaser = $vars['content'];     
     
// Calculate position of $coreteaser in $teaser
     
$start = strpos($teaser, $coreteaser);
     
// Calculate length of core teaser with tags
     
$length = strlen($coreteaser);
     
// Strip selected tags only from $coreteaser
     
$replacement = strip_only($coreteaser, '<img>');
     
// Replace corresponding part of $teaser with stripped $coreteaser
     
$vars['content'] = substr_replace($teaser, $replacement, $start, $length);
    }
  }
}

?>
Observer123’s picture

Please give me a sample how to use this function to strip only bold and italic tags tags?

Skelly1983’s picture

to strip just bold and italic tags just change the $replacement string so it is the same as this:

// Strip selected tags only from $coreteaser
      $replacement = strip_only($coreteaser, '<strong> <em> <b> <i>');

the b and i tag have bin included just incase users still use the older method for bold and italic.

youngros’s picture

I tried this with the Adaptive theme, but seems I am missing something as I can't seem to get it to work.
I am using inline images as my content is a node and not a field in the view and I've not sussed out CKEditor yet.

Any ideas where I might be going wrong please.

JimmyMoonJam’s picture

I don't understand why it doesn't work for me either. I don't use any editors. Tried it with the Garland theme also and with normal default Page content type.

Finally removed the img tags with this code my friend told me to try:

<?php
 
print preg_replace('#<img[^>]+>#i', '', $node->content['body']['#value']);
?>

Placed it into the node.tpl.php file.

julien.reulos’s picture

<?php
/* Strip only selcted tags in THEME_preprocess_node function below */
function strip_only($str, $tags) {
    if(!
is_array($tags)) {
       
$tags = (strpos($str, '>') !== false ? explode('>', str_replace('<', '', $tags)) : array($tags));
        if(
end($tags) == '') array_pop($tags);
    }
    foreach(
$tags as $tag) $str = preg_replace('#</?'.$tag.'[^>]*>#is', '', $str);
    return
$str;
}

/* Strip only selected tags from teasers - in this case, embed and iframe */
function YOUR_THEME_preprocess_node(&$vars) {
  if(isset(
$vars['content']['body'][0]['#markup']) && $vars['teaser']) {
   
$vars['content']['body'][0]['#markup'] = strip_only($vars['content']['body'][0]['#markup'], '<iframe> <embed>');
  }
}
?>
Flandry’s picture

This is working for me with D7 and Bartik theme, but I had to hardcode the tag i wanted stripped, img, by adding this line after the for_each line of the strip_only function:

$str = preg_replace('/<img[^>]*>/', '', $str);

It didn't work to add img to the list of tags in the function call and it wasn't removing the iframe tag it was supposed to remove, either. I also had to change $vars to $variables. I'm not sure what's wrong with the strip-only function, but everything else seems to be okay.

I also decided I wanted to strip out div tags and anything inside, because the only time I use them in Articles is to float images with a caption. It would probably be best to check for an img within the div, and only then to match the closing div tag, but this does what I need it to for now.

    $str = preg_replace('/<div.*?<\/div>/', '', $str); /*Remove anything between the nearest opening and closing <div> tags. *Doesn't handle nested divs!* */

rolfmeijer’s picture

The reason the img tag doesn’t work here is because the strip_only replaces tags and their closing counter parts only. The img-tag has this structure: <tag />, but strip_only searches for <tag> and </tag>.

Also, for multiple tags I only got results without a space between the tags, i.e. '<iframe> <div>' doens’t work for me, but '<iframe><div>' does.

Skelly1983’s picture

if you only want to leave certain tags in and strip the rest ie. keep a, img, strong etc then you can change:

strip_tags($coreteaser)

to...

strip_tags($coreteaser, '<a> <img> <strong> <em> <b> <i> <span> <div> <h1> <h2>')

the function is can be inputed with the two arguments the first part defines what string to strip from and the 2nd part is what tags you want to exclude from being striped, this way you can still keep your styling.