WooCommerce Produkttabelle: Mini-Warenkorb aktualisiert sich nicht
Wenn sich der WooCommerce-Mini-Warenkorb nach „In den Warenkorb“ in einer Produkttabelle nicht aktualisiert, ist das ein Anzeigeproblem und kein Warenkorbproblem. Die Tabelle zeigt Produkt zum Warenkorb hinzugefügt (Product added to cart!), die Warenkorbseite listet das Produkt auf, aber der Zähler im Header, der Mini-Warenkorb des Themes oder der Side-Cart zeigt bis zum Neuladen der Seite noch den alten Stand. Das Produkt liegt im Warenkorb; der Warenkorb des Themes hat es nur nicht mitbekommen. Im Folgenden lesen Sie, was die Tabelle beim Hinzufügen eines Produkts tut, wie Sie in wenigen Minuten herausfinden, warum Ihr Warenkorb nicht reagiert, und mit welchem Footer-Skript er sich aktualisiert und Side-Carts so öffnet wie die eigenen Buttons von WooCommerce.
Was beim Hinzufügen eines Produkts aus der Tabelle passiert
Der Button In den Warenkorb (Add to cart) der Tabelle nutzt den eigenen Endpunkt von WooCommerce, denselben wie die AJAX-Buttons auf der Shop-Seite:
- Der Browser sendet eine POST-Anfrage an
?wc-ajax=add_to_cartmit der Produkt-ID und der Menge. WooCommerce legt das Produkt in den Warenkorb und antwortet mit aktuellen Warenkorb-Fragmenten: HTML-Teilen für jedes Warenkorb-Element auf der Seite, geordnet nach ihrem CSS-Selektor, plus einemcart_hash. - Die Tabelle zeigt ihre Meldung an und löst das JavaScript-Ereignis
woot-added-to-cartaufdocumentaus. - Sie lädt ihre eigenen Warenkorbinformationen neu (das Warenkorb-Panel der Tabelle, die Zähler an den Buttons) und löst
woot-woo-cart-refreshedaus. - Sie löst das WooCommerce-Ereignis
wc_fragment_refreshaus. Das veranlasst das Cart-Fragments-Skript von WooCommerce, die Fragmente erneut abzurufen und die Warenkorb-Elemente auf der Seite zu ersetzen.
Der Button Ausgewählte hinzufügen (add selected) im Spaltenkopf legt alle markierten Produkte mit einer einzigen Anfrage an admin-ajax.php in den Warenkorb und führt danach die Schritte 3 und 4 aus.
Der Unterschied zu den Buttons auf der Shop-Seite liegt im letzten Schritt. Diese Buttons nehmen die Fragmente aus der Antwort, ersetzen die Warenkorb-Elemente direkt und melden den Kauf mit dem Standardereignis added_to_cart von WooCommerce, auf das Side-Cart-Plugins und der Mini-Cart-Block von WooCommerce lauschen. Die Tabelle verlässt sich stattdessen auf wc_fragment_refresh, und dieses Ereignis bewirkt nur dann etwas, wenn das Cart-Fragments-Skript (wc-cart-fragments) auf der Seite geladen ist. Aktuelle WooCommerce-Versionen laden dieses Skript nur dort, wo es gebraucht wird, etwa beim klassischen Warenkorb-Widget; viele Themes mit eigenem Header-Warenkorb laden es selbst, manche nicht. Der Mini-Warenkorb bleibt daher in vier Fällen unverändert:
- der Warenkorb des Themes wird über Fragmente aktualisiert, aber das Cart-Fragments-Skript ist auf der Tabellenseite nicht geladen;
- der Side-Cart oder Mini-Warenkorb reagiert nur auf
added_to_cart: Er öffnet und aktualisiert sich nach einem Shop-Button, nie aber nach der Tabelle; - der Zähler des Themes ist gar kein Fragment, sodass ihn nur ein Neuladen der Seite ändert;
- ein Seiten-Cache liefert HTML mit einem alten Warenkorb aus, sodass selbst nach dem Neuladen noch die alte Anzahl erscheint.
Die Ursache in fünf Minuten finden
Öffnen Sie die Seite mit der Tabelle in einem privaten Fenster, in dem Sie abgemeldet sind, und öffnen Sie die Entwicklertools (F12 oder auf dem Mac Cmd+Option+I).
- Network. Legen Sie ein Produkt aus der Tabelle in den Warenkorb und klicken Sie auf die Anfrage
?wc-ajax=add_to_cart. Enthält ihre Antwort"error":true, wurde das Produkt nicht hinzugefügt, und das Problem liegt beim Produkt (Lagerbestand, Mengenbegrenzungen), nicht beim Mini-Warenkorb. Andernfalls klappen Siefragmentsauf: Seine Schlüssel, etwadiv.widget_shopping_cart_content, sind die Warenkorb-Elemente, die WooCommerce und Ihr Theme aktualisieren können. - Ihr Warenkorb-Element. Klicken Sie mit der rechten Maustaste auf den Header-Zähler oder den Mini-Warenkorb, wählen Sie Untersuchen (Inspect) und vergleichen Sie Tag und Klasse mit diesen Schlüsseln. Passt nichts, ist das Element kein Fragment: Siehe dazu den Abschnitt zum PHP-Filter weiter unten.
- Console. Geben Sie
typeof wc_cart_fragments_paramsein und drücken Sie die Eingabetaste."undefined"bedeutet, dass das Cart-Fragments-Skript nicht auf der Seite ist, sodasswc_fragment_refreshnichts bewirkt. - Mit dem Shop vergleichen. Legen Sie auf der Shop-Seite ein Produkt mit dem eigenen Button von WooCommerce in den Warenkorb. Aktualisiert sich dort der Mini-Warenkorb oder öffnet sich der Side-Cart, nach der Tabelle aber nicht, lauscht Ihr Warenkorb auf
added_to_cart, das das Footer-Skript unten liefert. - Neu laden. Ist der Zähler nach dem Neuladen immer noch falsch, während die Warenkorbseite das Produkt zeigt, stammt die Seite aus einem Cache; siehe den Abschnitt zum Caching.
Den Mini-Warenkorb aktualisieren und den Side-Cart aus der Tabelle öffnen
Dieses Skript tut, was die Buttons auf der Shop-Seite tun. Sobald der Warenkorb der Tabelle aktualisiert wurde, ruft es die Fragmente von WooCommerce ab und ersetzt die Warenkorb-Elemente auf der Seite, ist also nicht vom Cart-Fragments-Skript abhängig. Nach einem Klick auf In den Warenkorb (Add to cart) oder Ausgewählte hinzufügen (add selected) löst es außerdem added_to_cart mit den echten Fragmenten aus, sodass sich Side-Carts und der Mini-Cart-Block wie konfiguriert aktualisieren und öffnen.
/*
* Products tables: update the theme mini cart and side cart after products are
* added from a table. Add it to the site footer: a JavaScript snippet in a code
* snippets plugin, or the footer scripts field of your theme.
*/
(function ($) {
var announce = false;
function fragmentsUrl() {
if (typeof wc_add_to_cart_params !== 'undefined') {
return wc_add_to_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'get_refreshed_fragments');
}
return '?wc-ajax=get_refreshed_fragments';
}
// One product added with a table's Add to cart button
document.addEventListener('woot-added-to-cart', function () {
announce = true;
});
// Several products added with the "add selected" button
document.addEventListener('click', function (e) {
var button = e.target.closest('.woot-add-to-cart-all-btn');
var table = button ? button.closest('table') : null;
if (table && table.querySelector('.woot-add-to-cart-check:checked')) {
announce = true;
}
}, true);
// The table cart was refreshed: on page load, after adding, removing or changing quantities
document.addEventListener('woot-woo-cart-refreshed', function () {
var opened = announce;
announce = false;
$.post(fragmentsUrl(), function (data) {
if (!data || !data.fragments) {
return;
}
$.each(data.fragments, function (selector, html) {
$(selector).replaceWith(html);
});
$(document.body).trigger('wc_fragments_refreshed');
if (opened) {
$(document.body).trigger('added_to_cart', [data.fragments, data.cart_hash, $()]);
}
});
});
})(jQuery);
So verhält es sich:
- Die Warenkorb-Elemente werden bei jeder Änderung über die Tabelle aktualisiert, einschließlich Entfernen und Mengenänderungen im Warenkorb-Popup der Tabelle. Das Ereignis
added_to_cart, und damit ein sich öffnender Side-Cart, folgt nur nach dem Hinzufügen von Produkten. - Der Warenkorb der Tabelle wird beim Laden der Seite außerdem einmal aktualisiert, daher stellt das Skript pro Seite mit Tabelle eine zusätzliche Fragment-Anfrage. So bleibt der Mini-Warenkorb auch auf Seiten korrekt, die aus einem Cache kommen.
- Manche Side-Carts öffnen sich nur über ihre eigene Funktion, nicht über
added_to_cart. Bleibt Ihrer geschlossen, während sich sein Inhalt aktualisiert, rufen Sie diese Funktion innerhalb des Blocksif (opened)auf; ihren Namen verraten die Dokumentation des Side-Carts oder sein Entwickler.
Wenn Sie den Kunden lieber zum Warenkorb weiterleiten möchten: Im Tab Optionen (Options) der Tabelle gibt es Aktion nach dem Hinzufügen zum Warenkorb (After to cart adding) mit Zur Warenkorbseite weiterleiten (Redirect to the cart page) und Zur Kassenseite weiterleiten (Redirect to the checkout page). Die Tabelle kann auch einen eigenen Warenkorb anzeigen, der immer synchron bleibt: Aktivieren Sie im selben Tab Shop-Warenkorb anzeigen (Show shop cart) oder platzieren Sie [woot_cart] an beliebiger Stelle auf der Seite.
Wenn der Warenkorb-Zähler des Themes kein Fragment ist
Ein Zähler, der nicht in der Liste fragments steht, lässt sich mit keinem Skript aktualisieren, denn WooCommerce sendet dafür nie neues HTML. Registrieren Sie ihn mit dem WooCommerce-Filter woocommerce_add_to_cart_fragments. Ersetzen Sie span.my-cart-count durch Tag und Klasse des Zählers Ihres Themes und behalten Sie dieselbe Klasse im zurückgegebenen HTML bei, damit sich das Element beim nächsten Mal wiederfinden lässt:
/*
* Make the theme's cart counter a WooCommerce fragment, so it is refreshed
* after AJAX add to cart. Child theme functions.php or a code snippets plugin.
*/
add_filter('woocommerce_add_to_cart_fragments', function ($fragments) {
$fragments['span.my-cart-count'] = '<span class="my-cart-count">'
. esc_html(WC()->cart->get_cart_contents_count())
. '</span>';
return $fragments;
});
Das hilft den Buttons auf der Shop-Seite genauso wie der Tabelle. Themes und Page Builder mit einem komplexen Mini-Warenkorb registrieren ihn meist bereits; fehlt Ihrer in der Liste, fragen Sie den Theme-Entwickler, welches Element zu verwenden ist.
Seiten-Caching und Skript-Optimierung
Ein Seiten-Cache speichert das HTML einer Seite, einschließlich des Header-Warenkorbs. Gibt das Theme seinen Warenkorb ins HTML aus und der Cache liefert weiter die Version für einen leeren Warenkorb aus, ist der Zähler nach jedem Neuladen falsch, während die Warenkorbseite, die Caching-Plugins standardmäßig ausschließen, stimmt. Zwei Maßnahmen beheben das, und Caches für WooCommerce-Shops brauchen beide:
- Liefern Sie Besuchern mit Artikeln im Warenkorb keine gecachten Seiten aus. WooCommerce setzt für sie die Cookies
woocommerce_items_in_cartundwoocommerce_cart_hash; die meisten Caching-Plugins und Hoster können den Cache umgehen, wenn diese vorhanden sind. Welche Seiten und Cookies auszuschließen sind, führt WooCommerce unter Configuring caching plugins auf. - Cachen Sie niemals die Anfragen
?wc-ajax=oderadmin-ajax.php. Eine gecachte Fragment-Antwort legt auf der Seite jedes Besuchers denselben Warenkorb ab.
Optimierungsfunktionen, die JavaScript verzögern, aufschieben oder zusammenfassen, können die obige Kette ebenfalls unterbrechen: Laufen das Warenkorb-Skript des Themes oder die Warenkorb-Skripte von WooCommerce zu spät oder gar nicht, aktualisiert nichts den Warenkorb. Schließen Sie jQuery, die Skripte add-to-cart und cart-fragments von WooCommerce, das Warenkorb-Skript Ihres Themes und den Ordner /wp-content/plugins/profit-products-tables-for-woocommerce/ aus und leeren Sie danach alle Caches. Behebt das Deaktivieren des Caching- oder Optimierungs-Plugins (WP Rocket oder ein ähnliches) den Mini-Warenkorb, gehen Sie dessen Cache- und JavaScript-Optionen einzeln durch, um die verantwortliche Einstellung zu finden, statt das Plugin ausgeschaltet zu lassen.
Checkliste
- Die Anfrage
?wc-ajax=add_to_cartantwortet mitfragments, nicht mit"error":true. - Ihr Header-Warenkorb oder -Zähler entspricht einem der Fragment-Schlüssel oder ist mit
woocommerce_add_to_cart_fragmentsregistriert. - Das Footer-Skript ist auf der Seite mit der Tabelle eingebunden, und die Browser-Konsole zeigt keine Fehler.
- Seiten werden Besuchern mit Artikeln im Warenkorb nicht aus dem Cache ausgeliefert;
wc-ajax-Anfragen werden nie gecacht. - Die Warenkorb-Skripte von WooCommerce, das Warenkorb-Skript des Themes und der Plugin-Ordner sind von Verzögern, Aufschieben und Zusammenfassen von JavaScript ausgenommen.
Aktualisiert sich der Warenkorb trotzdem nicht, eröffnen Sie im WOOT-Support-Forum ein Thema mit dem Link zur Seite, dem Namen Ihres Themes oder Side-Cart-Plugins und den Fragment-Schlüsseln aus der Antwort auf add_to_cart, dann sehen wir es uns an.