Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

On the WordPress archive template I am using a custom excerpt function that includes a reference to strip_shortcodes(). For some reason, shortcodes are being rendered and displayed in the archive.

Example: http://arisehub.org/blog/page/2/

Scroll down to "Sing a New Song with Joshua Cunningham"

Notice the script code showing up. That's a shortcode reference to JW Player, showing up rendered.

Here's the code I'm using for the custom excerpt function.

function custom_excerpt($length, $more_text) { 
    global $post;     
    $text = get_the_content(); 
    $text = strip_shortcodes( $text );    
    $text = apply_filters('the_content', $text);  
    $text = str_replace(']]>', ']]>', $text);  
    $text = strip_tags($text, '<a>, <p>, <strong>, <em>, <b>');


    if(!empty($length)){
        $excerpt_length = apply_filters('excerpt_length', $length); 
    } else {
        $excerpt_length = apply_filters('excerpt_length', 180); 
    }

    if(!empty($more_text)){
        $excerpt_more = apply_filters('excerpt_more', ' ' . '&hellip; <br /><a href="'.get_permalink($post->id).'" class="more-link">'.$more_text.'</a>');
    } else { 
        $excerpt_more = apply_filters('excerpt_more', ' ' . '&hellip;<a href="'.get_permalink($post->id).'" class="more-link">+ more</a>');
    }

    $words = preg_split('/(<a.*?a>)|\n|\r|\t|\s/', $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE );  
    if ( count($words) > $excerpt_length ) {  
        array_pop($words);  
        $text = implode(' ', $words);  
        $text = $text . $excerpt_more;  
    } else {  
        $text = implode(' ', $words);  
    }  
    $output = '<p>'.$text.'</p>';
    echo $output;  
} 

Any ideas?

share|improve this question
    
The page you linked does not look like a custom archive, it looks like the regular blog loop. –  Wyck May 19 '11 at 5:17
    
first find out what template is being called. I usually use a class inside of one the template files but do not use it in the header or footer files so if you have a archive template in there add a div class to an existing or non existing element. So if you have a <div id="post-content" class="post custom class here for id"></div> or create an element <div id="custom id here for id" class="custom class ere for id"></div> –  xLRDxREVENGEx May 19 '11 at 6:51
    
@Wyck - It is the regular blog loop. Was something I said unclear? –  Jonathan Wold May 19 '11 at 20:34
    
@xLRDxREVENGEx - The template being called is archive.php –  Jonathan Wold May 19 '11 at 20:34
    
I'm wrestling with this one folks. Any additional ideas are greatly welcomed. –  Jonathan Wold May 26 '11 at 15:31

5 Answers 5

up vote 2 down vote accepted
+50

JW Player Plugin for WordPress does not register its shortcode like all other shortcodes, so strip_shortcodes() will not know about it and not strip it. In the code there is a note that this is because it uses argument names with a . in it, and WordPress does not support this.

There are probably multiple ways to solve this, but I would copy the relevant line from strip_shortcodes() and integrate the regex from the plugin:

function custom_excerpt( $length, $more_text ) {
    global $post;
    $text = get_the_content();
    $text = strip_shortcodes( $text );
    // Strip JW Player shortcode too
    $text = preg_replace( '/(.?)\[(jwplayer)\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)/s', '$1$6', $text );
    $text = apply_filters('the_content', $text);
    // Continue with the rest of your function ...
share|improve this answer
    
Thank you. That was an excellent answer (I appreciate your edits to my question as well) and it worked beautifully. –  Jonathan Wold May 30 '11 at 16:21
    
Only problem with this is if (unforeseeable, but just stating) Wordpress decides to change the format of their shortcodes - you would update the jwplayer shortcode to match, and then this script would break. –  Mike Jun 1 '11 at 15:38
    
@Mike: You mean if WordPress went from [shortcode] to {shortcode} or something like that? Then you have a lot more to worry about than just this shortcode: all your content would have to be scanned and replaced to use the new format. –  Jan Fabry Jun 1 '11 at 15:40
    
That is true, but for a person who doesn't know how to edit code - replacing shortcodes is annoying. editing code to fix something set in stone is next to impossible. –  Mike Jun 9 '11 at 5:10

There's a function on the Codex page for strip_shortcodes that does what you need:

function remove_shortcode_from_index($content) {
  if ( is_home() ) {
    $content = strip_shortcodes( $content );
  }
  return $content;
}
add_filter('the_content', 'remove_shortcode_from_index');

In your case, you would apply it to your archives page or wherever else you want.

share|improve this answer
    
I gave this a try and no change. The rendered shortcodes still go through. It looks like this is, in essence, the same thing that I am attempting to do with my function (code above). –  Jonathan Wold May 26 '11 at 22:41

Try the code below. It will only add the filter to strip shortcodes when your custom_excerpt function is called. The rest of your site will be unaffected. I am not sure how your get_the_content function fetches the content. So this filter will also take care of it.

function my_strip_jwplayer( $content ) {
    $content = strip_shortcodes( $content );
    return $content;
}

function custom_excerpt($length, $more_text) { 
global $post;     

// add a custom filter
add_filter('the_content', 'my_strip_jwplayer', 10);


$text = get_the_content(); 
$text = apply_filters('the_content', $text);  
$text = str_replace(']]>', ']]>', $text);  
$text = strip_tags($text, '<a>, <p>, <strong>, <em>, <b>');


if(!empty($length)){
    $excerpt_length = apply_filters('excerpt_length', $length); 
} else {
    $excerpt_length = apply_filters('excerpt_length', 180); 
}

if(!empty($more_text)){
    $excerpt_more = apply_filters('excerpt_more', ' ' . '&hellip; <br /><a href="'.get_permalink($post->id).'" class="more-link">'.$more_text.'</a>');
} else { 
    $excerpt_more = apply_filters('excerpt_more', ' ' . '&hellip;<a href="'.get_permalink($post->id).'" class="more-link">+ more</a>');
}

$words = preg_split('/(<a.*?a>)|\n|\r|\t|\s/', $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE );  
if ( count($words) > $excerpt_length ) {  
    array_pop($words);  
    $text = implode(' ', $words);  
    $text = $text . $excerpt_more;  
} else {  
    $text = implode(' ', $words);  
}  
$output = '<p>'.$text.'</p>';
echo $output;  

} 
share|improve this answer

Just going to take a shot in the dark here, but after looking at your code it seems like you might want to try to swap the order of the following 2 lines:

$text = strip_shortcodes( $text );    
$text = apply_filters('the_content', $text);

As far as I know, do_shortcode() is applied to the 'the_content' filter at 11. You are removing it and then adding it right back again. Doing this instead:

$text = apply_filters('the_content', $text);    
$text = strip_shortcodes( $text );    

may help.

share|improve this answer
    
strip_shortcodes() replaces all instances of Some text. [shortcode]Blah blah[/shortcode] Some more text. with Some text. Some more text. The shortcode is completely removed so do_shortcode() will have no shortcodes to act on anymore. So the original order is correct. –  Jan Fabry May 29 '11 at 19:36

I did some digging and tried to re-create this scenario.

The only answer I can come up with that might help you is that your JWPlayer shortcode is added to the shortcodes list in a filter on the_content.

strip_shortcodes only works when a shortcode is previously added to the shortcode list.. so my suspicion is that the JWPlayer shortcode is not added when you call that, but added in the filter.

There are two ways to go about solving this problem.

  1. add your own shortcode with the same name before you do strip_shortcodes to the list, adding the capability for the strip_shortcodes to remove it, however that will remove your JWPlayer from ALL exceprts (may or may not be what you want)
  2. Modify the JWPlayer location of where it adds the shortcode so that it is available before the_content filter gets called.

Edit Note for #1: After you do the strip_shortcodes, I would remove the shortcode you added, just incase the JWPlayer needs to be called somewhere else (outside of an excerpt) on the same page, it might conflict having two shortcodes added, depending on load order.

Solution for #1:

function nullfunc(){
  return '';
}
// put that function outside, it's the placeholder function just so the shortcode registers properly, if the callback isn't a valid function - it won't register.

// do your get_the_content() here
add_shortcode('<replace_with_shortcode_for_JWPlayer','nullfunc');
// do your strip shortcodes here
remove_shortcode('<rplace_with_shortcode_for_JWPlayer');

// continue on with the rest of your code.

These are just based on what I could recreate myself, and I'm not 100% sure they will help you, though I can't think of any other reason why strip_shortcodes would fail, and this is the only scenario that makes sense to me.

share|improve this answer
    
Mike, it seems like you're onto the right answer.. Shortcodes are a bit of new territory with me, would you mind giving me an example of how you might implement #1? I am OK with JWPlayer not showing up in any of the excerpts. –  Jonathan Wold May 26 '11 at 22:43
    
@Jonathan Wold: something like this: (couldn't get it to format into code, so i'm just going to edit my answer) –  Mike May 30 '11 at 4:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.