Is there a hook in WordPress that I can use to filter the output of a specific shortcode? Something like this:
add_filter('shortcode_output', 'my_filter_function', 2);
function my_filter_function ( $output, $shortcode ) {
....
}
Where $shortcode would be something like [my_schortcode] or even better, shortcode and its attributes separated into an array.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
There is no filter that I know of that is meant to target individual shortcodes like you want.
You can filter attributes with shortcode_atts_{$shortcode} though.
You can hijack another shortcode by creating your own callback and registering it with the original shortcode slug. I think that is what you are probably going to need to do.
Proof of concept:
function my_gallery_shortcode($atts) {
return 'howdy';
}
add_shortcode('gallery','my_gallery_shortcode');
Now try to use a gallery 🙂
Method 2
WordPress 4.7 introduced a new filter, do_shortcode_tag, to do exactly this.
Method 3
While there is no hook, there is a small workaround that makes your end-goal possible. You can create a new shortcode that, on a per-instance basis, you always wrap around any other shortcode whose output you want to filter.
Usage in a post, etc:
Here is some post text. Blah blah... [filter][target_annoying_shortcode size="small" limit="20"][/filter] Here is some more text in my post. More blah blah...
In functions.php:
function my_shortcode_output_filter( $attr, $content ) {
// Express the shortcode into its output
$content_translated = do_shortcode(trim($content));
if($shortcode_to_modify == $content || !$content_translated) {
// Error handling
return 'There was an error in filtering shortcode: '.$content;
}
// Now modify the output as you like, here...
$content_translated_and_filtered = $content_translated;
return $content_translated_and_filtered;
}
add_shortcode('filter', 'my_shortcode_output_filter');
Method 4
The only thing that you can filter is the attributes fo the shortcode:
apply_filters( "shortcode_atts_{$shortcode}", $out, $pairs, $atts );
Point is, that $shortcode is the third argument when registering a shortcode. This argument is pretty new and nearly no shortcode uses it, therefore it will fall back to the default – which is a string of ''.
This leads to a funny result:
add_filter( 'shortcode_atts_', 'wpse112294_shortcode_atts_cb' );
function wpse112294_shortcode_atts_cb( $out, $pairs, $atts )
{
// here we need to find a way to uniquely identify a shortcode
// for which we ain't got a name
// something that makes the shortcode unique:
$found = isset( $pairs['foo_attribute_key'] );
if ( $found )
{
// Instantly remove this filter to save processing time:
remove_filter( current_filter(), __FUNCTION__ );
// do something stunning in here!
}
return $out;
}
So, yes, with a 90% chance we need to filter the output of every(!) shortcode and try to somehow identify the shortcode by either some default arguments ($pairs) or by input arguments (impossible). Then, finally we’re able to process the output. Are we able to process the string itself? No. This has to be done the way @s_ha_dum showed above.
Method 5
While @s_ha_dum gave a decent answer, you can create a new shortcode for the purpose of filtering an existing shortcode. For example,
function filter_function($atts, $content) {
extract(shortcode_atts(array(
'att1' => 'val1',
'att2' => 'val2'
), $atts));
//save shortcode output in $return
$return = do_shortcode("[existing_shortcode att1='$att1' att2='$att2'".$content."/existing_shortcode]");
//insert code to modify $return
echo $return;
}
add_shortcode('new_shortcode','filter_function');
note that for the shortcode, you have to use
global $wp_embed;
$return = $wp_embed->run_shortcode("[embed ...
instead of do_shortcode
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0