web-dev-qa-db-fra.com

Wordpress prend-il en charge un shortcode s’appelant à partir d’un appel shortcode?

J'ai construit un framework Wordpress super-fou qui comporte un million et un shortcodes, l'un d'entre eux est un shortcode de colonnes qui prend en charge un paramètre count qui vous permet de définir une colonne et la classe appropriée sera ajoutée.

Mon shortcode est le suivant:

add_shortcode('column', 'column_shortcode');
function column_shortcode($atts, $content = '')
{
    extract(shortcode_atts(array(
       'count' => 12
    ), $atts));

    if (stripos($count, '_') === FALSE)
    {
        if ((int) $count > 12)
        {
            $count = 12;
        }
    }

    $html = '<div class="column-'.$count.' column">';
    $html .= do_shortcode($content);
    $html .= '</div>';

    return $html;
}

Il semble y avoir un problème cependant, lorsque le shortcode de colonne est utilisé dans une colonne, s'agit-il d'un problème connu ou Wordpress ne prend-il pas en charge les shortcodes du même nom imbriqués les uns dans les autres?

Ce qui se passe essentiellement, c’est que la colonne qui se trouve à l’intérieur est prématurément fermée dans le code HTML généré et que [/ column] est encapsulé dans des balises de paragraphe affichées au niveau du frontal. Cependant, si je crée un autre shortcode et que je l'appelle enfant, en utilisant exactement le même code que ci-dessus, seul le code shrotcode de l'enfant est simplement [enfant] au lieu de [colonne], tout fonctionne comme prévu.

Voici le code de l'éditeur WYSIWYG dans mon installation Wordpress. La pièce A est le scénario idéal, je ne veux pas avoir à utiliser deux codes courts différents qui font la même chose. La pièce B est ce qui fonctionne simplement en dupliquant le code abrégé.

Annexe A - ne fonctionne pas

[column count="9"]

[column count="8_9"]

Welcome to the site.

Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head."

[/column]

[/column]

Pièce B - œuvres

[column count="9"]

[child count="8_9"]

Welcome to the site.

Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head."

[/child]

[/column]
2
Dwayne Charrington

C'est un problème connu. Si vous avez un shortcode dans un autre qui porte le même nom, l'analyseur wordpress ne pourra pas le gérer correctement. Ceci est également mentionné dans la page de codex pour l'API shortcode sous limitations.

De la page liée However the parser will fail if a shortcode macro is used to enclose another macro of the same name

La solution que je suggère est d’ajouter des paramètres supplémentaires à l’appel de shortcode principal et dans votre fonction de shortcode, s’appelant récursivement lui-même en fonction de la présence de ces paramètres supplémentaires.

EXEMPLE

[column count="9" child="8_9" 8_9_text="

Welcome to the site.

Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head."
" /]

Puis dans le code

function shortcode_handler($atts, $content, $tag) {
    if(isset($atts['child']))
        $output = shortcode_handler(array('count'=>$atts['child']), $atts[$atts['child'].'_text'])

    // Do something else with the output

}

Je sais que ça n'a pas l'air bien, mais peut-être que vous pouvez régler quelque chose dans le contexte de votre demande.

2
Mridul Aggarwal

J'ai écrit une petite fonction qui activera les codes courts en eux-mêmes. Cela devrait fonctionner parfaitement pour votre problème. Cela a été super utile pour moi.

Ouvrez le fichier 'wp-includes/shortcodes.php' et remplacez la fonction do_shortcode () (ligne 201) par la suivante

function do_shortcode($content) {
    global $shortcode_tags;

    if (empty($shortcode_tags) || !is_array($shortcode_tags))
        return $content;

    $content = enable_recursive_shortcodes($content);

    $pattern = get_shortcode_regex();
    return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
}

Tout ce qui a été changé est l'ajout de * $ content = enable_recursive_shortcodes ($ content); *

Cette fonction parcourt le contenu $ qui lui est transmis et ajoute un suffixe aux noms de code abrégé des codes abrégés qu'ils contiennent. Ensuite, seuls les codes courts externes sont traités et, lorsque leur contenu est traité, le suffixe est supprimé, ce qui permet leur traitement. Il n'y a pas de limite au nombre de niveaux qu'il peut atteindre. (exemple: [box] [box] [box] [box] Contenu [/ box] [/ box] [/ box] [/ box])

Ajoutez la fonction suivante au-dessus de la fonction do_shortcode ()

/**
 * Add shortcode suffix enabling recursive shortchodes.
 *
 * This function goes inside the set of $recursive_tags and adds a suffix to
 * the shortcode name so it will allow a shortcode to call itself in its content
 *
 * @since 2.5
 * @return string Content with recursive shortcodes modified out.
 */
function enable_recursive_shortcodes($content) {

    $recursive_tags = array( 'column', 'div', 'span', 'table' ); // define recursive shortcodes, these must have closing tags 
    $suffix = '__recursive'; // suffix is added to the tag of recursive shortcodes

    $content = str_replace( $suffix, '', $content ); // remove old suffix on shortcodes to start process over

    foreach( $recursive_tags as $recursive_tag ) {

        $open_tag = '[' . $recursive_tag . ' ';
        $close_tag = '[/'. $recursive_tag . ']';

        $open_tags = 0;

        $open_pos = stripos( $content, $open_tag ); // find first opening tag

        $offset = $open_pos + strlen( $open_tag ); // set offset for first closing tag

        while( $open_pos !== false ) {

            $close_pos = stripos( $content, $close_tag, $offset ); // find first closing tag

            if(++$open_tags > 1) { // if we are inside an open tag

                // modify open tag from original shortcode name
                $content = substr( $content, 0, $open_pos ) . 
                            '[' .$recursive_tag . $suffix . ' ' . 
                              substr( $content, $offset ); 
                // modify closing tag from original shortcode name
                $content = substr( $content, 0, $close_pos + strlen($suffix) ) . 
                            '[/'.$recursive_tag.'__recursive]' . 
                            substr( $content, $close_pos + strlen( $close_tag ) + strlen($suffix) ); 
                $open_tags--;
            }

            $open_pos = stripos( $content, $open_tag, $offset ); // find next opening tag

            if( $close_pos < $open_pos ) $open_tags--; // if closing tag comes before next opening tag, lower open tag count

            $offset = $open_pos + strlen($open_tag); // set new offset for next open tag search

        }

    }

    return $content;

}

Veillez à mettre à jour la variable $ recursive_tags selon vos besoins. Seules ces balises seront vérifiées pour les enfants du même nom. Ces balises doivent avoir des balises de fermeture [column] [/ column] car [column /] ne fonctionnera pas. Ils doivent également avoir un espace après le nom de shortcode dans la balise d'ouverture et aucun espace dans la balise de fermeture en raison de la manière dont la fonction effectue une recherche dans les balises. Si quelqu'un met à jour le code pour autoriser les codes abrégés de style [colonne] ou [colonne /], veuillez le partager.

2
Trey Welstad

La solution la plus simple - mais peut-être pas la meilleure - que j'ai trouvée consiste à ajouter le tag plusieurs fois sous de légères variations. Par exemple, dans le cas du questionneur, cela pourrait être:

function render_column( $atts, $content ) {
    // etc.

    return apply_filters( 'the_content', $content );
}

add_shortcode( 'column', 'render_column' );
add_shortcode( 'column-level-2', 'render_column' );
add_shortcode( 'column-level-3', 'render_column' );

Cela nécessite un peu de documentation supplémentaire et certains utilisateurs pourraient ne pas la comprendre immédiatement, mais j'estime que c'est un peu plus intuitif que de demander aux utilisateurs de mettre le contenu du shortcode dans un attribut. Et bien sûr, cette solution introduit le problème distinct de la gestion des guillemets dans un attribut shortcode.

0
John Watkins