web-dev-qa-db-fra.com

Comment analyser des codes courts imbriqués?

Les codes abrégés imbriqués ne seront pas analysés correctement:

[row]
    [col size="6"]...[/col]
    [col size="6"]
        [row]
            [col size="6"]...[/col]
            [col size="6"]...[/col]
        [/row]
    [/col]
[/row]

D'après la documentation WordPress , je comprends qu'il s'agit d'une limitation des codes courts de WordPress. Est-il encore possible de le faire fonctionner?

Edit: Voici le code de mon code court, il fonctionne correctement s'il n'est pas imbriqué (par exemple, le shortcode de la ligne n'est pas utilisé dans le shortcode de la colonne).

add_shortcode( 'row', 'row_cb' );
function row_cb( $atts, $content = null ) {             
        $output = '';
        $output .= '<div class="row">';
        $output .= do_shortcode( $content );        
        $output .= '</div>';

        return $output; 
}

add_shortcode( 'col', 'col_cb' );
function col_cb( $atts, $content = null ) {     
    extract( shortcode_atts( array(
            'size'  => '',
        ), $atts ) );


    $output = '';
    $output .= '<div class="col">';
    $output .= do_shortcode( $content );        
    $output .= '</div>';

    return $output; 
}
3
jay

Il existe une solution pour cela, en fait. Le shortcode que vous utilisez a la variable $ content, sans le filtre do_shortcode , comme ceci:

do_shortcode($content)

Ouvrez le fichier contenant les codes courts et modifiez $ content pour do_shortcode ($ content). Ça va marcher.

4
Gerard

J'ai créé une solution pour mes codes abrégés imbriqués, vous pourriez peut-être utiliser quelque chose de celle-ci.

J'ai utilisé une expression rationnelle récursive (notice |(?R)), donc ce n'est peut-être pas aussi rapide que le do_shortcode officiel, mais cela permet d'imbriquer des shortcodes avec le même nom.

Ma demande était de ne pas avoir une liste fixe de codes abrégés (donc, tous les codes abrégés de contenu doivent être analysés), afin de permettre n'importe quel niveau d'imbrication, et également d'utiliser une structure de $ atts, contenant certains paramètres, le temps de remplir ce contenu exact.

Pour $ atts, j'ai également écrit ma propre fonction, car je voulais que $ atts inclue à la fois tout ce qui provient du contenu (et pas seulement ceux dont la valeur par défaut est définie), ainsi que les valeurs par défaut de ces champs, existant dans le tableau par défaut. et ne venant pas des valeurs de shortcode.

Voici ma fonction atts:

function complete_atts_with_defaults( $pairs, $atts = array() ) {
  $out = $atts;
  foreach ($pairs as $name => $default) {
    if ( array_key_exists($name, $atts)  && !empty( $atts[$name] ) ) { continue; }
    //else
    $out[$name] = $default;
  }
  return $out;
}

Et voici l'autre code:

define( 'OUR_SHORTCODE_FULL_REGEX', '@\[([a-z0-9_]+)([^\]]*)\]((?:[^[]|(?R))+)\[\/\1\]@' );
define( 'OUR_SHORTCODE_HALF_REGEX', '@\[([a-z0-9_]+)([^\]]*)\/\]@' );

function fill_all_post_placeholders( $text, $atts = array() ) {
  //...
  $text = str_replace( '%5B', '[', $text );
  $text = str_replace( '%5D', ']', $text );

  $atts = complete_atts_with_defaults(
        array(
            'value1' => 'Hi :)',
            'value2' => '',
            'value3' => '',
        ), $atts );

  //...

  $text = preg_replace_callback( OUR_SHORTCODE_HALF_REGEX, function( $match ) use ( $atts ) { return replace_half_shortcode_placeholder( $match[1], $match[2], $atts ); }, $text );
  $text = preg_replace_callback( OUR_SHORTCODE_FULL_REGEX, function( $match ) use ( $atts ) { return replace_shortcode_placeholder( $match[1], $match[2], $match[3], $atts ); }, $text );

  return $text;
}

function replace_shortcode_placeholder( $name, $params, $content, $atts ) {
  $content = preg_replace_callback( OUR_SHORTCODE_FULL_REGEX, function( $match ) use ( $atts ) { return replace_shortcode_placeholder( $match[1], $match[2], $match[3], $atts ); }, $content );
  //   $function_to_call = '_rp_' . $name;
  //   if ( function_exists( $function_to_call ) ) { return $function_to_call( $name, $params, $atts ); }
  //   //else
  //   $value = $atts[ $name ];
  //   if ( empty( $value ) ) { return ''; }
  //   //else
  //   return $value;

  return '<br>name: '  . $name . ' <br>params: ' . $params . ' <br>content: (' . $content . ')<br><br>';
}

function replace_half_shortcode_placeholder( $name, $params, $atts ) {
  //   $function_to_call = '_rp_' . $name;
  //   if ( function_exists( $function_to_call ) ) { return $function_to_call( $name, $params, $atts ); }
  //   //else
  //   $value = $atts[ $name ];
  //   if ( empty( $value ) ) { return ''; }
  //   //else
  //   return $value;

  return '<br>name half: '  . $name . ' <br>params half: ' . $params . '<br><br>';
}

Je vous ai laissé intacte la zone commentée afin que vous puissiez voir comment ces fonctions pourraient être utilisées.

Ces "shortcodes" ne sont pas enregistrés, comme vous pouvez le constater dans le code commenté, ils fonctionnent différemment, de manière dynamique.

En outre, la règle nécessaire pour que ces codes courts fonctionnent consiste à toujours ajouter '/' aux balises à fermeture automatique, comme on le ferait en XML. (Dans le code, ils sont appelés "demi-codes courts".)

Exemple pour le contenu analysé par ce code (désolé pour le charabia):

[show_text_if campaign="2899"]subscribing to this newsletter [show_text_if campaign="2901" field_value="'a href='http://ajshdash.com/asdhal/asdasdasd'" field_value2="айксчд асй даксчй д"]subscribing to this new newsletter[/show_text_if] [red value1="dfsdfs" value2="sdfkls dfh skjha skd"/][/show_text_if]

[color value3="askdfjajls" value4="lskdfhjsldhfs df"/]

[show_text_if_not campaign="2899"]asdklja slkd alkd alskdj alsjd alsj als jdalsk jals dalskj asjd <a href="http://example.com/experiment/" target="_blank">Experiment</a> once more hooray! [green value4="askljjlaskd"/] Я сегодня это Я и я! :)[/show_text_if_not]

[show_text_if field_name="campaign" field_value="2899"]slkjd alsjkd aljsd ajs d new[/show_text_if]

Et je comprends, ce code n’est pas une solution directe à ce que vous avez demandé, mais vous pourriez peut-être en utiliser une partie pour trouver la solution vous-même.

1
Olga Farber

Votre rappel de shortcode devrait ressembler à quelque chose comme:

add_shortcode('col', 'col_cb');

add_shortcode('row', 'row_cb');

function col_cb( $atts, $content ) {
  $content = do_shortcode($content);
  // ...
}

function row_cb( $atts, $content ) {
  $content = do_shortcode($content);
  // ...
}
0
gmazzap