Filtrare l'output di uno shortcode specifico?
Esiste un hook in WordPress che posso utilizzare per filtrare l'output di uno shortcode specifico? Qualcosa del genere:
add_filter('shortcode_output', 'my_filter_function', 2);
function my_filter_function ( $output, $shortcode ) {
// ...
}
Dove $shortcode
potrebbe essere qualcosa come [my_schortcode]
o ancora meglio, lo shortcode e i suoi attributi separati in un array.
WordPress 4.7 ha introdotto un nuovo filtro, do_shortcode_tag
, proprio per fare questo.

+1 per questa soluzione poiché ora sostituisce la risposta accettata. Sarebbe bello se potessi modificare la tua risposta e fornire un piccolo esempio su come utilizzarla. I parametri del filtro non sono ovvi.

Per completezza: https://developer.wordpress.org/reference/hooks/do_shortcode_tag/

Ancora più completezza! https://developer.wordpress.org/reference/hooks/pre_do_shortcode_tag/

Finalmente, ho aspettato anni per questo tipo di implementazione. WordPress dovrebbe sempre applicare questo tipo di filtri prima del rendering. Un esempio per rimuovere i rientri a tabulazione dal codice sorgente: function example_shortcode_output($output, $tag, $attr, $m){
if($tag == 'gallery') $output = str_replace("\t", '', $output);
return $output;
}
add_filter('do_shortcode_tag', 'example_shortcode_output', 10, 4);

Non esiste un filtro che io conosca pensato per indirizzare singoli shortcode come desideri.
Puoi filtrare gli attributi con shortcode_atts_{$shortcode}
però.
Puoi "dirottare" un altro shortcode creando la tua callback e registrandola con lo slug originale dello shortcode. Penso che sia ciò che probabilmente dovrai fare.
Prova di concetto:
function my_gallery_shortcode($atts) {
return 'ciao';
}
add_shortcode('gallery','my_gallery_shortcode');
Ora prova a usare una galleria :)

Hai ragione. Non esiste un filtro per quello che volevo fare. Quindi invece di quello, sto filtrando the_content
. Funziona per il mio caso d'uso.

A partire dalla versione 4.7, esiste un filtro. Vedi la risposta di Shawn H qui sotto.

Sebbene non esista un hook diretto, c'è una piccola soluzione alternativa che rende possibile il tuo obiettivo finale. Puoi creare un nuovo shortcode che, per ogni istanza, avvolga sempre qualsiasi altro shortcode di cui vuoi filtrare l'output.
Utilizzo in un articolo, ecc.:
Ecco del testo nell'articolo. Bla bla...
[filter][target_annoying_shortcode size="small" limit="20"][/filter]
Ecco altro testo nel mio articolo. Ancora bla bla...
Nel file functions.php:
function my_shortcode_output_filter( $attr, $content ) {
// Converti lo shortcode nel suo output
$content_translated = do_shortcode(trim($content));
if($shortcode_to_modify == $content || !$content_translated) {
// Gestione degli errori
return 'Si è verificato un errore nel filtrare lo shortcode: '.$content;
}
// Ora modifica l'output come preferisci, qui...
$content_translated_and_filtered = $content_translated;
return $content_translated_and_filtered;
}
add_shortcode('filter', 'my_shortcode_output_filter');

L'unica cosa che puoi filtrare sono gli attributi dello shortcode:
apply_filters( "shortcode_atts_{$shortcode}", $out, $pairs, $atts );
Il punto è che $shortcode
è il terzo argomento quando si registra uno shortcode. Questo argomento è piuttosto nuovo e quasi nessuno shortcode lo utilizza, quindi ricadrà nel valore predefinito - che è una stringa
vuota ''
.
Questo porta a un risultato divertente:
add_filter( 'shortcode_atts_', 'wpse112294_shortcode_atts_cb' );
function wpse112294_shortcode_atts_cb( $out, $pairs, $atts )
{
// qui dobbiamo trovare un modo per identificare in modo univoco uno shortcode
// per cui non abbiamo un nome
// qualcosa che renda lo shortcode unico:
$found = isset( $pairs['foo_attribute_key'] );
if ( $found )
{
// Rimuovi immediatamente questo filtro per risparmiare tempo di elaborazione:
remove_filter( current_filter(), __FUNCTION__ );
// fai qualcosa di straordinario qui!
}
return $out;
}
Quindi, sì, con una probabilità del 90% dobbiamo filtrare l'output di ogni(!) shortcode e cercare di identificare in qualche modo lo shortcode tramite alcuni argomenti predefiniti ($pairs
) o tramite argomenti di input (impossibile). Poi, finalmente, siamo in grado di elaborare l'output. Siamo in grado di elaborare la stringa stessa? No. Questo deve essere fatto nel modo mostrato da @s_ha_dum sopra.

Anche se @s_ha_dum ha fornito una risposta valida, è possibile creare un nuovo shortcode per filtrare uno shortcode esistente. Ad esempio,
function filter_function($atts, $content) {
extract(shortcode_atts(array(
'att1' => 'val1',
'att2' => 'val2'
), $atts));
//salva l'output dello shortcode in $return
$return = do_shortcode("[existing_shortcode att1='$att1' att2='$att2'".$content."/existing_shortcode]");
//inserisci qui il codice per modificare $return
echo $return;
}
add_shortcode('new_shortcode','filter_function');
nota che per lo shortcode [embed]
, devi usare
global $wp_embed;
$return = $wp_embed->run_shortcode("[embed ...
invece di do_shortcode
