Sayfa başına benzersiz olması gereken bir bloğun oturumu kapatılmış kullanıcılar için olmadığı bir sorunla karşılaştım. Sorun özel filtreler (bir tür maruz kalan filtreler için özel bir yedek gibi. / Admin / structure / block yerleştirilen blok) içeren bir görünüm arama sayfasında sahip özel bir blok eklentisidir.
Drupal 8 hakkında öğrendiklerime dayanarak, önbellek bağlamlarını derleme dizime ekledim:
public function build() {
$search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
return [
'search_form' => $search_form,
'#cache' => ['contexts' => ['url.path', 'url.query_args']]
];
}
Ancak bu yanlış görünüyor gibi görünüyor, çünkü oturumu kapattığında, blok ilk görünümde önbelleğe alınacak ve url değiştiğinde, bloğun yeni bir sürümünü göstermiyordu.
Soruna neden olan görünüm sayfası olabileceğini düşündüm, ancak görünüm sayfasında önbelleğe almayı kapattığımda bile sorun devam etti.
Örneğin, bir preprocess_block kanca kullanarak sorunu çeşitli şekillerde düzeltmek başardı:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Ama beni rahatsız etti, sadece önbellek bağlamlarını bloğumun inşa dizisine koyamadım.
Bloğum BlockBase'i genişlettiğinden, özellikle çekirdek içindeki bazı modüllerin bu şekilde yapıldığını gördüğüm için getCacheContexts () yöntemini denemeye karar verdim.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
Bu da sorunu düzeltti, ancak ilginç bir şekilde, önişlem bloğu işlevindeki değişkenleri çıkardığımda, bunlar $ değişkenlerde ['# cache'] ['bağlamlar'] göstermiyorlar, ancak $ değişkenleri ['öğelerinde gösteriliyorlar '] [' # cache '] [' bağlamları]
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
Bunun nasıl çalıştığını ve neden yapı işlevinden çalışmadığını anlamaya çalışıyorum.
ViewMultiple () işlevinde /core/modules/block/src/BlockViewBuilder.php dosyasına bakıldığında, önbellek etiketlerini varlıktan ve eklentiden alıyor gibi görünüyor:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
Bu, blok eklentime neden getCacheContexts () yöntemi eklenmesinin bağlamları bloğuma eklediğini açıklıyor. Ayrıca, aynı sınıftaki preRender yöntemine bakıldığında, Drupal 8'de önbellek eklemenin bir #cache eklemesi gibi göründüğü için beni şaşırtan blok oluşturma işlevinde önbellek dizisini kullanmıyor gibi görünüyor öğeleri oluşturmak için öğe.
Benim sorum şu,
1) Önbellek bağlamları bir blok eklentisindeki doğrudan diziye eklenir mi?
2) Öyleyse, bunun bir yolu var mı, bunu yapı dizisinin alt öğesine eklememiz gerekiyor mu?
3) Doğrudan eklenen bağlam göz ardı edilirse, getCacheContexts () eklenmesi, özel modüllerde blok eklentilerine gitmenin yolu mudur?