Bagaimana saya bisa mengontrol visibilitas blok dengan kode?

11

Di Drupal 6, saya bisa mengontrol visibilitas blok menggunakan kode PHP dalam konfigurasi UI blok seperti:

<?php return MYMODULE_abc() || MYMODULE_def() ; ?>

Fungsi-fungsi ini mencari node saat ini, taksonomi, dll untuk memutuskan apakah akan menampilkan blok. Opsi PHP ini hilang dalam Drupal 8, tetapi ada $visibilitybidang di BlockBase. Bisakah saya menggunakan ini untuk secara terprogram mengatur visibilitas saat runtime?

Nic
sumber
1
Anda harus mendeklarasikan plugin kondisi khusus sebagai gantinya. Cari inti untuk @Condition untuk menemukan contoh yang berfungsi.
Eyal
Secara umum, menulis kode PHP ke dalam basis data adalah praktik yang buruk dan sebisa mungkin dihindari.
Eyal
Modul filter php telah dihapus dari D8. Secara umum itu adalah ide yang buruk untuk menggunakan php yang dimasukkan di UI dan dieksekusi dengan cara ini. Itu adalah ide yang buruk karena melewatkan; bisa melumpuhkan seluruh situs dan kemudian saya akan disewa untuk mencari db untuk menemukan yang hilang; Ini telah terjadi,
Frank Robert Anderson
Sepakat! Dipindahkan kode sebanyak yang saya bisa ke dalam modul, dan senang bahwa saya bisa melakukan ini dengan kode murni di D8!
Nic

Jawaban:

15

Cuplikan kode yang berfungsi bagaimana cara menggunakan hook_block_access(). Di sini saya mengambil kondisi dari bidang node saat ini:

use Drupal\block\Entity\Block;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Drupal\Core\Access\AccessResult;

/**
 * Implements hook_block_access().
 */
function MYMODULE_block_access(Block $block, $operation, AccountInterface $account) {

  $node = \Drupal::routeMatch()->getParameter('node');

  $hero_image_exists = FALSE;

  if ($node instanceof NodeInterface) {
    if ($node->hasField('field_hero_image')) {
      if (!$node->get('field_hero_image')->isEmpty()) {
        $hero_image_exists = TRUE;
      }
    }
  }

  if ($operation == 'view' && $block->getPluginId() == 'MYBLOCK') {
    return AccessResult::forbiddenIf($hero_image_exists == FALSE)->addCacheableDependency($block);
  }

  return AccessResult::neutral();
}

Terima kasih @Insasse untuk berbagi permata berikut di komentar. Untuk blok khusus yang dibuat secara program Anda dapat mengontrol visibilitas langsung dari dalam kelas blok melalui blockAccess():

class MyBlock extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() {
    return [
      '#markup' => $this->t('This is a simple block!'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  protected function blockAccess(AccountInterface $account) {
    return AccessResult::allowedIfHasPermission($account, 'access content');
  }

}

Sumber: Cara Membuat Program secara Blok di Drupal 8

leymannx
sumber
1
Anda bahkan dapat menulis cek akses di kelas blok Anda -> webwash.net/programmatically-create-block-drupal-8
Insasse
7

Kurangnya filter php di Drupal 8, ini tidak akan lagi dimungkinkan dari UI.

Satu-satunya pilihan adalah menggunakan api blok.

hook_block_access adalah canidate terbaik Anda. Dari sana Anda dapat memeriksa $operationdan mengembalikan AccessResult berdasarkan kondisi Anda.

Sama seperti di UI hanya kali ini menempatkan php ke dalam modul.

Frank Robert Anderson
sumber
4

Berikut ini solusi Drupal 8: Blokir Halaman yang Dikecualikan .

Modul ini menambahkan filter halaman kecualikan untuk blok.

Untuk mengecualikan halaman tertentu setelah wildcard atau di antara wildcard, cukup awali pola jalur dengan awalan '!' dalam konfigurasi visibilitas halaman blok.

Ini berfungsi untuk visibilitas yang diatur ke "tampilkan untuk halaman yang terdaftar", dalam hal ini, jalur kecualikan akan menyembunyikan blok pada halaman yang cocok dengan meskipun wildcard diatur untuk ditampilkan.

Atau sebaliknya, jika daftar halaman diatur ke "sembunyikan untuk halaman yang terdaftar" jalur yang dikecualikan akan menunjukkan blok pada halaman di mana pola cocok meskipun wild card diatur untuk disembunyikan.

Block Exclude Pages screenshot

Juyal Jee
sumber
1

untuk memperluas kemungkinan visibilitas blok Anda dapat mencoba tambalan ini:

https://www.drupal.org/project/drupal/issues/923934#comment-12401360

itu memperkenalkan operator konjungsi AND / OR untuk kondisi visibilitas sehingga Anda dapat mengatakan oh saya ingin blok ini terlihat jika itu dari my_content_type ATAU pengguna memiliki peran admin ATAU url dimulai dengan / path / ke / * dll. juga kondisinya dapat dinegasi sehingga Anda dapat mengatur banyak kondisi di mana Anda tidak ingin blok Anda terlihat

juga jika Anda menggunakan modul Drupal Commerce, Anda dapat mencoba yang di atas dengan menginstal https://www.drupal.org/project/commerce_quick_purchase modul. Perhatikan bahwa saat dipasang, modul ini mengekspos fungsi ini untuk semua blok pada sistem walaupun Anda tidak t gunakan blok yang disediakan oleh modul, lihat lebih lanjut

https://github.com/drugan/commerce_quick_purchase#block-visibility

selain itu Anda dapat membuat plugin kondisi Anda sendiri lihat contoh dari modul

https://cgit.drupalcode.org/commerce_quick_purchase/tree/src/Plugin/Condition

obat-obatan
sumber