it-swarm.com.de

Wie parse ich verschachtelte Shortcodes?

Die verschachtelten Shortcodes werden nicht korrekt analysiert:

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

Aus der WordPress-Dokumentation verstehe ich, dass es sich um eine Einschränkung der WordPress-Shortcodes handelt. Ist es noch möglich, es zum Laufen zu bringen?

Edit: Hier ist mein Shortcodes-Code. Er funktioniert einwandfrei, wenn er nicht verschachtelt ist (dh, der Zeilen-Shortcode wird nicht im col-Shortcode verwendet).

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

Dafür gibt es tatsächlich eine Lösung. Der von Ihnen verwendete Shortcode hat die Variable $ content, ohne den Filter do_shortcode , wie folgt:

do_shortcode($content)

Öffnen Sie die Datei, in der sich die Shortcodes befinden, und ändern Sie $ content für do_shortcode ($ content). Es wird klappen.

4
Gerard

Ich habe eine Lösung für meine verschachtelten Shortcodes erstellt. Vielleicht können Sie etwas daraus verwenden.

Ich habe einen rekursiven regulären Ausdruck (note |(?R)) verwendet, daher ist er möglicherweise nicht so schnell wie der offizielle do_shortcode, ermöglicht jedoch das Verschachteln von Shortcodes mit demselben Namen.

Mein Wunsch war es, keine feste Liste von Shortcodes zu haben (daher müssen alle in den Inhalten vorhandenen Shortcodes analysiert werden), um eine beliebige Verschachtelungsebene zu ermöglichen und auch eine Struktur von $ atts zu verwenden, die einige Parameter enthält, die unter vorhanden sind der Zeitpunkt, zu dem genau dieser Inhalt ausgefüllt wurde.

Für $ atts habe ich auch meine eigene Funktion geschrieben, da ich wollte, dass $ atts sowohl alles aus dem Inhalt (und nicht nur die, deren Standardwert definiert ist) als auch die Standardwerte für diese Felder enthält, die im Standardarray vorhanden sind und nicht aus den Shortcode-Werten.

Hier ist meine atts Funktion:

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;
}

Und hier ist der andere 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>';
}

Ich habe den kommentierten Bereich für Sie unangetastet gelassen, damit Sie sehen können, wie diese Funktionen verwendet werden können.

Diese "Shortcodes" von mir sind nicht registriert, wie Sie im kommentierten Code sehen können, sie funktionieren dynamisch anders.

Die notwendige Regel für das Funktionieren dieser Shortcodes wäre auch, immer '/' zu den sich selbst schließenden Tags hinzuzufügen, wie dies in XML der Fall ist. (Im Code werden sie "Halb-Shortcodes" genannt.)

Beispiel für den Inhalt, der von diesem Code analysiert wird (Entschuldigung für den Kauderwelsch):

[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]

Und ich verstehe, dass dieser Code keine direkte Lösung für das ist, wonach Sie gefragt haben, aber vielleicht könnten Sie einen Teil davon verwenden, um die Lösung selbst zu erarbeiten.

1
Olga Farber

Ihr Shortcode-Rückruf sollte ungefähr so ​​aussehen:

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