Block mit Cachable = false wird auf der Produktansichtsseite nicht angezeigt

21

Ich benutze magento2-1.0.0-beta4

Ich habe den checkout.rootBlock von app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xmlauf die Produktseite kopiert .

Alles funktioniert einwandfrei, bis ich den aktiviere page_cache. Dieser Block ist cacheable="false"in der Layout-XML enthalten.

Wenn ich jetzt meine Produktseite öffne, wird der Block überhaupt nicht gerendert.

Wenn ich den Seiten-Cache richtig verstanden habe, sollte er solche Blöcke über einen AJAX-Aufruf laden. Es scheint jedoch nicht so einen AJAX-Aufruf zu geben, dass mein Breakpoint-In \Magento\PageCache\Controller\Block\Render::executenie erreicht wird.

Beim öffnen /checkout/oder /checkout/cart/alles klappt. Es scheint aber auch kein AJAX-Aufruf zu passieren. Stattdessen scheint die ganze Seite nicht aus dem Cache gerendert zu werden, was für den Warenkorb Sinn macht.

Soll ich die Produktansichtsseite einfach von der Liste ausschließen page_cache? Aber ich habe keinen Weg gefunden, dies zu tun?

Alex
quelle

Antworten:

15

Dieses Problem ist in Magento 2.0.0 Stable immer noch reproduzierbar.

In der Ausnahmebehandlung von Magento 2 gibt es eine Funktion, die das Rendern beschädigter Blöcke verhindert, während alle anderen Blöcke gerendert werden. Im Entwicklermodus ist es deaktiviert und alle Ausnahmen werden direkt im Browser angezeigt. Wenn im Standard- und Produktionsmodus beim Rendern von Blöcken eine Ausnahme auftritt, wird der Block nur aus der Ausgabe entfernt (die entsprechende Ausnahme wird weiterhin in var / log / system.log protokolliert ). Sehen \Magento\Framework\View\Layout::renderNonCachedElement().

Nach Ausnahme tritt bei der Kasse Block - Rendering auf der Produktseite und das ist , warum dieser Block fehlt: main.CRITICAL: No such entity with customerId = [] [].

Der Grund für diese Ausnahme ist, dass die Kundendaten im Sitzungsspeicher customerLoggedIn == truenach der \Magento\PageCache\Model\Layout\DepersonalizePlugin::afterGenerateXml()Ausführung inkonsistent sind ( und Kundendaten fehlen) . Dieses Plugin schließt die aktuelle PHP-Sitzung und entfernt somit Kundendaten aus dem Sitzungsspeicher. Dies geschieht nur, wenn die Seite vollständig zwischengespeichert werden kann (und tatsächlich ist).

Die Seite kann vom Seiten-Cache-Modul nur dann zwischengespeichert werden, wenn ihr Layout keine Blöcke mit enthält cacheable="false". Durch Hinzufügen dieses Attributs wird dieser Block nicht von Ajax geladen (wie in der Frage angenommen). Damit ein Block von Ajax geladen wird, sollte dieser Block eine deklarierte Eigenschaft haben, _isScopePrivatedie auf gesetzt trueist. Außerdem sollte cacheable="false"die Seite keine Blöcke mit enthalten . Siehe \Magento\PageCache\Observer\ProcessLayoutRenderElement::execute()und mage.pageCache._replacePlaceholder()in Magento / PageCache / view / frontend / web / js / page-cache.js . Überprüfen Sie auch die allgemeinen Dokumente in der Readme -Datei des Seiten-Cache-Moduls

Die Produktseite sollte nicht zwischenspeicherbar sein, da sie cacheable="false"für den Checkout-Block festgelegt ist. Dies ist jedoch auf ein bekanntes Problem zurückzuführen, das darin besteht, dass nicht zwischenspeicherbare Blöcke zwischengespeichert werden . Bis dieses Problem behoben ist, kann die folgende Problemumgehung verwendet werden (fragen Sie mich nicht, warum es funktioniert, es ist eine lange Geschichte):

  1. Gehe zu \Magento\Framework\Pricing\Render\Layout::__construct
  2. Wechseln Sie ['cacheable' => $generalLayout->isCacheable()]zu['cacheable' => false]

Dies sollte nicht schaden, da Produktseiten nach dem Hinzufügen des Checkout-Blocks ohnehin nicht zwischengespeichert werden

Eine andere Frage ist, ob Sie Produktseiten wirklich durch den eingebauten Seiten-Cache oder den Lack nicht zwischenspeicherbar machen möchten.

Alex Paliarush
quelle
1
Gibt es Updates für dieses Problem in der neuesten Magento2-Version? @ Alex
Keyur Shah
Alex, ich möchte nur einen phtml aus dem Cache entfernen. und diese HTML-Datei in Header-Container aufrufen. Jede Idee, lass es mich wissen
Camit1dk