Wie platziere ich programmgesteuert einen Block?

10

Über die Benutzeroberfläche können Sie einen Block in einer Region folgendermaßen hinzufügen:

  1. Gehen Sie zu Admin -> Struktur -> Blocklayout (/ admin / Struktur / Block).
  2. Klicken Sie neben dem Regionsnamen auf die Schaltfläche "Block platzieren".

Ich möchte das Gleiche tun, aber programmatisch. Wie füge ich einer Region einen vorhandenen Block hinzu und speichere ihn? Dieser Block sollte dann in dieser Region angezeigt werden und auf der Seite Blocklayout verfügbar sein .

user3554770
quelle
Nach dem Erstellen des Blocks können Sie die Position des Blocks neu ordnen von: Site-Name / Admin / Struktur / Block
Crazyrubixfan
Ich gehe davon aus, dass Sie "einer Region einen Block zuweisen" falsch eingegeben haben.
Cilefen
@IcecreamJelly Was ich versuche zu tun, ist dies programmgesteuert zu tun. Cilefen, ja, das ist es, was ich meine% -)
jmzea
@ShawnConn danke, das ist ähnlich, aber nicht genau das gleiche. Ich habe die Antwort woanders gefunden.
jmzea

Antworten:

9

Um einen Plugin-Block bereitzustellen , können Sie ein Array von Einstellungen \Drupal\block\Entity\Block::create()erstellen und an übergeben , um das Block-Objekt zu erstellen und die Instanz zu speichern.

Wenn Sie beispielsweise dem Seven-Thema einen Devel Execute PHP- Block hinzufügen möchten :

$values = array(
  // A unique ID for the block instance.
  'id' => 'devel_execute_php_1',
  // The plugin block id as defined in the class.
  'plugin' => 'devel_execute_php',
  // The machine name of the theme region.
  'region' => 'content',
  'settings' => array(
    'label' => 'Execute PHP',
  ),
  // The machine name of the theme.  
  'theme' => 'seven',
  'visibility' => array(),
  'weight' => 100,
);
$block = \Drupal\block\Entity\Block::create($values);
$block->save();
Shawn Conn
quelle
Hallo, ich brauche Hilfe. Ich habe einen benutzerdefinierten Block mithilfe der Benutzeroberfläche erstellt und möchte ihn zu Testzwecken programmgesteuert in der Fußzeile platzieren. Ich weiß nicht, wie man Plugins von benutzerdefinierten Blöcken erhält, die von der Benutzeroberfläche erstellt wurden. Danke
Mudassar Ali
Stellen Sie dies als eine andere Frage. Kommentare sind nicht zum Stellen von Fragen gedacht.
Shawn Conn
es ist schon da. drupal.stackexchange.com/questions/207042/…
Mudassar Ali
Was ist die ID hier? ist es dasselbe wie der Blockname?
Crazyrubixfan
@RubberDuckIsKing Ich glaube, Sie können idalles benennen, was Sie wollen, solange es einzigartig ist. Zum Beispiel möchten Sie es vielleicht mit dem Namen des Moduls starten, in dem es sich befindet.
Parag
7

Sie können das Twig Tweak- Modul verwenden:

Das Twig Tweak-Modul bietet eine Twig-Erweiterung mit einigen nützlichen Funktionen und Filtern, die die Entwicklererfahrung verbessern können.

Und dann auf Ihrer Zweigvorlagenregion:

{{ drupal_block('block_id') }}
rpayanm
quelle
Das Problem bei dieser Lösung ist, dass Sie bei Twig Tweaks den Block immer noch platzieren und dann deaktivieren müssen.
Lexikant
6

Jede Instanz eines Blocks (welcher "Blocktyp", welche Konfiguration und welche Platzierung) ist eine Konfigurationsentität : \Drupal\block\Entity\Block. Sie müssen also nur eine neue Instanz dieser Entität mit den richtigen Details erstellen, und schon sind Sie fertig.

Dies kann getan werden, ist aber verrückt komplex. Sie müssten das Plugin-System, das Block-Plugin-System und vieles mehr verstehen.

Sie können einen Blick darauf werfen \Drupal\block\BlockForm::submitForm, um ein Gefühl dafür zu bekommen oder \Drupal\simpletest\BlockCreationTrait::placeBlock. Vielleicht möchten Sie darüber nachdenken, ob dies etwas ist, das Sie wirklich brauchen. Die Sichtbarkeit des Blocks ist ziemlich komplex.

googletorp
quelle
4
Abgesehen von den Sichtverhältnissen denke ich nicht, dass es so kompliziert ist. \ Drupal \ simpletest \ BlockCreationTrait :: placeBlock () ist wahrscheinlich ein besseres Beispiel. Sie können auch einfach einige exportierte Konfigurationsdateien importieren.
Berdir
@Berdir Danke für den Link zum Testmerkmal, fügte es hinzu. Da Drupal 8 noch so jung ist, wissen viele Leute nicht viel über das Plugin-System und die Dokumentation könnte mehr Anwendungsfälle usw. verwenden, was vielen Entwicklern Schwierigkeiten bereiten kann, damit zu arbeiten.
googletorp
Felix Eve hat die beste Antwort. Es ist kein verrückter Komplex.
Kratos
@kratos Die Antwort, die Felix gegeben hat, löst nicht die Frage, wie ein Block "programmgesteuert" platziert werden soll, sondern verwendet stattdessen Konfigurationsdateien. Die Konfiguration kann nur über Drush, Konfigurationssynchronisationsschnittstelle oder Modulinstallation importiert werden. Wenn es passieren muss, während der Laufzeit, nach dem Speichern eines Abschnitts-Frontpage-Knotentyps usw., wäre es nutzlos, diese Strategie zu verwenden :)
googletorp
4

Ich lerne gerade D8, aber ich habe anscheinend einen viel einfacheren Weg gefunden, einen Block programmgesteuert zu platzieren (es schien ziemlich einschüchternd, nachdem ich die Antwort von googletorp gelesen hatte!)

Als ich mein benutzerdefiniertes Modul aktivierte, das den Block definierte, wollte ich, dass der Block automatisch in der richtigen Region platziert wird. Schritte, die ich verwendet habe, um dies zu erreichen, sind:

  1. Aktivieren Sie das Modul und platzieren Sie den Block über die Benutzeroberfläche unter /admin/structure/block
  2. Wechseln Sie zur Exportseite für die Konfiguration einzelner Elemente unter admin/config/development/configuration/single/export
  3. Wählen Sie den Block Konfigurationstyp und als Konfigurationsname den Block, den Sie gerade über die Benutzeroberfläche platziert haben, und kopieren Sie den generierten Code.
  4. Erstellen Sie in Ihrem Modul den Ordner /config/install/
  5. Unter dem generierten Codetextbereich wird der Dateiname angezeigt, den Sie verwenden müssen. Erstellen Sie diese Datei im /config/installVerzeichnis und kopieren Sie den Code dort hinein.
  6. Wenn Sie nun Ihr Modul deinstallieren und dann wieder aktivieren, wird der Block automatisch platziert.
Felix Eve
quelle
Müssten Sie die UUID nicht entfernen, damit dies für andere Entwickler oder Umgebungen funktioniert?
powpow12
Ja - das Entfernen der UUID wäre eine gute Idee.
Felix Eve
Sie können auch die Drupal-Konsole verwenden, die sich um die Automatisierung einiger dieser Aufgaben kümmert
Beau
2

Das obige Beispiel ist nah genug, aber immer noch nicht korrekt. Die Idee ist, dass Sie Ihre eigene ID der Blockinstanz (in meinem Fall devel_execute_php_1112 (vielleicht weil ich versucht habe, es 1112 Mal zum Laufen zu bringen, es bleibt ein Rätsel)) und dann die tatsächliche Block-ID (die, die das ist) erstellen müssen wird für die benutzerdefinierten Blöcke in der Anmerkung und das Thema deklariert. Dann stellen Sie einfach die Region ein und Sie können loslegen. Erstellt eine Instanz eines Blocks unter der gewünschten Region.

$blockEntityManager = \Drupal::service('entity.manager')->getStorage('block');
$block = $blockEntityManager->create(
  array(
      'id'=> 'devel_execute_php_1112',
      'plugin' => 'devel_execute_php',
      'theme' => 'seven'
  )
);
$block->setRegion('content');
$block->save();

edit1: Ich habe den obigen Kommentar später tatsächlich überprüft - und er ist richtig. Es ist einfach nicht klar, dass die ID etwas ist, das Sie sich einfallen lassen müssen. Als Einlösung für meinen lahmen Kommentar werde ich eine Lösung zum Erstellen einer Blockinstanz einer benutzerdefinierten Blockentität veröffentlichen:

$blockEntityManager = \Drupal::service('entity.manager')->getStorage('block');
$block = $blockEntityManager->create(
  array(
      'id'=> 'ggggggggsssssss',
      'plugin' => 'block_content:79d53b4e-9e60-4f97-befc-101da919bb7a',
      'theme' => 'visitb_he_theme'
  )
);
$block->setRegion('content');

Im Grunde das gleiche, aber für ein Plugin schreiben Sie block_content: uuid_of_custom_block_entity_instance

Nikolay Borisov
quelle