4
votes

Is it possible to filter out only the shortcode from the post and then run the shortcode?

My page looks like this:

[summary img="images/latest.jpg"]

This here is the summary

[/summary]

Lots of text here...

And i just want to display the shortcode on a specific page.

Tried using regular expressions, but they dont seem to work:

$the_query = new WP_Query('category_name=projects&showposts=1');

    //loop
    while ( $the_query->have_posts() ) : $the_query->the_post();
        echo '<b>';
        the_title();
        echo '</b>';
        echo '<p>';

        $string = get_the_content();

        if (preg_match("[\\[[a-zA-Z]+\\][a-zA-Z ]*\\[\/[a-zA-Z]+\\]]", $string , $matches)) {
            echo "Match was found <br />";
            echo $matches[0];
        }

        echo '</p>';
    endwhile;

Any idéas?

EDIT:

Found a temporary solution.

while ( $the_query->have_posts() ) : $the_query->the_post();

    $content = str_replace(strip_shortcodes(get_the_content()),"",get_the_content());               
    echo do_shortcode($content);

endwhile;

I saw that wordpress had a function for striping shortcodes but not for strip content. So i replaced the stripped content string from the whole post to get just the shortcode. The only bad thing about this that the shortcodes have to be in the beginning of the posts.

5

5 Answers

13
votes

Better answer is:

$pattern = get_shortcode_regex();
preg_match('/'.$pattern.'/s', $post->post_content, $matches);
if (is_array($matches) && $matches[2] == 'the_shortcode_name') {
   $shortcode = $matches[0];
   echo do_shortcode($shortcode);
}

It will search through the post content for a shortcode called “the_shortcode_name”. If it finds it, it will store the shortcode in the $matches variable. Easy to run it from there.

2
votes

I've had the following problems with these answers:

  1. regex pattern not containing all registered shortcode tags
  2. inability to get all shortcodes from the post

.. and my solution is:

// Return all shortcodes from the post
function _get_shortcodes( $the_content ) {

    $shortcode = "";
    $pattern = get_shortcode_regex();
    preg_match_all('/'.$pattern.'/uis', $the_content, $matches);

    for ( $i=0; $i < 40; $i++ ) {

        if ( isset( $matches[0][$i] ) ) {
           $shortcode .= $matches[0][$i];
        }

    }

    return $shortcode;

}

Use it like so:

<?php echo do_shortcode( _get_shortcodes( get_the_content() ) ) ?>
1
votes

Search wherever your shortcode position is on your content

Example :

[my_shortcode]
[my_shortcode_2]

or

[my_shortcode_2]
[my_shortcode]

Functions.php

function get_shortcode($code,$content) {
    $pattern = get_shortcode_regex();
    preg_match_all('/'.$pattern.'/s',$content,$matches);
    if(is_array($matches) && isset($matches[2]) && in_array($code,$matches[2])) {
        $index = array_search($code,$matches[2]);
        $shortcode = $matches[0][$index];;
        return do_shortcode($shortcode);
    } else {
        return false;
    }
}

Using example :

$content = $post->post_content;
$my_shortcode = get_shortcode('my_shortcode',$content);
$my_shortcode_2 = get_shortcode('my_shortcode_2',$content);
echo $my_shortcode;
if($my_shortcode){ // if shortcode#1 found so echo shortcode#2 after
   echo $my_shortcode_2;
}
0
votes

use this regex

preg_match('/\[summary[^\]]*](.*)\[\/summary[^\]]*]/uis', $string , $matches)

$match[1] should be your text

Edit: ok to match any combination of tags use

/\[([^\]]+)\](.*?)\[\/\1\]/uis

but if you have nested tags you might need to parse the matches again recursively. However if it is a wordpress free text i think you might get too complex cases that a simple script can handle

-1
votes

You can do this using the get_shortcode_regex() function to get the regex for all registered shotcodes in your blog, apply that to the content to get an array of shortcodes found in that content, then call the appropriate callback to process the one you want.

So inside a loop somewhere it would be something like:

$pattern = get_shortcode_regex();
$matches = array();
preg_match_all("/$pattern/s", get_the_content(), $matches);
var_dump($matches); //Nested array of matches
//Do the first shortcode
echo preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $matches[0][0] );

This will execute the first shortcode found in the post, obviously in practice you want to check that you've got one!