wake-up-neo.com

Wordpress-Filter zum Ändern der endgültigen HTML-Ausgabe

Wordpress verfügt über eine großartige Filterunterstützung, um bestimmte Arten von Inhalten abzurufen und vor der Ausgabe zu ändern. Wie der Filter "the_content", mit dem Sie auf das Markup eines Posts zugreifen können, bevor er auf dem Bildschirm ausgegeben wird. 

Ich versuche einen Catch-All-Filter zu finden, der mir einen letzten Riss beim Ändern des endgültigen Markups vor der Ausgabe gibt. Kennt jemand einen?

Ich habe die Filterliste mehrmals durchsucht, aber nichts springt bei mir heraus: http://adambrown.info/p/wp_hooks/hook/filters

(Ich habe einige Wordpress-spezifische Communities für diese Frage angetippt, aber da ich keine einzige Antwort erhalten hatte, dachte ich, ich würde mich an die ehrwürdige SO wenden.)

48

AFAIK, dafür gibt es keinen Haken, da die Themes HTML verwenden, das von WordPress nicht verarbeitet wird.

Sie können jedoch Ausgabepufferung verwenden , um den endgültigen HTML-Code abzufangen:

<?php
// example from php.net
function callback($buffer) {
  // replace all the apples with oranges
  return (str_replace("apples", "oranges", $buffer));
}
ob_start("callback");
?>
<html><body>
<p>It's like comparing apples to oranges.</p>
</body></html>
<?php ob_end_flush(); ?>
/* output:
   <html><body>
   <p>It's like comparing oranges to oranges.</p>
   </body></html>
*/
16
moff

WordPress hat keinen "endgültigen Ausgabefilter", aber Sie können einen zusammen hacken. Das folgende Beispiel befindet sich in einem "Must Use" Plugin, das ich für ein Projekt erstellt habe. 

Hinweis: Ich habe noch keine Plugins getestet, die die Aktion "Herunterfahren" verwenden könnten.

Das Plugin arbeitet durch, indem es alle offenen Pufferpegel durchläuft, sie schließt und ihre Ausgabe erfasst. Dann wird der Filter "final_output" ausgelöst und der gefilterte Inhalt angezeigt.

Leider führt WordPress fast genau den gleichen Vorgang aus (das Schließen der offenen Puffer), erfasst jedoch nicht den Puffer für die Filterung (löscht ihn nur), so dass zusätzliche Aktionen zum Herunterfahren keinen Zugriff darauf haben. Aus diesem Grund hat die unten stehende Aktion Vorrang vor WordPress.

wp-content/mu-plugins/buffer.php

<?php

/**
 * Output Buffering
 *
 * Buffers the entire WP process, capturing the final output for manipulation.
 */

ob_start();

add_action('shutdown', function() {
    $final = '';

    // We'll need to get the number of ob levels we're in, so that we can iterate over each, collecting
    // that buffer's output into the final output.
    $levels = ob_get_level();

    for ($i = 0; $i < $levels; $i++) {
        $final .= ob_get_clean();
    }

    // Apply any filters to the final output
    echo apply_filters('final_output', $final);
}, 0);

Ein Beispiel für das Einhängen in den final_output-Filter:

<?php

add_filter('final_output', function($output) {
    return str_replace('foo', 'bar', $output);
});

Bearbeiten:

Dieser Code verwendet anonyme Funktionen, die nur in PHP 5.3 oder höher unterstützt werden. Wenn Sie eine Website mit PHP 5.2 oder älter betreiben, leisten Sie sich selbst einen schlechten Dienst. PHP 5.2 wurde 2006 veröffentlicht, und obwohl Wordpress STILL dies unterstützt, sollten Sie es nicht verwenden.

46
kfriend

die Frage ist vielleicht alt, aber ich habe einen besseren Weg gefunden.

function callback($buffer) {
  // modify buffer here, and then return the updated code
  return $buffer;
}

function buffer_start() { ob_start("callback"); }

function buffer_end() { ob_end_flush(); }

add_action('wp_head', 'buffer_start');
add_action('wp_footer', 'buffer_end');

Erklärung Dieser Plugin-Code registriert zwei Aktionen - buffer_start und buffer_end.

buffer_start wird am Ende des Header-Abschnitts der HTML-Datei ausgeführt. Der Parameter, die Funktion callback, wird am Ende der Ausgabepufferung aufgerufen. Dies geschieht in der Fußzeile der Seite, wenn die zweite registrierte Aktion buffer_end ausgeführt wird.

Mit der Funktion callback fügen Sie Ihren Code hinzu, um den Wert der Ausgabe (die Variable $buffer) zu ändern. Dann geben Sie einfach den geänderten Code zurück und die Seite wird angezeigt.

Hinweise Achten Sie darauf, eindeutige Funktionsnamen für buffer_start, buffer_end und callback zu verwenden, damit diese nicht mit anderen Funktionen in Plugins in Konflikt stehen.

18
Jacer Omri

@jacer, wenn Sie die folgenden Hooks verwenden, wird auch die header.php eingeschlossen.

function callback($buffer) {      
    $buffer = str_replace('replacing','width',$buffer);
    return $buffer; 
}

function buffer_start() { ob_start("callback"); } 
function buffer_end() { ob_end_flush(); }

add_action('after_setup_theme', 'buffer_start');
add_action('shutdown', 'buffer_end');
10
Nick Kuijpers

In der Tat gab es kürzlich eine Diskussion auf der WP-Hackers-Mailingliste über das Thema der vollständigen Seitenänderung, und es scheint, dass der Konsens darin bestand, dass Ausgabepufferung mit ob_start () usw. die einzige wirkliche Lösung war. Es gab auch einige Diskussionen zu den Vor- und Nachteilen: http://groups.google.com/group/wp-hackers/browse_thread/thread/e1a6f4b29169209a#

Zusammenfassend: Es funktioniert und ist im Bedarfsfall die beste Lösung (wie im WP-Supercache-Plugin), verlangsamt jedoch die Gesamtgeschwindigkeit, da der Inhalt nicht an den Browser gesendet werden darf, sondern bereit ist, auf den Browser zu warten Vollständiges Dokument, das gerendert werden soll (für ob_end ()), bevor es von Ihnen verarbeitet und an den Browser gesendet werden kann.

3

Sie könnten versuchen, in der Datei wp-includes/formatting.php nachzuschlagen. Zum Beispiel die wpautop-Funktion . Wenn Sie etwas mit der gesamten Seite machen möchten, sehen Sie sich das Super Cache-Plugin an. Dadurch wird die letzte Webseite zum Caching in eine Datei geschrieben. Wenn Sie sehen, wie das Plug-In funktioniert, können Sie einige Ideen haben.

3
Brent Baisley

Ich habe die Top-Lösung dieses Beitrags (von Kfriend) für eine Weile verwendet. Es verwendet einen mu-plugin, um die gesamte Ausgabe zu puffern. 

Diese Lösung bricht jedoch das Zwischenspeichern von wp-super-cache und beim Hochladen des mu-plugin werden keine Supercache-Dateien generiert.

Also: Wenn Sie wp-super-cache verwenden, können Sie den Filter dieses Plugins folgendermaßen verwenden:

add_filter('wp_cache_ob_callback_filter', function($buffer) {
    $buffer = str_replace('foo', 'bar', $buffer);
    return $buffer;
});
2
Arne L

Ich bin mit diesem Code auf Probleme gestoßen, da ich mit dem scheinbar ursprünglichen Quellcode der Seite ende, so dass einige Plugins keine Auswirkungen auf die Seite haben. Ich versuche, das jetzt zu lösen - ich habe nicht viele Informationen über bewährte Methoden zum Sammeln der Ausgabe von WordPress gefunden.

Update und Lösung:

Der Code von KFRIEND hat für mich nicht funktioniert, da dies unverarbeitete Quelle von WordPress erfasst, nicht die gleiche Ausgabe, die im Browser tatsächlich endet. Meine Lösung ist wahrscheinlich nicht elegant, wenn Sie eine globale Variable verwenden, um den Inhalt zwischenzuspeichern. Könnte sein, dass unterschiedliche Setups von Plugins Probleme bereiten, aber dank des obigen Codebeispiels von Jacer Omri bin ich damit fertig geworden.

Dieser Code befindet sich in meinem Fall normalerweise in functions.php im Designordner.

$GLOBALS['oldschool_buffer_variable'] = '';
function sc_callback($data){
    $GLOBALS['final_html'] .= $data;
    return $data;
}
function sc_buffer_start(){
    ob_start('sc_callback');
}
function sc_buffer_end(){
    // Nothing makes a difference in my setup here, ob_get_flush() ob_end_clean() or whatever
    // function I try - nothing happends they all result in empty string. Strange since the
    // different functions supposedly have very different behaviours. Im guessing there are 
    // buffering all over the place from different plugins and such - which makes it so 
    // unpredictable. But that's why we can do it oldschool :D
    ob_end_flush();

    // Your final HTML is here, Yeeha!
    $output = $GLOBALS['oldschool_buffer_variable'];
}
add_action('wp_loaded', 'sc_buffer_start');
add_action('shutdown', 'sc_buffer_end');
1
Kim Steinhaug

Geändert https://stackoverflow.com/users/419673/kfriend answer.

Der gesamte Code wird auf functions.php sein. Mit dem HTML-Filter "final_output" können Sie alles tun, was Sie möchten.

Auf der "functions.php" Ihres Themes

//we use 'init' action to use ob_start()
add_action( 'init', 'process_post' );

function process_post() {
     ob_start();
}


add_action('shutdown', function() {
    $final = '';

    // We'll need to get the number of ob levels we're in, so that we can iterate over each, collecting
    // that buffer's output into the final output.
    $levels = ob_get_level();

    for ($i = 0; $i < $levels; $i++) {
        $final .= ob_get_clean();
    }

    // Apply any filters to the final output
    echo apply_filters('final_output', $final);
}, 0);

add_filter('final_output', function($output) {
    //this is where changes should be made
    return str_replace('foo', 'bar', $output); 
});
1
okto

Versuchen Sie es zuerst mit JavaScript zu lösen, bevor Sie Ausgabepuffer verwenden.

Angenommen, Sie möchten beim Laden von Iframes einen Spinner hinzufügen, beispielsweise:

(function ($) {

    $(document).ready(function () {
        showSpinnerWhileIFrameLoads();
    });

    function showSpinnerWhileIFrameLoads() {
        var iframe = $('iframe');
        if (iframe.length) {
            $(iframe).before('<div id=\'spinner\'><i class=\'fa fa-spinner fa-spin fa-3x fa-fw\'></i></div>');
            $(iframe).on('load', function() {
                document.getElementById('spinner').style.display='none';
            });
        }
    }

})(jQuery);

Passen Sie diese Idee an Ihre Bedürfnisse an. Normalerweise sollten Sie die HTML-Ausgabe mit JavaScript bearbeiten können, ohne Ausgabepuffer verwenden zu müssen, die beispielsweise den Cache beschädigen können.

0