it-swarm.com.de

Warum tut WP Nicht wie mein <a> Container?

In letzter Zeit habe ich an einigen Shortcodes gearbeitet, bei denen alle Elemente, die der Shortcode erzeugt, in einem Tag eingeschlossen sind. Leider wird dies nicht wie gewünscht gerendert, da der Filter wpautop auf the_content oder was auch immer Sie verwenden, um Shortcodes und/oder regulären Inhalt anzuzeigen.

Die Einrichtung

Stellen Sie sich vor, wir haben den folgenden Shortcode erstellt:

<?php

function example_shortcode($atts, $content = null) {
    extract(shortcode_atts(
        array(
           'before' => '',
           'after' => '',
           'link' => '',
        ), $atts)
    );

    $before = (!empty($atts['before'])) ? '<div class="before">'.$atts['before'].'</div>' : '';
    $after = (!empty($atts['after'])) ? '<div class="after">'.$atts['after'].'</div>' : '';
    $link = (!empty($atts['link'])) ? ' href="'.$atts['link'].'"' : '';

    return '<a'.$link.'>'.$before.do_shortcode($content).$after.'</a>';
}
add_shortcode('example_shortcode', 'example_shortcode');

Außerdem haben wir eine Seite mit folgendem Inhalt erstellt.

some text before the shortcode

[example_shortcode before="Welcome" after="Goodbye" link="#"]

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

[/example_shortcode]

some text after the shortcode

Die Tests

Wenn der Filter wpautop mit der Standardpriorität hinzugefügt wird, sieht die Ausgabe folgendermaßen aus:

<p>some text before the shortcode</p>
<a href="#"><div class="before">Welcome</div></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
<p><div class="after">Goodbye</div></a>
<p>some text after the shortcode</p>

Oder mit remove_filter('the_content', 'wpautop'); gibt es auch korrektes HTML zurück:

some text before the shortcode

<a href="#"><div class="before">Welcome</div>

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

<div class="after">Goodbye</div></a>

some text after the shortcode

Aber wenn der wpautop-Filter zum Beispiel mit einer höheren Priorität hinzugefügt wird ...

<?php
remove_filter('the_content', 'wpautop');
add_filter('the_content', 'wpautop', PHP_INT_MAX);

Dann gibt die Ausgabe alles durcheinander, wie folgt:

<p>some text before the shortcode</p>
<p><a href="#">
</a></p><div class="before"><a href="#">Welcome</a></div><a href="#">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
<div class="after">Goodbye</div>
</a><p><a href="#"></a></p>
<p>some text after the shortcode</p>

Das Problem und mein Ziel

Warum wird das <a> -Tag mehrmals hinzugefügt, wenn es nur einmal geöffnet und geschlossen werden soll?

Dies ist der HTML-Code, den ich rendern möchte, und dies kann erreicht werden, wenn das Tag <a> in der Funktion example_shortcode in z. ein <div> tag. Warum unterscheidet sich die Ausgabe dieser Tags?

<p>some text before the shortcode</p>
<a href="#">
<div class="before">Welcome</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
<div class="after">Goodbye</div>
</a>
<p>some text after the shortcode</p>
2
Fleuv

Ich denke, man kann mit Sicherheit sagen, dass wpautop() ein Korb ist, ohne die Gefühle anderer zu verletzen, aber ich würde es nicht entfernen und mit einer anderen Priorität hinzufügen, da dies, wie gezeigt, die Dinge nur verschlimmert (obwohl Sie das gepostet haben, was der Browser versucht zu machen) Gefühl von kaputtem HTML, anstatt die eigentliche Ausgabe, die nur einmal den <a> Tag hat).

Ich habe festgestellt, dass das Anwenden dieses Codes auf den Shortcode-Inhalt die meisten Probleme behebt, um das zerstörte HTML zu reparieren, das mit normaler Priorität erstellt wurde:

function cleanup_sc_content( $sc_content ) {
    $sc_content = force_balance_tags( $sc_content );
    $sc_content = preg_replace( '/<p>\s*+(<br\s*\/*>)?\s*<\/p>/i', '', $sc_content );
    return $sc_content;
}

dies ist eine Umnutzung (mit geringfügigen Änderungen) der ursprünglichen Funktion remove_empty_p(), die von @Michelle gepostet wurde, was wiederum auf @mtinsley (github ninnypants, original) zurückzuführen ist Kern ).

Um es zu verwenden, würde ich es nicht persönlich als Filter hinzufügen, sondern direkt auf den Shortcode-Inhalt anwenden, z.

return '<a' . $link . '>' . $before  
   . cleanup_sc_content( do_shortcode( shortcode_unautop( $content ) ) ) 
   . $after . '</a>';

(Beachten Sie, dass auch der shortcode_unautop()-Hack benötigt wird, da wpautop() zwar auf dem Inhalt von Shortcodes ausgeführt wird, shortcode_unautop() jedoch nicht - ja, wirklich). Angesichts der ständigen Fehlerkorrekturen von wpautop() und der vielen ausstehenden und verwirrenden Fehler (über Jahre hinweg), die möglicherweise zutreffen oder nicht zutreffen, wird diese (und jede andere) Lösung instabil sein.

2
bonger