Saya telah mengalami masalah di mana blok yang seharusnya unik per halaman bukan untuk pengguna yang keluar. Masalahnya adalah plugin blok khusus yang saya miliki pada halaman pencarian tampilan yang berisi filter khusus (semacam pengganti kustom untuk filter terbuka. Blok ditempatkan melalui / admin / struktur / blok).
Berdasarkan apa yang telah saya pelajari tentang Drupal 8, saya menambahkan konteks cache ke array build saya:
public function build() {
$search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
return [
'search_form' => $search_form,
'#cache' => ['contexts' => ['url.path', 'url.query_args']]
];
}
Tapi sepertinya ini pasti salah karena ketika keluar, blok akan di-cache pada tampilan pertama, dan ketika url berubah, itu tidak menunjukkan versi baru dari blok.
Saya pikir itu mungkin halaman tampilan yang menyebabkan masalah, tetapi bahkan ketika saya mematikan caching pada halaman tampilan, masalah tetap ada.
Saya dapat memperbaiki masalah ini beberapa cara, misalnya, dengan menggunakan kait preprocess_block:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Tapi itu mengganggu saya, saya tidak bisa begitu saja memasukkan konteks cache ke dalam array build blok saya.
Karena blok saya memperluas BlockBase, saya memutuskan untuk mencoba metode getCacheContexts (), terutama karena saya melihat beberapa modul di dalam core melakukannya dengan cara ini.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
Ini juga memperbaiki masalah, tetapi yang menarik, ketika saya menampilkan variabel dalam fungsi blok preproses, ini tidak ditampilkan dalam $ variabel ['# cache'] ['konteks'], tetapi mereka ditampilkan dalam elemen $ variabel [' '] [' # cache '] [' contexts ']
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
Saya mencoba mencari tahu bagaimana ini bekerja, dan mengapa itu tidak berfungsi dari fungsi build.
Melihat /core/modules/block/src/BlockViewBuilder.php pada fungsi viewMultiple (), sepertinya ia menarik tag cache dari entitas dan plugin:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
Jadi itu menjelaskan mengapa menambahkan metode getCacheContexts () ke plugin blok saya menambahkan konteks ke blok saya. Juga, melihat metode preRender di kelas yang sama, sepertinya itu tidak menggunakan array cache di fungsi blok bangunan, yang membingungkan saya, karena tampaknya cara untuk menambahkan caching di Drupal 8 adalah menambahkan #cache elemen untuk membuat elemen.
Jadi pertanyaan saya adalah,
1) Apakah konteks cache ditambahkan langsung pada array di plugin blok diabaikan?
2) Jika demikian, apakah ada cara lain, apakah kita perlu menambahkannya ke elemen turunan build?
3) Jika konteks yang ditambahkan secara langsung diabaikan, apakah menambahkan getCacheContexts () cara untuk mencari plugin blok dalam modul khusus?