Puncte:1

Render view inside block with caching

drapel lc

My setup is a bit unconventional. I have a view displaying a block, relying on a contextual filter (let's call it product ID). I also have a custom block that renders this view programmatically because I need to include this block in multiple places on the page and I have some custom logic that pulls the actual product ID to call the view with. Basically:

$view = Views::getView('view_id'); 
$args = ['product_id' => $whatever_product];
return $view->buildRenderable('views_block_id', $args);

The process basically works but, as usual, I'll have problems when there are several such blocks on the page. Views only caches using the block id as a cache tag, so the first rendered view gets cached and displayed in all places. Naturally, switching off the cache would work:

return $view->buildRenderable('views_block_id', $args, FALSE);

but not exactly what I have in mind, I don't want to lose the benefits of caching.

My initial thought was quite simple, let's use custom cache tags in the view, thanks to views_custom_cache_tag. So I did, including the argument from the contextual filter:

views_block:view_id-views_block_id
custom:{{ arguments.product_id }}

But it still doesn't work.

Is there any other way I missed? I can't push new cache tags right before I try to render the view. The usual view hooks don't get called in this case (the second block already gets the cached variant, without even bothering to go near the hooks).

4uk4 avatar
drapel cn
*Desigur, dezactivarea memoriei cache ar funcționa* `return $view->buildRenderable('views_block_id', $args, FALSE);`. Dacă funcționează, atunci folosește-l. Nu trebuie să memorați în cache rezultatul redat al Vizualizării atunci când vă aflați într-un bloc care este stocat în cache singur.
drapel lc
Dacă am același bloc de două ori pe pagina care se întâmplă să se refere la un alt produs, ei bine, nu voi fi foarte fericit dacă blocul se păstrează în cache cu unul dintre ele. :-) Dacă mă gândesc bine, dacă blocul se păstrează în cache cu propriul ID de instanță adăugat, nu doar cu cel generic...
drapel lc
OK, mulțumesc, dacă copiați același lucru într-un răspuns, aș fi bucuros să îl accept.
Puncte:2
drapel cn

Într-un bloc, puteți dezactiva stocarea în cache a vizualizării redate în ViewExecutable::buildRenderable:

$view->buildRenderable('views_block_id', $args, FALSE)

deoarece rezultatul redat al fiecărei instanțe de bloc este deja stocat în cache.

Apropo, etichetele cache nu sunt implicate atunci când stocarea în cache a variantelor aceluiași element.Acest lucru este controlat doar de cheile și contextele cache. Cu cache=FALSE dezactivați cheile cache, dar nu contextele, care ar trebui să urce în continuare până la nivelul blocului. Dacă lipsește un context, puteți seta manual un context cache, de exemplu pentru rută sau arg de interogare a căii URL dacă ID-ul produsului depinde de acesta.

Editare: am eliminat instrucțiunea return, deoarece ar putea fi necesar să construim o matrice de randare reală cu vizualizarea încorporată.

drapel lc
În acest caz particular, funcționează OK cu returnarea, aceasta este deja ultima linie a funcției `build()`. Mulțumiri.
steve avatar
drapel in
Am ceea ce _cred_ că este o configurație similară, cu excepția faptului că ar trebui să adaug că singurul meu bloc personalizat poate afișa unul _sau mai multe_ blocuri de vizualizare. Vederile sunt referite dintr-un câmp de vizualizare cu mai multe valori de pe nod și, în unele cazuri, aceeași vizualizare este referită cu un afișaj și argumente diferite. În aceste cazuri în care aceeași vizualizare este referită de mai multe ori, numai primul afișaj este folosit pentru toate, iar adăugarea argumentului `FALSE` la metoda `buildRenderable` nu rezolvă această problemă.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.